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がある。次回はそちらを試してみる。