[PYTHON] Créer un bot LINE WORKS avec Amazon Lex

Ceci est l'article sur le 11ème jour du Calendrier de l'Avent LINEWORKS 2019.

Il existe de nombreux services qui facilitent la création de chat bots, mais cette fois j'ai essayé de développer un bot LINE WORKS en utilisant "Amazon Lex" qui m'intéressait depuis longtemps.

Qu'est-ce qu'Amazon Lex?

«Amazon Lex» est un service AWS qui fournit une interface interactive. Il semble que Lex utilise la même technologie que celle utilisée dans Alexa. Non seulement le traitement du langage naturel mais aussi la reconnaissance vocale sont inclus.

https://aws.amazon.com/jp/lex/

Des services similaires incluent DialogFlow et Azure Bot Service et IBM. Watson Assistant

Cette fois, j'ai créé un flux de dialogue avec Amazon Lex et créé un robot qui peut parler sur LINE WORKS talk.

!!!Mise en garde!!!

__ Depuis le 12/11/2019, Amazon Lex prend uniquement en charge l'anglais américain, pas le japonais ou la région de Tokyo. __ Cette fois aussi, ce sera un chat bot qui parle en anglais. (Quand sera-t-il disponible en japonais ...) En outre, la région utilisée est l'Oregon.

Constitution

lex lineworks (2).png

--Une configuration sans serveur utilisant AWS Lambda.

Environnement de développement

--Langage: Python 3.7.1 --Deploy: utilisez Serverless Framework pour déployer Lambda

la mise en oeuvre

1. Créez un bot avec Amazon Lex

Cette fois, j'ai créé un Bot en utilisant un échantillon selon le tutoriel officiel ci-dessous.

Exemple de bot: BookTrip --Amazon Lex https://docs.aws.amazon.com/ja_jp/lex/latest/dg/ex-book-trip.html

En termes simples, c'est un chatbot qui réserve les voitures et les hôtels. J'ai choisi "Book Trip" dans l'échantillon et l'ai créé.

lex bot book trip

Sur un tel écran, vous pouvez définir l'intention et le déroulement du dialogue.

Impression que toute personne ayant utilisé d'autres services de création de chatbot peut l'utiliser immédiatement. Les débutants ont estimé qu'il serait difficile de repartir de zéro.

2. Créez diverses clés et bots à partir de la console développeur de LINE WORKS

Connectez-vous à la console développeur LINE WORKS et créez une clé ou ce bot.

Pour plus de détails, veuillez consulter cet article précédent.

Implémentons LINE WORKS Talk Bot en Python ~ Partie 1: Authentification API ~ https://qiita.com/mmclsntr/items/1d0f520f1df5dffea24b

3. Création de serveur d'application de bot LINE WORKS

Je l'ai configuré avec Lambda et implémenté le runtime en Python 3.7.

Il existe deux fonctions Lambda:

  1. __LINE WORKS Access Token Regular Update __
  1. __LINE WORKS Chatbot __

Voici un exemple de code

lambda_function.py


import json
import jwt
import requests
import urllib
import boto3
import os
from datetime import datetime
from base64 import b64encode, b64decode
import hashlib
import hmac

from requests.structures import CaseInsensitiveDict

ssm = boto3.client('ssm')
lex = boto3.client('lex-runtime')

####################################
#Magasin de paramètres Systems Manager#
####################################
def get_parameter(key):
    """
Obtenir les paramètres du magasin de paramètres SSM
    """
    response = ssm.get_parameters(
        Names=[
            key
        ],
        WithDecryption=True
    )
    parameters = response["Parameters"]
    if len(parameters) > 0:
        return response['Parameters'][0]["Value"]
    else:
        return ""


def put_parameter(key, value):
    """
Stocker les paramètres dans le magasin de paramètres SSM
    """
    response = ssm.put_parameter(
        Name=key,
        Value=value,
        Type='SecureString',
        Overwrite=True
    )


##############
# Amazon Lex #
##############
def post_text_to_lex(text, user_id, bot_name, bot_alias):
    """
Envoyer un texte à Amazon Lex&Obtenez une réponse
    """
    response = lex.post_text(
        botName=bot_name,
        botAlias=bot_alias,
        userId=user_id,
        inputText=text
    )

    return response["message"]


