[PYTHON] Make LINE BOT (Echolalia)

I made a simple parrot return with LINEBOT with Heroku, Flask, and line-bot-sdk. It took a full two days and there were many points that got stuck, so share it including notes.

・ Mac ・ Python

(1) Environment maintenance, directory structure

Create a directory test_linebot on your desktop. Build a virtual environment in the directory and start it.

python3 -m venv .
source bin/activate

The final directory structure is as follows

test_linebot
├main.py
├runtime.txt
├Procfile
└requirements.txt

(2) Install the required framework

pip install flask
pip install gunicorn
pip install line-bot-sdk

(3) Create main.py

.py:main.py



from flask import Flask, request, abort
from linebot import (
    LineBotApi, WebhookHandler
)
from linebot.exceptions import (
    InvalidSignatureError
)
from linebot.models import (
    MessageEvent, TextMessage, TextSendMessage,
)
import os

app = Flask(__name__)

#LINE Developers access token and Channel Secret set in heroku environment variables
#Code to get
YOUR_CHANNEL_ACCESS_TOKEN = os.environ["YOUR_CHANNEL_ACCESS_TOKEN"]
YOUR_CHANNEL_SECRET = os.environ["YOUR_CHANNEL_SECRET"]
line_bot_api = LineBotApi(YOUR_CHANNEL_ACCESS_TOKEN)
handler = WebhookHandler(YOUR_CHANNEL_SECRET)

#Code to check if the deployment to heroku was successful
@app.route("/")
def hello_world():
    return "hello world!"


#Specify a URL for the LINE Developers webhook so that the webhook sends an event to the URL
@app.route("/callback", methods=['POST'])
def callback():
    #Get the value for signature verification from the request header
    signature = request.headers['X-Line-Signature']

    #Get request body
    body = request.get_data(as_text=True)
    app.logger.info("Request body: " + body)

    #Validate the signature and call the function defined in handle if there is no problem
    try:
        handler.handle(body, signature)
    except InvalidSignatureError:
        abort(400)
    return 'OK'


#The following describes how to handle the event sent from the webhook.
@handler.add(MessageEvent, message=TextMessage)
def handle_message(event):
    line_bot_api.reply_message(
        event.reply_token,
        TextSendMessage(text=event.message.text))

#Port number setting
if __name__ == "__main__":
    port = int(os.getenv("PORT", 5000))
    app.run(host="0.0.0.0", port=port)

* Supplementary explanation of the above code

try:〜 A description of the webhook. A webhook is a process that sends an event to a server that processes the event when an event (sending a message, adding a friend, etc.) occurs (a URL must be specified in the LINE Developers webhook to send it to the server).

@handler.add(MessageEvent, message=TextMessage) Enter the event type in the first argument (this time I want to reply when a message is sent, so I chose MessageEvent) In the second argument I want to enter the message type (this time I want to return text) Therefore, message = TextMessage).

def handle_message(event): The event processing function handle_message is called, and the value of the second argument of reply_message is returned as a LINE reply. To return it as a line message, use the reply_message function of lineb_bot_api. The first argument event.reply_token, which is reply_message, contains reply_token. This can be obtained from the webhook object and identifies which event to reply to. Means the response token for an event. In the second argument, put a function called TextSendMessage for reply defined in linebot.models, and this function puts the message to be returned in the argument. In addition, event.message.text stores the message sent from LINE. For example, if "Good morning" is sent, event.message.text = "Good morning" is stored. If TextSendMessage (text ='Good morning')), all replies will return "Good morning". By the way, the contents of the event are as follows.

{
  "message": {
    "id": "***************",
    "text": "Good morning",
    "type": "text"
  },
  "replyToken": "***********************",
  "source": {
    "type": "user",
    "userId": "************************"
  },
  "timestamp": *********************,
  "type": "message"
}

port = int(os.getenv("PORT", 5000)) Heroku seems to assign port numbers dynamically, so use os.getenv to do the following: os.getenv ("PORT", 5000) attempts to acquire the environment variable'PORT', and if it can be acquired, the acquired value is returned, and if it cannot be acquired: 5000 is returned. 5000 is intended for working in a local environment.

