LINEのChatbotを作ってみる(Python+Herokuバージョン)

LINEのDeveloper登録からチャネル作成までは前回記事と同様。

また、Herokuの登録、CLIのインストールも同様に行っておく。

今回はHeroku CLIを使って操作する。

 

まずheroku loginでHerokuにログインする。

次に、以下のコマンドでアプリケーションを登録する。

heroku create linebot

このコマンドで、自動的にリモートリポジトリとして、git...を登録してくれる。

 

次に、環境変数の設定をする。Messaging APIへのアクセスに必要なChannel secretと、Channnel access tokenを設定。

heroku config:set LINE_CHANNEL_ACCESS_TOKEN="XXXXXXXXXXXXXXXXXXXXXXXXX" --app linebot
heroku config:set LINE_CHANNEL_SECRET="XXXXXXXXXXXXXXXXXXXXX" --app linebot

 

続いてローカルでファイル作成に入る。

まずはpythonの仮想環境の作成。前回はあまりまとめていなかったので。

 

自分の環境ではAnacondaをインストールしているため、python関係の設定はAnaconda promptで実施する。Anaconda promptを開き、

conda create -n myenv (myenvは適当な名前)

proceed[y/x] はyを選択。

activate myenv

で仮想環境を有効にする。なお、

conda info -e

で現在ある仮想環境のリストが表示される。

 

この仮想環境下で、

pip install flask

pip install line-bot-sdk

でインストール。

 

つづいて、Windowsエクスプローラー上で、以下のディレクトリ構造を作成。

linebot

  |---Procfile

  |---main.py

  |---runtime.txt

  |---requirements.txt

 

それぞれのファイルの内容は、

Procfile

web: python main.py

プログラムの実行方法を定義する設定ファイル。この作り方を間違えてハマった。スペースの有り無しに注意。また、ファイル名に拡張子が無いことにも注意。

 

runtime.txt

python-3.7.0

プログラムを作成したPythonのバージョンを入れること。

 

requirements.txt

Flask==1.0.2
line-bot-sdk==1.8.0

インストールするライブラリを記載する。

 

main.py(メインのプログラム)

# インポートするライブラリ
from flask import Flask, request, abort

from linebot import (
LineBotApi, WebhookHandler
)
from linebot.exceptions import (
InvalidSignatureError
)
from linebot.models import (
FollowEvent, MessageEvent, TextMessage, TextSendMessage, ImageMessage, ImageSendMessage, TemplateSendMessage, ButtonsTemplate, PostbackTemplateAction, MessageTemplateAction, URITemplateAction
)
import os

# 軽量なウェブアプリケーションフレームワーク:Flask
app = Flask(__name__)


#環境変数からLINE Access Tokenを設定
LINE_CHANNEL_ACCESS_TOKEN = os.environ["LINE_CHANNEL_ACCESS_TOKEN"]
#環境変数からLINE Channel Secretを設定
LINE_CHANNEL_SECRET = os.environ["LINE_CHANNEL_SECRET"]

line_bot_api = LineBotApi(LINE_CHANNEL_ACCESS_TOKEN)
handler = WebhookHandler(LINE_CHANNEL_SECRET)

@app.route("/callback", methods=['POST'])
def callback():
# get X-Line-Signature header value
signature = request.headers['X-Line-Signature']

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

# handle webhook body
try:
handler.handle(body, signature)
except InvalidSignatureError:
abort(400)

return 'OK'

# MessageEvent
@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"))
app.run(host="0.0.0.0", port=port)

 

このプログラムたちをHerokuにデプロイする。

コマンドは、

git init

heroku git:remote -a linebot

git add .

git commit -m "new commit" (""内にコメント)

git push heroku master

 

あとはHerokuでWebhookの設定。

WebhookのURLに、

https://<アプリケーション名>.herokuapp.com/callback

を入れて、Webhook通信を有効にする。

callbackを入れるのを忘れずに。

 

これで完成!なはず。

LINEのChatbotを作ってみる(LINE tutorialバージョン)

コードは自分で全く書かない、目にすることもないバージョン。

LINE Developersのクイックスターにあるサンプルボットのトレース。

 

まず準備として、LINEでボット用のチャネルを作成する。

LINEアカウントへのログインに使用しているメールアドレスとパスワードを使って、LINE Developersコンソールにログインする。

続いて、新規プロバイダーを作成する。アプリを提供する組織の登録のことだが、ここでは個人用なので適当に。そこに新しいチャネルを作成する。名前は適当でよい。

 

続いてHerokuの設定。まずHerokuのアカウントを作成しておく。

 

LINE Developersコンソールで、上記で作成したチャネルを開き、Basic settingsタブ上でChannel secretの文字列を確認、またMessaging APIタブの下の方でChannel access tokenの文字列を確認。

 

チュートリアルとして用意されているGitHubのsample-spring-boot-echoディレクトリのREADMEファイルの、Deploy Herokuをクリックすると、HerokuのCreate New Appページが表示される。

 

上記で確認したChannel secret、Channel access tokenを入力、App nameは適当に。ただ、App nameは後で使うので覚えておく。Deploy Appをクリックするとしばらく待たされる。

 

LINE Developersコンソールで、Message APIタブのWebhook setting、Webhook URLに、「https://{HEROKU_APP_NAME}.herokuapp.com/callback」というURL形式で、Webhook URLを入力する。{HEROKU_APP_NAME}は上記でで指定したアプリ名。Use webhookはオンにしておく。

Message APIタブで、応答メッセージとあいさつメッセージは設定はオフにしておく。

