#LINEBOTで単純なオウム返しを、Heroku、Flask、line-bot-sdkで作成した。丸2日かかり詰まった点も多いのでメモも含めて共有。
・Mac
・Python
#(1)環境整備、ディレクトリ構成
デスクトップに、ディレクトリtest_linebotを作成。
ディレクトリ内に仮想環境を構築して起動。
python3 -m venv .
source bin/activate
最終的なディレクトリ構成は以下の通り
test_linebot
├main.py
├runtime.txt
├Procfile
└requirements.txt
#(2)必要なフレームワークをインストール
pip install flask
pip install gunicorn
pip install line-bot-sdk
#(3)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__)
#herokuの環境変数に設定された、LINE DevelopersのアクセストークンとChannelSecretを
#取得するコード
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)
#herokuへのデプロイが成功したかどうかを確認するためのコード
@app.route("/")
def hello_world():
return "hello world!"
#LINE DevelopersのWebhookにURLを指定してWebhookからURLにイベントが送られるようにする
@app.route("/callback", methods=['POST'])
def callback():
# リクエストヘッダーから署名検証のための値を取得
signature = request.headers['X-Line-Signature']
# リクエストボディを取得
body = request.get_data(as_text=True)
app.logger.info("Request body: " + body)
# 署名を検証し、問題なければhandleに定義されている関数を呼ぶ
try:
handler.handle(body, signature)
except InvalidSignatureError:
abort(400)
return 'OK'
#以下でWebhookから送られてきたイベントをどのように処理するかを記述する
@handler.add(MessageEvent, message=TextMessage)
def handle_message(event):
line_bot_api.reply_message(
event.reply_token,
TextSendMessage(text=event.message.text))
# ポート番号の設定
if __name__ == "__main__":
port = int(os.getenv("PORT", 5000))
app.run(host="0.0.0.0", port=port)
##※上記コードの補足説明
####try:〜
Webhookに関する記述。Webhookとはイベント(メッセージ送信、友達追加など)が起きた時にイベントを処理するサーバーへイベントを送る処理をするもの(サーバーへ送るためにはLINE DevelopersのWebhookにURLを指定が必要)。
###@handler.add(MessageEvent, message=TextMessage)
1つ目の引数にはイベントの種類を入れる(今回はメッセージが送られてきた時に返信したいので、MessageEventとした)、2つ目の引数にはメッセージの種類を入れる(今回はテキストを返したいので、message=TextMessageとした)。
###def handle_message(event):
イベント処理する関数handle_messageが呼び出され、reply_messageの第2引数の値がLINEの返信として返される。lineメッセージとして返すためにはlineb_bot_apiのreply_message関数を使う。reply_messageである第一引数のevent.reply_tokenはreply_tokenが入る。これはwebhookオブジェクトから取得できるもので、どのイベントに対して返信するのか識別するもの。イベントの応答トークンを意味する。第二引数にはlinebot.modelsに定義されている返信用のTextSendMessageという関数を入れ、この関数は引数に返すメッセージを入れる。
また、event.message.textはLINEから送られてきたメッセージが格納されている。例えば”おはよう”と送られてきたら、event.message.text="おはよう"が格納されている。仮に、TextSendMessage(text='おはよう'))とすれば、返信は全て"おはよう"と返す。
ちなみに、eventの中身は以下のようになっている。
{
"message": {
"id": "***************",
"text": "おはよう",
"type": "text"
},
"replyToken": "***********************",
"source": {
"type": "user",
"userId": "************************"
},
"timestamp": *********************,
"type": "message"
}
port = int(os.getenv("PORT", 5000))
Herokuは動的にポート番号を割り当てているようなので、os.getenvを使用して,以下のようにする。os.getenv("PORT", 5000)は,環境変数'PORT'を取得を試みて、取得できた場合はその取得した値が返され、取得できない場合:5000が返される。5000はローカル環境で作業する場合を想定としたもの。
# ポート番号の設定
if __name__ == "__main__":
port = int(os.getenv("PORT", 5000))
app.run(host="0.0.0.0", port=port)
#(4)LINE Developersに登録
LINE Developersへアクセスして、登録後、サービス提供者を表す「プロバイダー」を作成。プロバイダー内で新規チャネルを作成。チャネルの種類はMessage APIを選択。
#(5)Herokuの環境変数を設定
Herokuにログインして、アプリを作成する。今回は、testlinebot0319という名前とした。
heroku login
heroku create testlinebot0319
初期化して、
git init
herokuのアプリとgitを紐つけて、
heroku git:remote -a testlinebot0319
herokuの環境変数に、Line developersの「アクセストークンの文字列」と「チャンネルシークレットの文字列」を設定する。
例えば、heroku config:set YOUR_CHANNEL_ACCESS_TOKEN="チャネルアクセストークンの文字列" -a (アプリ名)とする。
heroku config:set YOUR_CHANNEL_ACCESS_TOKEN="チャネルアクセストークンの文字列" -a testlinebot0319
heroku config:set YOUR_CHANNEL_SECRET="チャネルシークレットの文字列" -a testlinebot0319
heroku上に環境変数がちゃんとセットされたか確認。
heroku config
#(6)その他、必要なファイルを揃える
Procfile、runtime.txt、requirements.txtを作成する。
runtime.txtは、自身のpythonのバージョンを確認の上作成する。
python-3.8.0
Procfileは以下を記述。
web: python main.py
requirements.txtは以下をターミナルで入力して記述。
pip freeze > requirements.txt
#(7)Herokuへデプロイ
gitを再度初期化、紐つけて、addして、the-firstという名前でcommitする。
最後にHerokuにプッシュ。
git init
heroku git:remote -a testlinebot0319
git add .
git commit -m'the-first'
git push heroku master
heroku openして、
heroku open
ブラウザに以下が出れば成功。
#(8)LINE DevelopersのWebhook設定
以下のように、自分のHeroku上のアプリ名をLINE DevelopersのWebhook欄に設定する。Heroku上のアプリ名=testlinebot0319
この時、Webhookの利用をオンにしておく。
これで、LINE Developersの上記にあるQRコードを読み込み友達登録すればオウム返しのアプリの完成。
うまく、オウム返ししてくれないなどLINEBOTが機能しない場合は、Webhookの利用を、オン、オフを繰り返すとる場合がある(私の場合はそれでうまくいった)。
#参考にしたサイト
1時間でWikipedia検索できるLINE BOTをサクッと作ってみよう!
Python + Flask + HerokuでLINE BOT
【Python初心者! -LINE Botでオウム返し編-】