#Port number setting
if __name__ == "__main__":
    port = int(os.getenv("PORT", 5000))
    app.run(host="0.0.0.0", port=port)

(4) Register with LINE Developers

Access LINE Developers, and after registration, create a "provider" that represents the service provider. Create a new channel within your provider. Select Message API as the channel type.

(5) Set Heroku environment variables

Log in to Heroku and create an app. This time, I named it testlinebot0319.

heroku login
heroku create testlinebot0319

Initialize

git init

Link heroku app and git,

heroku git:remote -a testlinebot0319

Set the "access token string" and "channel secret string" of Line developers in the environment variables of heroku. For example, heroku config: set YOUR_CHANNEL_ACCESS_TOKEN = "Channel access token string" -a (app name).

heroku config:set YOUR_CHANNEL_ACCESS_TOKEN="Channel access token string" -a testlinebot0319
heroku config:set YOUR_CHANNEL_SECRET="Channel secret string" -a testlinebot0319

Check if the environment variables are set properly on heroku.

heroku config

(6) Prepare other necessary files

Create Procfile, runtime.txt and requirements.txt.

Create runtime.txt after confirming your own python version.

.txt:runtime.txt



python-3.8.0

Procfile describes the following.

Prockfile


web: python main.py

Describe requirements.txt by entering the following in the terminal.

pip freeze > requirements.txt

(7) Deploy to Heroku

Reinitialize git, associate it, add it, and commit it with the name the-first. Finally push to Heroku.

git init
heroku git:remote -a testlinebot0319
git add .
git commit -m'the-first'
git push heroku master

heroku open,

heroku open

Success if the following appears in the browser.

スクリーンショット 2020-03-19 22.32.28.png

(8) LINE Developers Webhook settings

Set your Heroku app name in the LINE Developers webhook field as shown below. App name on Heroku = testlinebot0319 スクリーンショット 2020-03-19 22.34.25.png

At this time, turn on the use of Webhook. With this, if you read the QR code above of LINE Developers and register as a friend, the parrot return application is completed. If LINE BOT doesn't work, such as when it doesn't return the parrot, I may turn on and off the Webhook repeatedly (in my case, that worked).

Referenced site

Let's make a LINE BOT that can be searched on Wikipedia in an hour! LINE BOT with Python + Flask + Heroku [Python beginner! -LINE Bot Echolalia-]

Recommended Posts

Make LINE BOT (Echolalia)
Make a LINE BOT (chat)
[Python] Make your own LINE bot
LINE BOT if ~ stumbled
Make a LINE WORKS bot with Amazon Lex
Make a morphological analysis bot loosely with LINE + Flask
Make a parrot return LINE Bot on AWS Cloud9
[For play] Let's make Yubaba a LINE Bot (Python)
[Super easy] Let's make a LINE BOT with Python.
Let's make a Discord Bot.
Parrot return LINE BOT creation
Safety confirmation LINE bot [Explanation]
Make a LINE bot with GoogleAppEngine / py. Simple naked version
Let's make a LINE bot using various services [ngrok edition]
Make python segfault in one line
Make Echolalia LINEbot with Python + heroku
Make Perl segfault on one line
How to make a slack bot
[LINE bot] I'm a ranger! Part 2
Create a LINE Bot in Django
How to make an artificial intelligence LINE bot with Flask + LINE Messaging API
Python beginners decided to make a LINE bot with Flask (Flask rough commentary)
I tried to make "Sakurai-san" a LINE BOT with API Gateway + Lambda
Make the line breaks visible in journalctrl
Display Disney's waiting time with LINE bot
Creating a LINE bot ~ Creating, deploying, and launching ~
[Python] [LINE Bot] Create a parrot return LINE Bot
Upload photos from LINE Bot to Dropbox
Monitor web page updates with LINE BOT
Let's make a Twitter Bot with Python!