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.
«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.
__ 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.
--Une configuration sans serveur utilisant AWS Lambda.
--Langage: Python 3.7.1 --Deploy: utilisez Serverless Framework pour déployer Lambda
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éé.
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.
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
Je l'ai configuré avec Lambda et implémenté le runtime en Python 3.7.
Il existe deux fonctions Lambda:
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
https://github.com/mmclsntr/lineworks-bot-with-amazon-lex
Vous pouvez parler (en anglais) avec un chatbot créé dans Lex sur LINE WORKS. Parlez comme suit.
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