##################
# LINE WORKS API #
##################
def get_jwt(server_list_id, server_list_privatekey):
    """
Obtenez le jeton d'accès JWT for LINE WORKS
    """
    current_time = datetime.now().timestamp()
    iss = server_list_id
    iat = current_time
    exp = current_time + (60 * 60) #1 heure

    secret = server_list_privatekey

    jwstoken = jwt.encode(
        {
            "iss": iss,
            "iat": iat,
            "exp": exp
        }, secret, algorithm="RS256")

    return jwstoken.decode('utf-8')


def get_server_token(api_id, jwttoken):
    """
Acquisition de jetons d'accès LINE WORKS
    """
    url = 'https://authapi.worksmobile.com/b/{}/server/token'.format(api_id)

    headers = {
        'Content-Type' : 'application/x-www-form-urlencoded; charset=UTF-8'
    }

    params = {
        "grant_type" : urllib.parse.quote("urn:ietf:params:oauth:grant-type:jwt-bearer"),
        "assertion" : jwttoken
    }

    form_data = params

    r = requests.post(url=url, data=form_data, headers=headers)

    body = json.loads(r.text)
    access_token = body["access_token"]

    return access_token


def validate_request(body, signature, api_id):
    """
Vérification de la demande de LINE WORKS
    """
    #Utiliser l'ID API comme clé privée
    secretKey = api_id.encode()
    payload = body.encode()

    # HMAC-Encodé avec l'algorithme SHA256
    encoded_body = hmac.new(secretKey, payload, hashlib.sha256).digest()
    #Encodage BASE64
    encoded_b64_body = b64encode(encoded_body).decode()

    #Comparaison
    return encoded_b64_body == signature


def send_message(content, api_id, botno, consumer_key, access_token, account_id):
    """
Envoyer le message LINE WORKS
    """
    url = 'https://apis.worksmobile.com/{}/message/sendMessage/v2'.format(api_id)

    headers = {
          'Content-Type' : 'application/json;charset=UTF-8',
          'consumerKey' : consumer_key,
          'Authorization' : "Bearer " + access_token
        }

    params = {
            "botNo" : int(botno),
            "accountId" : account_id,
            "content" : content
        }

    form_data = json.dumps(params)

    r = requests.post(url=url, data=form_data, headers=headers)

    if r.status_code == 200:
        return True

    return False

######################
#Gestionnaire de fonctions Lambda#
######################
def update_token_handler(event, context):
    """
LINE WORKS Mise à jour périodique du jeton d'accès Fonction de gestionnaire Lambda
    """
    #Obtenir les paramètres LINE WORKS à partir du magasin de paramètres SSM
    api_id = get_parameter("lw_api_id")
    server_list_id = get_parameter("lw_server_list_id")
    server_list_privatekey = get_parameter("lw_server_list_private_key").replace("\\n", "\n")
    #Obtenez JWT
    jwttoken = get_jwt(server_list_id, server_list_privatekey)

    #Obtenir un jeton de serveur
    access_token = get_server_token(api_id, jwttoken)

    #Définir le jeton d'accès dans le magasin de paramètres
    put_parameter("lw_access_token", access_token)

    return


def chat_with_lex_handler(event, content):
    """
Fonction de gestionnaire Lambda du chatbot LINE WORKS
    """
    botno = os.environ.get("BOTNO")
    lex_bot_name = os.environ.get("LEX_BOT_NAME")
    lex_bot_alias = os.environ.get("LEX_BOT_ALIAS")
    #Obtenir les paramètres LINE WORKS à partir du magasin de paramètres SSM
    api_id = get_parameter("lw_api_id")
    consumer_key = get_parameter("lw_server_api_consumer_key")
    access_token = get_parameter("lw_access_token")

    event = CaseInsensitiveDict(event)
    headers = event["headers"]
    body = event["body"]

    #Demande de validation
    if not validate_request(body, headers.get("x-works-signature"), api_id):
        #Demande illégale
        return

    #Perth à Json
    request = json.loads(body)

    #Obtenir l'utilisateur d'envoi
    account_id = request["source"]["accountId"]

    res_content = {
        "type" : "text",
        "text" : "Only text"
    }

    #Vérifiez le contenu du message reçu
    request_type = request["type"]
    ## Message
    if request_type == "message":
        content = request["content"]
        content_type = content["type"]
        ## Text
        if content_type == "text":
            text = content["text"]

            #Fonctionne avec Amazon Lex
            reply_txt = post_text_to_lex(text, account_id.replace("@", "a"), lex_bot_name, lex_bot_alias)

            res_content = {
                "type" : "text",
                "text" : reply_txt
            }

    #Envoyer
    rst = send_message(res_content, api_id, botno, consumer_key, access_token, account_id)

    res_body = {
        "code": 200,
        "message": "OK"
    }
    response = {
        "statusCode": 200,
        "headers": {
            "Content-Type": "application/json"
        },
        "body": json.dumps(res_body)
    }

    return response

