[PYTHON] Tipps zum Erstellen eines interaktiven Bots mit LINE

Hallo, das ist Ninomiya von LIFULL CO., LTD. Ich war dieses Jahr an der Prototyp-Implementierung des LINE-Bots beteiligt.

Für die LINE-Entwicklung ist SDK auch in Sprachen wie Python verfügbar, und Sie können ganz einfach einen einfachen Bot erstellen. Wenn Sie jedoch versuchen, eine Anwendung zu erstellen, die komplizierter als eine bestimmte Ebene ist, ist die Implementierung etwas schwierig, z. B. das Verwalten von Szenarien und das Generieren von FlexMessage json.

Für diejenigen, die es als nächstes implementieren, werde ich die Punkte teilen, die ich hauptsächlich bei der Implementierung des LINE-Bots entwickelt habe.

Aktiviert, um Szenarien in der Einstellungsdatei zu verwalten

Die Konfigurationsdatei gibt Ihnen einen Überblick über das Interaktionsszenario. Die Implementierung ist so, dass der reguläre Ausdruck durch "trigger_message" in "senario" festgelegt wird und der durch "endpoint" festgelegte Controller aufgerufen wird, wenn er übereinstimmt.

config.json


//Aufgrund der Spezifikationen von json können keine Kommentare eingegeben werden, sie sind jedoch der Einfachheit halber enthalten.
{
  "scenario": {
    "initial": {
      "trigger_message": "Starten Sie den Bot",
      "endpoint": "controllers.initial",
      "possible_replies": [
        "initial"
      ]
    },
    //Antwort auf die Suche nach Produkten. beim Postback-Event"method: first_search, target:Buch"Angenommen, ein Wert wie wird dynamisch gesendet
    "search_products": {
      "trigger_message": "method: search_products, target: (?P<target>[\\s\\S]+)",
      "endpoint": "controllers.search_products",
      "possible_replies": [
        "selection"
      ]
    },
    //Standardauswahl
    "default": {
      "endpoint": "controllers.default",
      "possible_replies": [
        "default"
      ]
    }
 },
  "replies": {
    "initial": {
      "view": "views.initial",
      "template": [
        {
          "mode": "text",
          "text": "Wählen Sie die Funktion aus, die Sie aufrufen möchten"
        },
        {
          "mode": "flex",
          "template": "flex_messages/buttons.tpl.json",
          "alt_text": "Entscheidungen"
        }
      ]
    }, 
    "products": {
      "view": "views.search_result",
      "template": [
        {
          "mode": "text",
          "text": "Ich habe nach einem Produkt gesucht"
        },
        {
          "mode": "flex",
          "template": "flex_messages/products.tpl.json",
          "alt_text": "Empfohlene Produkte"
        }
      ]
    }
  }
}

