[PYTHON] J'ai essayé de créer un linebot (implémentation)

Préparation: https://qiita.com/maihamada/items/2c4d5b4f6ae82db45970 Maintenant que les préparatifs sont terminés, nous allons le mettre en œuvre.

(1) Le système que vous souhaitez créer cette fois

A la réception de l'entrée «Diagnostic diacre», effectuez «Diagnostic diacre». La question est le flux suivant. スクリーンショット 2020-05-09 19.09.01.png L'image terminée ressemble à ceci. S__3842059.jpg

En fonction de la réponse de l'événement de bouton, l'événement de bouton peut être renvoyé, l'événement de message peut être renvoyé, et ainsi de suite.

(2) Création d'un dossier

Un répertoire de travail a été créé, nous allons donc y travailler. Créez un dossier avec la structure de fichiers suivante.

situji-bot/ [Directeur de travail(Tout ira bien)]
 ├app.py 
 ├conf.json
 ├Procfile
 ├requirements.txt
 ├runtime.txt
 └template/
  └button_event.py

(3) Description du fichier

app.py J'écris le principal pour l'application.


import os
import sys
import json

#importer une bibliothèque de flacons
from flask import Flask, request, abort
#importer la bibliothèque de linebot
from linebot import LineBotApi, WebhookHandler
from linebot.exceptions import InvalidSignatureError
from linebot.models import (
    MessageEvent, PostbackEvent, TextMessage, TextSendMessage
)

#Importez votre propre bibliothèque
from template import button_event

app = Flask(__name__)

#Lire le fichier de paramètres
ABS_PATH = os.path.dirname(os.path.abspath(__file__))
with open(ABS_PATH+'/conf.json', 'r') as f:
    CONF_DATA = json.load(f)
CHANNEL_SECRET = CONF_DATA['CHANNEL_SECRET']
CHANNEL_ACCESS_TOKEN = CONF_DATA['CHANNEL_ACCESS_TOKEN']

#Créer une instance de la bibliothèque cliente
line_bot_api = LineBotApi(CHANNEL_ACCESS_TOKEN)
handler = WebhookHandler(CHANNEL_SECRET)

#Code de test
@app.route("/")
def test():
    app.logger.info("test")
    return('test OK')

#Code API LINE
@app.route("/callback", methods=['POST'])
def callback():
    signature = request.headers['X-Line-Signature']
    body = request.get_data(as_text=True)
    app.logger.info(f"Request body: {body}")
    try:
        handler.handle(body, signature)
    except InvalidSignatureError as e:
        print(e)
        abort(400)
    return 'OK'

#Réaction lorsqu'un message arrive
@handler.add(MessageEvent, message=TextMessage)
def message_text(event):
    message_text = event.message.text
    app.logger.info(message_text)

    if message_text == 'Diagnostic de majordome':
        line_bot_api.reply_message(
            event.reply_token,
            button_event.SitujiSindan().question_a()
        )
    else:
        msg = 'Nous sommes désolés, mais nous ne le soutenons pas actuellement.'
        line_bot_api.reply_message(
            event.reply_token,
            TextSendMessage(text=msg)
        )

#Réaction quand la valeur revient
@handler.add(PostbackEvent)
def on_postback(event):
    reply_token = event.reply_token
    user_id = event.source.user_id

    # postback_msg :nom de la méthode sous forme de chaîne
    postback_msg = event.postback.data
    # situji_sindan :objet de classe
    situji_sindan = button_event.SitujiSindan()
    #Créer un objet méthode à partir de l'objet classe et le nom de méthode obtenu à partir de la chaîne de caractères
    question = getattr(situji_sindan, postback_msg)
    #Jeter la question suivante
    line_bot_api.reply_message(
        event.reply_token,
        question()
    )

if __name__ == "__main__":
    app.run(debug=True)

conf.json Si vous regardez ce fichier, il est séparé afin que vous puissiez voir quel paramètre vous utilisez. Actuellement, je ne configure que l'API de ligne, mais je voudrais inclure les paramètres DB à l'avenir. Le jeton d'accès au canal secret au canal obtenu lors de la préparation est utilisé ici.

{
"CHANNEL_SECRET": "[Secret de chaîne]",
"CHANNEL_ACCESS_TOKEN": "[Jeton d'accès au canal]"
}

Procfile Fichier de paramètres tel que le type de processus. Il semble que gunicorn (serveur WSGI) soit nécessaire pour connecter le serveur Web et le framework flask. La manière d'écrire est la suivante, et le dernier --log-file-n'est décrit que lorsque vous souhaitez générer un journal. [process type]: [command] [api_name] : app --log-file -

web: gunicorn app:app --log-file -

