Preparation: https://qiita.com/maihamada/items/2c4d5b4f6ae82db45970 Now that the preparations are complete, we will actually implement it.
When the input "Deacon diagnosis" is received, perform "Deacon diagnosis". The question is the following flow. The completed image looks like this.
Depending on the response of the button event, the button event may be returned, the message event may be returned, and so on.
Since the working directory has been created, we will work on it. Create a folder with the following file structure.
situji-bot/ [Working directory(Anything will be fine)]
├app.py
├conf.json
├Procfile
├requirements.txt
├runtime.txt
└template/
└button_event.py
app.py I'm writing the main one for the application.
import os
import sys
import json
#import flask library
from flask import Flask, request, abort
#import linebot library
from linebot import LineBotApi, WebhookHandler
from linebot.exceptions import InvalidSignatureError
from linebot.models import (
MessageEvent, PostbackEvent, TextMessage, TextSendMessage
)
#Import your own library
from template import button_event
app = Flask(__name__)
#Read configuration file
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']
#Create an instance of the client library
line_bot_api = LineBotApi(CHANNEL_ACCESS_TOKEN)
handler = WebhookHandler(CHANNEL_SECRET)
#Code for testing
@app.route("/")
def test():
app.logger.info("test")
return('test OK')
#LINE API code
@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'
#Reaction when a message comes
@handler.add(MessageEvent, message=TextMessage)
def message_text(event):
message_text = event.message.text
app.logger.info(message_text)
if message_text == 'Butler diagnosis':
line_bot_api.reply_message(
event.reply_token,
button_event.SitujiSindan().question_a()
)
else:
msg = 'We are sorry, but we do not currently support it.'
line_bot_api.reply_message(
event.reply_token,
TextSendMessage(text=msg)
)
#Reaction when the value comes back
@handler.add(PostbackEvent)
def on_postback(event):
reply_token = event.reply_token
user_id = event.source.user_id
# postback_msg :method name as a string
postback_msg = event.postback.data
# situji_sindan :class object
situji_sindan = button_event.SitujiSindan()
#Create a method object from the method name obtained from the class object and the character string
question = getattr(situji_sindan, postback_msg)
#Throw the next question
line_bot_api.reply_message(
event.reply_token,
question()
)
if __name__ == "__main__":
app.run(debug=True)
conf.json If you look at this file, it's separated so you can see which setting you're using. Currently, I only set the line api, but I would like to include the DB settings in the future. The channel secret channel access token obtained in the preparation is used here.
{
"CHANNEL_SECRET": "[Channel secret]",
"CHANNEL_ACCESS_TOKEN": "[Channel access token]"
}
Procfile Configuration files such as process type. It seems that gunicorn (WSGI server) is required to connect the web server and the flask framework. The way to write is as follows, and the last --log-file-is described only when you want to output a log. [process type]: [command] [api_name] : app --log-file -
web: gunicorn app:app --log-file -
requirements.txt Write the library and version used.
Flask==1.1.2
gunicorn==20.0.4
line-bot-sdk==1.16.0
runtime.txt Write the version of python used.
python-3.8.1
template/button_event.py This time, I created a lot of button events, so I tried to make it a separate module.
from linebot.models import (
PostbackEvent, TextSendMessage, TemplateSendMessage,
ButtonsTemplate, PostbackTemplateAction
)
class SitujiSindan:
def question_a(self):
button_template = TemplateSendMessage(
alt_text="Butler diagnosis",
template=ButtonsTemplate(
title="question 1",
text="When you get into a pinch",
actions=[
PostbackTemplateAction(
label='Help you with your brain',
data='question_b'
),
PostbackTemplateAction(
label='Stretch your body and help you',
data='question_c'
)
]
)
)
return button_template
def question_b(self):
button_template = TemplateSendMessage(
alt_text="Butler diagnosis",
template=ButtonsTemplate(
title="Question 2",
text="When you do something hard ...",
actions=[
PostbackTemplateAction(
label='I want you to follow me gently',
data='answer_d'
),
PostbackTemplateAction(
label='I want you to scold me properly',
data='answer_e'
)
]
)
)
return button_template
def question_c(self):
button_template = TemplateSendMessage(
alt_text="Butler diagnosis",
template=ButtonsTemplate(
title="Question 2",
text="Which is the type?",
actions=[
PostbackTemplateAction(
label='Unfriendly',
data='answer_f'
),
PostbackTemplateAction(
label='Friendly',
data='answer_g'
)
]
)
)
return button_template
def answer_d(self):
msg = 'The diagnosis result is "Orthodox Butler". Anyway, I'm doing my best for the young lady'
return TextSendMessage(text=msg)
def answer_e(self):
msg = 'The diagnosis result is "Older brother butler". I love her and always care about her.'
return TextSendMessage(text=msg)
def answer_f(self):
msg = 'The diagnosis result is "butler". It's a little unfriendly, but I'm doing my best to protect the young lady. The habit is "because it's just a butler."'
return TextSendMessage(text=msg)
def answer_g(self):
msg = 'The diagnosis result is "younger brother butler". I love my young lady and treat her like a younger brother. I don't usually rely on it, but I will do my best to protect it in a pinch.'
return TextSendMessage(text=msg)
$ 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
Hit the following url with chrome etc., and when the word "test OK" appears, it's OK. http://127.0.0.1:5000/
I set it to deploy automatically when I push it to Git, so push it. Staging.
$ git add .
Check the staging status.
$ 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
Do commit & push.
$ 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
Set up webhock. (In Messaging API settings)
Arrange the response settings as you like.
This completes the creation of LINE BOT.
It was easier to implement than I expected. In the future, I would like to increase the response pattern by character strings and change the tone of the butler using the result of this diagnosis.
Recommended Posts