[Eingeschränkter Automat] des Dialogs mit dem Bot (https://ja.wikipedia.org/wiki/%E6%9C%89%E9%99%90%E3%82%AA%E3%83%BC%E3%83 Unter Berücksichtigung von% 88% E3% 83% 9E% E3% 83% 88% E3% 83% B3) wird die Nachricht des Bots mit dem Bild erstellt, dass der Status über die Schaltfläche ausgewählt wird, um den nächsten Übergang des Benutzers auszuwählen. Da der Inhalt des Postback-Ereignisses jedoch in der Nachricht anstelle der Einstellungsdatei erstellt wird, wird nicht verwaltet, welche Art von Übergang der Benutzer vornimmt.

Seit ich es in Python implementiert habe, habe ich importlib verwendet, um den Controller aufzurufen. Ich habe es auch mit json implementiert, aber es ist schwer zu kommentieren, also mache es entweder yaml oder [zum Beispiel Django Dispatcher](https://docs.djangoproject.com/en/2.2/topics] Es ist möglicherweise besser, ein Skript schreiben zu können, das die Eingabenachricht der Klasse zuordnet, die Sie ausführen möchten, z. B. / http / urls /).

trigger_message wird mit einem regulären Ausdruck analysiert und vom Controller als Argument aufgerufen, wie unten gezeigt. Dieses Mal ist es als Postback-Ereignis so, als würde "der Benutzer die hier vorbereitete Schaltfläche drücken", sodass der reguläre Ausdruck ausgelöst wird. (Post), aber wenn Sie frei antworten möchten, verwenden Sie ein Tool wie Dialogflow, um den Kontext (Controller zum Starten) und die Entität (sein Argument) festzulegen. ..

script/controllers/search_products/__init__.py


from script.controllers._utils import AbstractController, Response, render, UserContext
from script.models import search_model

class Controller(AbstractController):
    """Controller, der die erste Wahl gibt"""

    def call(self, user_context: UserContext, target: str) -> Response:
        """Controller-Anrufverarbeitung

        Args:
            user_context:Klasse, die ID usw. umschließt
            target:Inhalt analysiert mit einer benannten Erfassung eines regulären Ausdrucks
        Returns:
Antwort an den Benutzer

        """
        products = search_model.search(target)
        return render("initial", proc=lambda view: view.render(products=products))

FlexMessage wurde mit der Template-Engine (jinja2) zusammengestellt.

In LINE können Sie [Nachrichten mit einem flexiblen Layout namens FlexMessage] verwenden (https://developers.line.biz/ja/docs/messaging-api/using-flex-messages/).

Dazu müssen Sie einen komplexen JSON für FlexMessage zusammenstellen und die LINE-Antwort-API senden. Ich habe FlexMessage zuerst mit einem Python-Wörterbuch erstellt, aber es war ziemlich schwierig. Daher habe ich auf diesen Artikel verwiesen und die Vorlage für die Template-Engine (jinja2) verwendet. Ich habe es vorbereitet und umgesetzt.

Wenn Sie es jedoch mit Simulator entworfen haben, wäre es mühsam, es in ein SDK-Modell umzuschreiben. Die Quelle wird auch länger sein. In einem solchen Fall scheint es besser, den Wert mithilfe der Template-Engine in JSON einzubetten und das Ergebnis in das SDK-Modell zu konvertieren. Es gibt eine Methode namens new_from_json_dict (), um ein Modell aus JSON zu erstellen.

Ich habe es in jinja2 implementiert, aber ich denke nicht, dass es sich in anderen Sprachen und Bibliotheken stark ändern wird.

https://palletsprojects.com/p/jinja/

{
  "type": "carousel",
  "contents": [
{% for product in products %}
    {
      "type": "bubble",
      "body": {
        "type": "box",
        "layout": "vertical",
        "contents": [
          {
            "type": "box",
            "layout": "horizontal",
            "contents": [
              {
                "type": "image",
                "url": {{ product.image | json_escape }},
                "size": "full",
                "aspectMode": "cover",
                "action": {
                  "type": "uri",
                  "uri": {{ product.url | json_escape }}
                }
              }
            ]
          },
//Folgendes wird weggelassen

Der aktuelle Status von "json_escape" ist hier "json.dumps", der den Vorgang des "Escapings der Zeichenkette und des Hinzufügens" ausführt, um sicherzustellen, dass der richtige json zusammengestellt wird.

class JsonTemplete(object):
    ENV = Environment(loader=FileSystemLoader(
        str(Path(__file__).resolve().parent / "../templetes"), encoding='utf8'))
    ENV.filters["json_escape"] = json.dumps

#Folgendes wird weggelassen

Verwenden Sie dies, indem Sie es mit Methode namens new_from_json_dict in das SDK laden.

    def __build_contents(self, content):
        """Sortieren Sie die Containertypen in FlexSendMssage.
        Args:
            content (dict):Containerinformationen
        Returns:
            BubbleContainer/CarouselContainer:Container in FlexSendMessage
        """
        t = content["type"]
        if t == "bubble":
            return BubbleContainer.new_from_json_dict(content)
        elif t == "carousel":
            return CarouselContainer.new_from_json_dict(content)
        else:
            raise RuntimeError(f"Es ist ein nicht unterstützter Container: {t}")

Im Fall von "Die Grammatik ist für json korrekt, aber die LINE-Nachrichtenspezifikationen werden nicht erfüllt" bleibt das Problem bestehen, dass das Debuggen etwas problematisch ist. Ich kann mir keine gute Lösung dafür vorstellen. Bitte lassen Sie mich wissen, wenn Sie irgendwelche Kenntnisse haben.

Andere Punkte, mit denen ich im LINE-Projekt zu kämpfen hatte

Abhängig vom Smartphone-Modell und den Einstellungen des Benutzers änderte sich das Erscheinungsbild von FlexMessage (z. B. waren die Zeichen größer als erwartet und Zeilenumbrüche wurden eingefügt), und manchmal sah es nicht wie erwartet aus. Sie können die Schriftgröße nicht im Detail angeben, daher sollten Sie kein sehr aufwändiges Design anstreben.

Wie in anderen Artikeln häufig erwähnt, ist es außerdem reibungslos, wenn Sie das Erscheinungsbild mit FlexMssageSimulator anpassen und den Inhalt der Schaltfläche in die Vorlage einbetten. ..

schließlich

Ich hoffe, dieser Artikel ist hilfreich für diejenigen, die mit der Implementierung von Chatbots beginnen.

Dieser Artikel ist der erste Tagesartikel von LIFULL Adventskalender. Vielen Dank für Ihre weitere Unterstützung.

Recommended Posts

Tipps zum Erstellen eines interaktiven Bots mit LINE
Tipps zum Erstellen kleiner Werkzeuge mit Python
Tipps zur Verwendung von Realsense SR300 auf einem MacBook im Jahr 2020
Vorgehensweise zum Erstellen eines Linienbot in AWS Lambda
Suchen Sie unter Linux über die Befehlszeile nach großen Dateien