requirements.txt Écrivez la bibliothèque et la version utilisées.

Flask==1.1.2
gunicorn==20.0.4
line-bot-sdk==1.16.0

runtime.txt Écrivez la version de python que vous avez utilisée.

python-3.8.1

template/button_event.py Cette fois, j'ai créé beaucoup d'événements de bouton, alors j'ai essayé d'en faire un module séparé.

from linebot.models import (
    PostbackEvent, TextSendMessage, TemplateSendMessage,
    ButtonsTemplate, PostbackTemplateAction
)

class SitujiSindan:
    def question_a(self):
        button_template = TemplateSendMessage(
            alt_text="Diagnostic de majordome",
            template=ButtonsTemplate(
                title="question 1",
                text="Quand tu es dans une pincée",
                actions=[
                  PostbackTemplateAction(
                    label='Vous aider avec votre cerveau',
                    data='question_b'
                  ),
                  PostbackTemplateAction(
                    label='Étirez votre corps et aidez-vous',
                    data='question_c'
                  )
                ]
            )
        )
        return button_template

    def question_b(self):
        button_template = TemplateSendMessage(
            alt_text="Diagnostic de majordome",
            template=ButtonsTemplate(
                title="question 2",
                text="Quand tu fais quelque chose de difficile ...",
                actions=[
                  PostbackTemplateAction(
                    label='Je veux que tu me suives doucement',
                    data='answer_d'
                  ),
                  PostbackTemplateAction(
                    label='Je veux que tu me grondes correctement',
                    data='answer_e'
                  )
                ]
            )
        )
        return button_template

    def question_c(self):
        button_template = TemplateSendMessage(
            alt_text="Diagnostic de majordome",
            template=ButtonsTemplate(
                title="question 2",
                text="Quel est le type?",
                actions=[
                  PostbackTemplateAction(
                    label='Hostile',
                    data='answer_f'
                  ),
                  PostbackTemplateAction(
                    label='Amical',
                    data='answer_g'
                  )
                ]
            )
        )
        return button_template

    def answer_d(self):
        msg = 'Le résultat du diagnostic est "Orthodox Butler". Bref, je fais de mon mieux pour la jeune femme'
        return TextSendMessage(text=msg)

    def answer_e(self):
        msg = 'Le résultat du diagnostic est "Grand frère diacre". Je l'aime et je me soucie toujours d'elle.'
        return TextSendMessage(text=msg)

    def answer_f(self):
        msg = 'Le résultat du diagnostic est "majordome". C'est un peu hostile, mais je fais de mon mieux pour protéger la jeune femme. L'habitude est «parce que ce n'est qu'un majordome».'
        return TextSendMessage(text=msg)

    def answer_g(self):
        msg = 'Le résultat du diagnostic est "plus jeune frère majordome". J'adore la jeune femme et la traite comme un petit frère. Je ne m'y fie généralement pas, mais je ferai de mon mieux pour le protéger en un clin d'œil.'
        return TextSendMessage(text=msg)

(4) Testez localement.

$ python app.py
 * Serving Flask app "app" (lazy loading)
 * Environment: production
   WARNING: This is a development server. Do not use it in a production deployment.
   Use a production WSGI server instead.
 * Debug mode: on
 * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
 * Restarting with stat
 * Debugger is active!
 * Debugger PIN: 897-298-226

Cliquez sur l'url suivante avec chrome, etc., et lorsque le mot «test OK» apparaît, c'est OK. http://127.0.0.1:5000/

(5) Déployer

Je l'ai configuré pour qu'il soit automatiquement déployé lorsque je le pousse vers Git, alors je le pousse. Mise en scène.

$ git add .

Vérifiez l'état de la préparation.

$ git status
On branch master
Your branch is up to date with 'origin/master'.

Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
	new file:   Procfile
	new file:   app.py
	new file:   conf.json
	new file:   requirements.txt
	new file:   runtime.txt
	new file:   template/button_event.py

Engagez-vous et poussez.

$ git commit -m 'first push'
[master 04a377d] first push
 6 files changed, 198 insertions(+)
 create mode 100644 Procfile
 create mode 100644 app.py
 create mode 100644 conf.json
 create mode 100644 requirements.txt
 create mode 100644 runtime.txt
 create mode 100644 template/button_event.py
$ git push origin master
Enumerating objects: 10, done.
Counting objects: 100% (10/10), done.
Delta compression using up to 4 threads
Compressing objects: 100% (6/6), done.
Writing objects: 100% (9/9), 2.80 KiB | 1.40 MiB/s, done.
Total 9 (delta 0), reused 0 (delta 0), pack-reused 0
To github.com:maihamada/situji-bot.git
   fc7af07..04a377d  master -> master