Veuillez également vous référer à cet article précédent. Implémentons LINE WORKS Talk Bot en Python ~ Partie 2: Implémentation de Chatbot ~ https://qiita.com/mmclsntr/items/28ba6baaf23124a53663

Code source

https://github.com/mmclsntr/lineworks-bot-with-amazon-lex

Essayez de bouger

Vous pouvez parler (en anglais) avec un chatbot créé dans Lex sur LINE WORKS. Parlez comme suit. LINE WORKS Lex

Résumé

J'ai pu exécuter le chatbot créé avec Amazon Lex avec LINE WORKS sans aucun problème. Je pense que de simples enquêtes peuvent être facilement réalisées. J'espère que vous pouvez soutenir le japonais. ..

Après cela, je jouerai avec Lex en réglant divers paramètres de dialogue.

Recommended Posts

Créer un bot LINE WORKS avec Amazon Lex
Créer un LINE BOT (chat)
[AWS] J'ai créé un BOT de rappel avec LINE WORKS
Faire un bot d'analyse morphologique de manière lâche avec LINE + Flask
[Super facile] Faisons un LINE BOT avec Python.
Créez un bot LINE avec GoogleAppEngine / py. Version nue simple
[AWS] J'ai créé un BOT de rappel avec LINE WORKS (implémentation)
Faisons un bot Twitter avec Python!
J'ai fait un robot de remplacement de tampon avec une ligne
Créer un bot Twitter Trend avec heroku + Python
Les débutants en Python ont décidé de créer un bot LINE avec Flask (commentaire approximatif de Flask)
Créer un LINE BOT avec Minette pour Python
J'ai essayé de créer un LINE BOT "Sakurai-san" avec API Gateway + Lambda
J'ai créé un Bot LINE avec Serverless Framework!
J'ai créé un bot de livre de compte de ménage avec LINE Bot
Créer un robot LINE de retour de perroquet avec AWS Cloud9
J'ai essayé de faire LINE BOT avec Python et Heroku
[Pour jouer] Essayez de faire de Yuma un robot LINE (Python)
Faisons un robot Discord.
Faites une loterie avec Python
Faire un feu avec kdeplot
Comment créer un BOT Cisco Webex Teams à l'aide de Flask
Créez une application d'apprentissage automatique avec ABEJA Platform + LINE Bot
Créons un bot LINE en utilisant divers services [ngrok edition]
[Python] Créez votre propre bot LINE
Faisons une interface graphique avec python.
Faites un son avec le notebook Jupyter
Comment créer un bot slack
Faisons une rupture de bloc avec wxPython
Créer un système de recommandation avec python
Créer un filtre avec un modèle django
[LINE bot] Je suis un ranger! Partie 2
Faisons un graphe avec python! !!
Faisons un spacon avec xCAT
Créer un itérateur de modèle avec PySide
Faire un joli graphique avec plotly
Créer un bot LINE avec Django
[LINE Messaging API] Créez un BOT qui se connecte à quelqu'un avec Python
Tweet la météo avec bot
L'histoire de la création d'un robot LINE pour le petit-déjeuner d'une université de 100 yens avec Python
Faisons un jeu de shiritori avec Python
Créer un lecteur vidéo avec PySimpleGUI + OpenCV
Comment créer un bot LINE à intelligence artificielle avec l'API de messagerie Flask + LINE
Afficher le temps d'attente de Disney avec le bot LINE
Création d'un bot LINE ~ Création, déploiement et lancement ~
Créez un simulateur de gacha rare avec Flask
Faire une figure partiellement zoomée avec matplotlib
Créez un quiz de dessin avec kivy + PyTorch
Faisons la voix lentement avec Python
[Python] [LINE Bot] Créer un robot LINE de retour de perroquet
Créez un classificateur en cascade avec Google Colaboratory
Faisons un langage simple avec PLY 1
Surveillez les mises à jour des pages Web avec LINE BOT
Faire un circuit logique avec Perceptron (Perceptron multicouche)
Faire Oui Non Popup avec Kivy
Faire une minuterie de lavage-séchage avec Raspberry Pi
Créer une animation GIF avec surveillance des dossiers
Créez un framework Web avec Python! (1)
Faisons une IA à trois yeux avec Pylearn 2