13
17

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

LINE BOT(オウム返し)を作る

Last updated at Posted at 2020-03-19

#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を作成

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のバージョンを確認の上作成する。

runtime.txt

python-3.8.0

Procfileは以下を記述。

Prockfile
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

ブラウザに以下が出れば成功。

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

#(8)LINE DevelopersのWebhook設定
以下のように、自分のHeroku上のアプリ名をLINE DevelopersのWebhook欄に設定する。Heroku上のアプリ名=testlinebot0319
スクリーンショット 2020-03-19 22.34.25.png

この時、Webhookの利用をオンにしておく。
これで、LINE Developersの上記にあるQRコードを読み込み友達登録すればオウム返しのアプリの完成。
うまく、オウム返ししてくれないなどLINEBOTが機能しない場合は、Webhookの利用を、オン、オフを繰り返すとる場合がある(私の場合はそれでうまくいった)。

#参考にしたサイト
1時間でWikipedia検索できるLINE BOTをサクッと作ってみよう!
Python + Flask + HerokuでLINE BOT
【Python初心者! -LINE Botでオウム返し編-】

13
17
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
13
17

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?