概要
LINEbotのバックエンドをさまざまなサービスを利用して作ってみようというシリーズです。
第1弾はngrokを利用します。
また今回の記事に限り、導入編としてLINE Developersへの登録などの手順も記載に含めます。
そのほかのサービスを利用した構築については、以下を参照ください。
- 第1弾:ngrok ※本記事
- 第2弾:Heroku
- 第3弾:Google CloudFunctions ※近日更新
- 第4弾:Google Cloud Run
- 第5弾:Google Kubernetes Engine
- 第6弾:AWS Lambda (予定)
前提
- LINEのアカウントを持っている
- ローカルでPythonが実行可能な状態である
全体像
LINE Developers準備
2020/10時点でのキャプチャ・手順です。今後、変更が出る可能性がある点はご留意ください。
ログイン
Messaging APIを利用するため、まずはLINE Developersへアカウント登録をしましょう。
まず、こちらへアクセスし、右上のログインボタンを押下します。
次の画面では、「LINEアカウントでログイン」を押下します。
すると以下のような画面が表示されるので、LINEに登録しているメールアドレス・パスワードを入力するか、QRコードをスキャンするかのいずれかの方法でログインをします。成功すれば、コンソールのホーム画面へ遷移します。
Channel作成
ホーム画面にProviders
というセクションがあるので、横の「Create」ボタンを押下し、Provider name
欄に任意の名称を入力します。
※作成に失敗するケースは、名称に問題があるので、適宜変更をしてみてください。
Providerのホーム画面へ遷移するので、「Create a Messaging API Channel」ブロックを押下します。
情報の入力画面に遷移するので、以下を入力します(必要最低限の項目のみ記載)。
- Channel icon:アイコン、必須ではないけれど白アイコンは寂しいので、なんでもよいから設定しておきたい
- Channel name:チャンネルの名前、任意の名称でOK
- Channel description:チャンネルの説明、「LINE Bot練習用」などでOK
- Category:チャンネルのカテゴリ、なんでもよいが困ったら「個人」
- Subcategory:チャンネルのサブカテゴリ、なんでもよいが困ったら「個人(その他)」
- 最下部の規約リンクを確認、チェックボックスをONにする(2箇所)
Channel SecretとChannel Access Tokenの発行
バックエンドで利用するので、この段階で発行しておきます。
なお、この2つの値は他人に知られないように慎重に保管するようにしてください。
- Channel Secret
Basic settings
タブのChannel secret
部分の文字列です。こちらはチャンネルを作成した段階で発行されています。
- Channel Access Token
Messaging API
タブ最下部のChannel access token
部分の文字列です。こちらはデフォルトでは発行されていないので、「Issue」ボタンを押下して生成しましょう。
友だち登録
Messaging API
タブにQRコードがあるので、LINEアプリでスキャンして友だち登録しておきましょう。
バックエンドサーバの構築
ソースコード
line-bot-sdk-pythonのコードをコピーして、ローカルにapp.py
という名前で保存します。
そして、以下のようにシークレット情報を設定します。
-
YOUR_CHANNEL_SECRET
と書かれている部分(L16)をChannel secret
で取得した文字列に置き換える -
YOUR_CHANNEL_ACCESS_TOKEN
と書かれている部分(L15)をChannel access token
で取得した文字列に置き換える
# 例
line_bot_api = LineBotApi('YXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXZGG==') # こっちが長い方の文字列
handler = WebhookHandler('fxxxxxxxxxxxxxxxxxxxxx')
※本編ではローカルでのみ起動することを想定しているため、ソースコードにベタ書きしますが、アンチパターンである点ご注意ください。
ライブラリインストール
ソースコードはライブラリを利用しているので、ライブラリのインストールが必要です。ターミナルで次のコマンドを実行します。
pip install Flask line-bot-sdk
ngrokのインストール
ngrokとは一言でいうと、ローカルで起動しているプロセスへインターネットを介して外部からアクセスできるようにサービスです。なにより、https
での公開エンドポイントが用意される点が非常に大きいです。(WebhookURLはhttps
である必要がある)
MacOSの場合は1つめのHomebrew
でインストールすることをおすすめします。そのほかは2つめのコマンドでインストールします。
MacOSの場合
brew cask install ngrok
その他の場合
wget https://bin.equinox.io/c/4VmDzA7iaHb/ngrok-stable-linux-amd64.zip
unzip ngrok-stable-linux-amd64.zip
mv ngrok /usr/local/bin/ngrok
インストール確認
正しくインストールされているか確認しておきましょう。ngrok
コマンドを実行し、下のような表示が出ていれば問題ありません。
停止する際はCtrl + C
を入力します。
ngrok http 80
実行結果
ngrok by @inconshreveable (Ctrl+C to quit)
Session Status online
Session Expires 7 hours, 59 minutes
Version 2.3.35
Region United States (us)
Web Interface http://127.0.0.1:4040
Forwarding http://a9e65703bdfa.ngrok.io -> http://localhost:80
Forwarding https://a9e65703bdfa.ngrok.io -> http://localhost:80
Connections ttl opn rt1 rt5 p50 p90
0 0 0.00 0.00 0.00 0.00
オウム返しさせる
では、いよいよサーバを立ち上げて、メッセージがオウム返しされるところを確認しましょう。
バックエンドサーバの起動
ターミナルで以下のコマンドを実行します。
なお、Pythonのファイル名がapp.py
ではない場合は、環境変数FLASK_APP
にそのファイル名を設定する必要があります。
flask run --reload --port 8080
# 以下のように表示されていれば、起動状態
* Environment: production
WARNING: This is a development server. Do not use it in a production deployment.
Use a production WSGI server instead.
* Debug mode: off
* Running on http://127.0.0.1:8080/ (Press CTRL+C to quit)
現在の状態を図にすると以下となります。
サーバの外部公開
別のターミナルを起動して、以下のコマンドを実行します。
そして、Forwarding
と書かれている行のhttps
で始まる側のURLをコピーします。
ngrok http 8080
Forwarding http://e5e58099a87e.ngrok.io -> http://localhost:8080
Forwarding https://e5e58099a87e.ngrok.io -> http://localhost:8080 # こっち
現在の状態を図にすると以下となります。
WebhookURLの設定
ここで一度LINE Developersの画面に戻ります。
Messaging API
タブのWebhook URL
の部分に「先程コピーしたURL + /callback
」を入力します。
また、上記画像のEditボタンから応答設定画面へ遷移し、次のように設定してください。
- 応答メッセージ:OFF
- Webhook:ON
これでLINEへメッセージを送るとngrokエンドポイントを経由し、ローカルで起動しているサーバへリクエストが飛ぶようになりました。
メッセージを送る
友だち登録しておいたBotで実際にメッセージを送ってみましょう。同じメッセージが返ってくれば成功です!!
注意点
ngrok
は起動するたびに異なるエンドポイントを発行するため、一度終了したのちに再度起動した場合はLINE DevelopersのWebhookURLもあわせて修正する必要があります。
ステップアップ
ソースコードについての解説は省きましたが、sdkのソースコードではテキストメッセージのオウム返しをするのみでした。
ステップアップとして挙動を変更する以下の2例を課題的に記載しておきますので、よろしければチャレンジしてみてください。
1. 常に「メッセージありがとう!」と返事をするようにする
こたえ
handle_message
関数のtext
で指定している値が返事の内容となります。
もともとのソースではevent.message.text
が設定されており、このevent.message.text
というものはこちらが送信したメッセージの内容なのでオウム返しとなっていたわけですね。
つまりはtext
に「メッセージありがとう!」と設定すればよいです。
def handle_message(event):
line_bot_api.reply_message(
event.reply_token,
- TextSendMessage(text=event.message.text))
+ TextSendMessage(text='メッセージありがとう!'))
2. スタンプを送ったら、「かわいいスタンプだね」と返事するようにする
こたえ
なぜテキストメッセージだけがハンドリングされているかというと、@handler.add(MessageEvent, message=TextMessage)
のデコレータで、WebhookHandlerに「TextMessage種別のメッセージイベントが来た場合は、handle_message
関数の処理を行う」というようにしているためです。
これと同じ要領でスタンプ種別(StickerMessage)のイベントを処理する関数を追加すればよいです。
+ @handler.add(MessageEvent, message=StickerMessage)
+ def handle_sticker_message(event):
+ line_bot_api.reply_message(
+ event.reply_token,
+ TextSendMessage(text='かわいいスタンプだね'))
ほかにどのようなイベント種別・メッセージ種別があるのかはAPI仕様を見ると良いでしょう。
おわりに
ローカルで手軽に動作確認ができる点は非常によいと思います。
しかしながら、ずっとローカルで起動している必要があったり、起動するたびにWebhookURLを設定し直すのはメンドウですよね。
クラウドサービスを用いてサーバ起動することでこの手のメンドウは解決することが可能ですので、次回以降触れていきたいと思います。