(6) Configurer les développeurs LINE

Configurez Webhock. (Dans les paramètres de l'API de messagerie) スクリーンショット 2020-05-09 19.52.12.png

Organisez les paramètres de réponse comme vous le souhaitez. スクリーンショット 2020-05-09 19.53.28.png

Ceci termine la création de LINE BOT.

Impressions

C'était plus facile à mettre en œuvre que prévu. À l'avenir, j'aimerais augmenter le modèle de réponse par des chaînes de caractères et changer le ton du majordome en utilisant le résultat de ce diagnostic.

Recommended Posts

J'ai essayé de créer un linebot (implémentation)
J'ai essayé de créer un linebot (préparation)
Je souhaite créer un type d'implémentation pouvant être branché
J'ai essayé de créer l'API Quip
J'ai essayé de créer automatiquement un rapport avec la chaîne de Markov
J'ai essayé de créer un bot pour annoncer un événement Wiire
J'ai essayé d'ajouter un post-incrément à l'implémentation CPython
J'ai créé une API Web
J'ai essayé de créer un environnement serveur qui fonctionne sous Windows 10
J'ai essayé de créer un pointage de crédit simple avec régression logistique.
J'ai essayé de créer une liste de nombres premiers avec python
J'ai essayé de créer des taureaux et des vaches avec un programme shell
J'ai essayé de déboguer.
J'ai essayé de créer une méthode de super résolution / ESPCN
Je souhaite créer facilement un modèle de bruit
J'ai essayé de créer une méthode de super résolution / SRCNN ①
Je veux créer une fenêtre avec Python
J'ai essayé de générer une chaîne de caractères aléatoire
J'ai essayé de créer une méthode de super résolution / SRCNN ③
J'ai essayé de créer une méthode de super résolution / SRCNN ②
J'ai créé un jeu ○ ✕ avec TensorFlow
J'ai essayé de créer un programme qui convertit les nombres hexadécimaux en nombres décimaux avec python
J'ai essayé de créer un plug-in avec HULFT IoT Edge Streaming [Development] (2/3)
J'ai essayé de créer un plug-in avec HULFT IoT Edge Streaming [Execution] (3/3)
[Outlook] J'ai essayé de créer automatiquement un e-mail de rapport quotidien avec Python
J'ai essayé de créer un plug-in avec HULFT IoT Edge Streaming [Setup] (1/3)
J'ai créé un exemple pour accéder à Salesforce en utilisant Python et Bottle
J'ai essayé de faire un "putain de gros convertisseur de littérature"
J'ai essayé d'apprendre PredNet
J'ai essayé de créer une classe qui peut facilement sérialiser Json en Python
J'ai essayé d'organiser SVM.
J'ai essayé d'implémenter un pseudo pachislot en Python
Quand j'ai essayé de créer un environnement virtuel avec Python, cela n'a pas fonctionné
J'ai essayé d'implémenter PCANet
J'ai essayé de créer facilement un système de présence entièrement automatique avec Selenium + Python
[Azure] J'ai essayé de créer une machine virtuelle Linux avec Azure de Microsoft Learn
[Go + Gin] J'ai essayé de créer un environnement Docker
J'ai essayé de réintroduire Linux
Je souhaite créer manuellement une légende avec matplotlib
J'ai essayé de présenter Pylint
J'ai essayé de créer un bouton pour Slack avec Raspeye + Tact Switch
J'ai essayé de résumer SparseMatrix
jupyter je l'ai touché
J'ai essayé d'implémenter StarGAN (1)
J'ai essayé de dessiner un diagramme de configuration à l'aide de diagrammes
J'ai essayé de créer un modèle avec l'exemple d'Amazon SageMaker Autopilot
J'ai essayé de créer un environnement d'apprentissage amélioré pour Othello avec Open AI gym
[Python] J'ai essayé de créer automatiquement un rapport quotidien de YWT avec la messagerie Outlook
J'ai essayé de créer une classe pour rechercher des fichiers avec la méthode Glob de Python dans VBA
J'ai essayé de créer un cadre de données pandas en grattant les informations de rappel d'aliments avec Python
J'ai essayé d'implémenter une ligne moyenne mobile de volume avec Quantx
J'ai essayé de mettre en œuvre le modèle de base du réseau neuronal récurrent
J'ai essayé de créer une API list.csv avec Python à partir de swagger.yaml
J'ai essayé d'implémenter un automate cellulaire unidimensionnel en Python
[Chaîne de Markov] J'ai essayé de lire les citations en Python.
J'ai créé un outil pour créer un nuage de mots à partir de wikipedia