前回のLINE BOTに続いて、今回はTwilioを使ったIVRチャットボットをVoiceflow SDKで作ってみました。
目次
コードとアーキテクチャ
サンプルコードはこちら。
構成は前回とほぼ同じ。Twilioで電話番号からStudio、そこからWebhookでローカルのnode.jsアプリにつないでます。
必要なもの
- node.js実行環境
- ngrok
- Twilio(Phone Numbers、Studio)の設定
- Voiceflowの設定
- Voiceflowのカスタムアシスタント向けサンプルプロジェクト
- VoiceflowプロジェクトのバージョンID
- VoiceflowのAPIキー
1、2、あと4〜6は前回と同じですので、説明は短めに。今回はTwilioの設定を中心に説明します。
アプリ実行
レポジトリをcloneして、npm install
します。
$ git clone https://github.com/kun432/voiceflow-twilio.git && cd voiceflow-twilio
$ npm install
次に、Voiceflow SDKで必要なバージョンIDとAPIキーを設定します。そう、この管理画面が正式にリリースされました。
ワークフロー画面から、右上の"Settings"アイコン(歯車のやつ)をクリックして、"Workspace Settings"をクリックします。
"Workspace Settings"に"Developer"というメニューが追加されていますね。これをクリックするとAPIキーの発行画面が表示されますので、APIキーを作成します。
バージョンIDは前回と同じです。coffeeshop.vf
ファイルをインポートして、プロジェクトのURLからバージョンIDをコピーしてください。
インポート後に、”Test”をクリックして、学習させておくこともお忘れなく。また、一度テストも実行しておいてください。
バージョンIDとAPIキーを環境変数にセットしておきます。
# VoiceflowのサンプルプロジェクトのバージョンID $ export VF_VERSION_ID="XXXXX...XXXXX" # Voiceflowのサンプルプロジェクトが存在するワークスペースのAPIキー $ export VF_API_KEY="VF.XXXXX...XXXXX"
アプリを起動します。
$ node .
listening on 3000
ngrokで公開します。
$ ngrok http 3000
前回同様、ngrokのURLを控えておいてください。
Twilioの設定
Twilioの設定は以下の流れになります。
- 電話番号の購入
- Twilio Studioでフローを作成
- 電話番号のWebhookにTwilio Studioのフローを指定
電話番号の購入については以下をご覧ください。
注意としては、
- 電話番号の購入には本人認証が必要になりました。免許証など個人を証明するものの画像をアップロードして認証しててもらう必要があります。認証は3営業日以内ということなので、事前にやっておくことをおすすめします。
- 電話番号は国内のもので良いと思います。海外の番号だとSMSやMMSも使えたりするのですが、このサンプルではSMS/MMSは不要ですし、テストで電話する場合は国際電話になってしまうので。
- ということで、電話料金が発生しますので予めご了承ください。
- 上記の手順の中にあるTwiML Binの設定は、Twilio Studioでフローを作成したあとで変更しますので、不要です。初めての方は実際に電話で応答することを確認するためにやってみてもいいかもしれません。
電話番号が用意できたら、Twilio Studioのフローを作成します。Twilio Studioは、Voiceflowと同じく、GUIで応答フローを作ることができるというものです。かんたんな自動応答であればTwilio Studioだけで作れたりします。Amazon Connectとかと似た感じですね。今回はマルチターンの会話を繰り返すために使ってて、会話のロジックはVoiceflow側に持たせています。このあたりのやり方は以下を参考にさせてもらいました。
では、Twilio Studioの会話フローを作りましょう。予めTwilio Studioのフローをファイルで用意してありますので、これをインポートするだけでできるようにしてます。
左のメニューから"Studio"を開きます。
”Create a flow”で新規にフローを作成します。
フローの名前を適当につけて、"Next"をクリックします。
フローの新規作成は、空から作ることも、テンプレートから作ることもできます。今回はファイルからのインポートで作りますので、下の方にある"Import from JSON"を選択して、"Next"をクリックします。
JSONのインポート画面が開きました。ここに用意してあるフローのファイル、twilio-studio.json
の内容をコピペで上書きして、"Next"をクリックします。
以下のようにフローが表示されればインポートは成功しています。
1箇所だけ変更をしましょう。上の方にある"defaults"というブロックの中で、ngrokのURLが表示されているのがわかるでしょうか?ここをngrokが生成したURLに書き換える必要があります。
"defaults"ブロックをクリックすると、右のメニューに設定が表示されます。"Config"タブの"Variables"タブでngrok_url
という変数が設定してあるので、"edit"をクリックして変更します。
URLを変更したら"Save"をクリックして、変数の設定変更を完了させます。
下にある"Save"もクリックして、ブロックの設定変更を完了させます。
ブロックのURLが正しく書き換わっていればOKです。
最後に一番上の”Publish”をクリックしてフローを公開します。
初回は以下のようなメッセージが表示され、"Publish"するだけではフローが使えず、電話から呼び出す必要があることを教えてくれます。このあとやりますので、一旦"Publish”をクリックします。
"Flow is up-to-date"と表示されればOKです。
では、電話をかけたらこのフローを呼び出すようにしましょう。
左のメニューから"Phone Numbers"を開きます。
購入した電話番号の設定画面を開きます。
下の方にある"Voice & Fax"のところに"A CALL COMES IN" というのがあるかと思います。これが購入した電話番号に電話がかかってきたときにどの処理を呼び出すか?という設定になります。
ここで先程作成したフローを実行するように設定すればOKです。まず、左のメニューでStudio Flow
を選択します。
右のメニューで先ほど作成したTwilio Studioのフローを選択します。
最後に一番下の"Save"をクリックすれば完成です!
テスト
では実際に電話をかけてテストしてみましょう。
うまくいきましたね!
コード
ほぼVoiceflow SDKのexpressサンプルからほとんど変わってないです。
最初はLINEの場合と同じように、普通にWebhookでTwiMLの応答を返す形でやろうと思ったのですが、Twilioからのリクエストにはユーザを識別するためのIDのようなものが渡ってきません。発信者番号通知を使えばできるのかなぁ?と思いながらも、非通知な場合も多いことを考えると、それも現実的ではない。
Twilio Studioの場合、Webhookのレスポンスを変数として保持することができます。これを使って、
- 初回はユーザID(というか正しくはセッションIDですね)がない状態でリクエストが飛んでくるので、アプリ側でユーザIDを発行し、Voiceflowのstateと紐付け。Voiceflowからのメッセージと一緒にユーザIDを含めて、Twilio Studioに返す。
- Twilio Studio側で、レスポンスからメッセージとユーザIDを取り出して、メッセージを発話しつつ、次のWebhookリクエストでユーザIDも付与してリクエスト。
- 2回目以降はこのユーザIDをもとにセッションを管理する
というやり方を行っています。詳しくはTwilio Studioのフローの設定も見ていただければと思います。Voiceflow SDKは会話の状態管理は行ってくれますが、そのためのキーとなるセッションIDのようなものはアプリ側で実装する必要があります。LINEの場合はリクエストにユーザIDが含まれていたため、やりやすかったのですが、プラットフォームの違いはこういうところにもあるのかーという感じです。
ただ、これによって、Twilioの応答フォーマットを気にしなくて良くなった(Twilio Studio側でやってくれる)ので、純粋な中継アプリになり、コードがとてもシンプルになりました。Twilio Studio、久々に触ってみましたが、マルチターンの会話の場合はWebhookやTwilio Functionsよりもやりやすい気がしました。
まとめ
Voiceflow SDKを使うと、比較的容易にマルチプラットフォームに対応できる、ということがわかっていただけましたでしょうか?
Voiceflow SDK公式のレポジトリには、
- Facebook Messenger
- Slack
- Microsoft Teams
- Discord
などとのインテグレーションのサンプルコードがありますので、こちらもぜひ見てみてください!