スマートフォンのLINEアプリ、友達追加からMessage APIタブのQRコードを読み込み、このチャネルを友達設定する。

 

このアカウントにテキストメッセージを送ると、同じメッセージが返ってくる!

 

 

 

 

 

 

 

WhatsappのChatbotを作ってみる

日本語の情報だと、LINEのChatbotは多く検索できるが、WhatsappのChatbotはあまり出てこないのでまとめてみた。Pythonで作っているが、コードはほぼコピペしている。

参考にした、というかトレースしたサイトは、https://www.twilio.com/blog/build-a-whatsapp-chatbot-with-python-flask-and-twilioである。まだFlaskのフレームワークとか、Twilioのサービスとか全く知らないままに書いている。

ここで作るのは、Whatsappで特定の番号に、quoteという単語の入ったメッセージを送ると、ランダムに何か有名な引用句が返信され、catという単語が入っていると、ランダムで猫の画像が返信されるというもの。

 

画像1

 

まずはTwilioに登録する必要がある。https://www.twilio.com/からアカウント登録を行う。登録が終われば左上のメニューからProgrammable Messagingを選び、Try it Out, Try WhatsAppをクリックする。すると、SandboxのナンバーとJoinコードが表示される。

 

画像2

自分のWhatsappアカウントとSandboxを関連付けるために、このSandboxの番号にJoinコードを送る。Whatsappから新しい連絡先としてこの電話番号を登録し、そこにjoin ****-***と送信すると、メッセージの送受信を開始できることを示す返信がTwilioから届く。

ここからはPythonでの仕事。例に沿ってChatbot用にディレクトリを作成し、その中に仮想環境を作成する。そこにChatbotに必要なPythonパッケージをインストールしていく。

 

自分の場合はAnaconda promptで、 

$ mkdir whatsapp-bot
$ cd whatsapp-bot
$ conda create -n whatsapp-bot
$ conda info -e (仮想環境の確認)
$ activate whatsapp-bot
$ pip install twilio flask requests
この操作でインストールされるのが、
・Flaskフレームワーク:Webアプリケーションを作成するためのフレームワーク
・Twilio Pythonヘルパーライブラリ:Twilio APIを操作するためのライブラリ
・Requestsパッケージ:サードパーティAPIにアクセスするためのパッケージ
 
ここからがChatbotの作成。
 
WhatsApp用のTwilio APIは、メッセージ着信がある場合にWebhookを利用し、アプリケーションに通知する。Flaskフレームワークを利用すると、Webhookを簡単に定義できる。
 
実際のコード(トレースしたサイトからコピペ)はこちら。
 
from flask import Flask, request
import requests
from twilio.twiml.messaging_response import MessagingResponse

app = Flask(__name__)


@app.route('/bot', methods=['POST'])
def bot():
    incoming_msg = request.values.get('Body', '').lower()
    resp = MessagingResponse()
    msg = resp.message()
    responded = False
    if 'quote' in incoming_msg:
        # return a quote
        r = requests.get('https://api.quotable.io/random')
        if r.status_code == 200:
            data = r.json()
            quote = f'{data["content"]} ({data["author"]})'
        else:
            quote = 'I could not retrieve a quote at this time, sorry.'
        msg.body(quote)
        responded = True
    if 'cat' in incoming_msg:
        # return a cat pic
        msg.media('https://cataas.com/cat')
        responded = True
    if not responded:
        msg.body('I only know about famous quotes and cats, sorry!')
    return str(resp)


if __name__ == '__main__':
    app.run()
詳細はサイトを参照のこと。
 
このコードをbot.pyにコピーしておき、python bot.pyを実行してChatbotを起動する。出力は以下のようになる。
 
(whatsapp-bot-venv) $ python bot.py
 * Serving Flask app "bot" (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: off
 * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit
これでアプリケーションはPC内のポート5000でプライベートサービスとして実行され、待機状態となる。ここにインターネットからアクセスする必要がある。
 
ここではまずテストとして、ngrokを利用する。
 
ngrokの公式サイトからユーザ登録をする。GoogleアカウントでもなんでもOK。Setup$InstallationからOSにあったファイルをダウンロードする。自分はWindowsのファイルをダウンロード。Zipファイルの中には実行ファイルが入っている。
 
ngrok.exeを実行し、ngrokのサイトのSetup&Installationにある、Connect your accountに記載されているngrokのコマンドを実行、認証トークンを取得する。これで準備完了。
 
ngrok.exeのターミナルウィンドウから、ngrok http 5000を実行し、HTTPリクエストをローカルポート5000にリダイレクトする。Forwardingで始まる行が、ngrokがリクエストをサービスにリダイレクトするために使用するURLを示す。このURLをTwilioが使用するように指示する必要がある。
 
Twilioコンソールに移動し、再度Programmable Messaging, そこからSettingをクリック、WhatsApp Sandbox Settingを開き、ngrokのForwarding以降にあるアドレスを、TwilioのWhen a message comes inのフィールドにコピーする。コピーしたURLの最後に、/botを追加するのを忘れないこと。さらに、その後にページ下部にあるSaveボタンを押すのを忘れないこと。
 
さあこれで準備完了。Whatsappでメッセージを送ってみよう。
 
諸注意として、ここで使用したFlaskに付属するWebサーバーはとても便利だが、本番環境にはセキュリティの面で不十分である。PythonのWebアプリケーション用の本番環境対応のWebサーバーとしては、gunicornとuWSGIがある。次回はそちらを試してみる。