ワタナベ書店

読んだ本の感想とか美味しかったお店の紹介とかLinuxの知見とか好きなことを好きなだけ書くブログです。

Twilio StudioとDialogflowで作るサーバレス自然言語による自動応答電話(IVR)システム ~Kintoneでの可視化も添えて~

タイトル盛りすぎ。

ところで「お前が神を殺したいなら、とあなたは言った」が完結しましたね。
このブログを読んでる各位はもうすでにお読みでしょうが、念の為に言っておきますと、とても面白いので読みましょう。
異世界転生宗教改革ものですよ。陰謀策略政治会話群像劇が好きな人絶対楽しいですよ。

なお、この話が好きな方は不朽のフェーネチカも好きだと思うのでぜひ。

まえがき

Dialogflow とはGoogle Homeのアプリ作成で使用されている自然言語対話のプラットフォームです。
ただし、Dialogflow はGoogle Homeアプリだけに使うわけではなく、APIを用いて直接自然言語対話をリクエストすることができます。
よって、Google Homeアプリだけでなく、直接スピーカーとマイクを用いてDialogflowと直接通信することもできるし、チャットサービスのバックエンドで使用することもできます。

じゃあ、Dialogflowを使えばテキストや音声を経由して何か情報を受け取ったり送信したりするシステムは自動化できるよね?ってことで電話をプログラミングできるサービス「Twilio」と組み合わせてみました。

TwilioのバックエンドでDialogflowが動作するので、曖昧な質問や、言い方を変えてもDialogflow側がうまく吸収してくれて、自動応答では従来難しかった、問い合わせに回答できる自動応答電話システムを作ることができました。

更にサーバレスで構成できたので、プログラムを走らせるサーバの運用は不要となり、TwilioとDialogflowのサービスが生きている限り、自動で電話応答してくれるシステムになりました。
料金も1通話5〜10円くらいでした。

自動応答システムの流れ

  1. Twilioで買った電話番号にカスタマーが電話。それに関連付けられたTwilio Studioのフローが実行される
  2. Twilioの音声認識サービスで相手の音声をテキスト化(デフォルトの機能である!)
  3. テキストをTwilio FunctionにてDialogflowに送信(ここだけコードを書く必要あり)
  4. Dialogflow側でテキストに応じたレスポンスを返す
  5. Twilio Studioでレスポンスを発話(Amazon pollyがデフォルトで使える!)
  6. 会話終了まで2-5のフローを繰り返す

用意するもの

Twilioアカウント(要電話番号購入)
Dialogflowが使用可能なGCPアカウント

作り方

Dialogflowで会話集の作成。及び、それを使うための鍵をダウンロードする

Dialogflow にログインし、適当に会話集を作りましょう。これが電話で質問されたときの回答となります。

会話例
「パソコンが壊れました」→「Macbookを買いましょう」 
「なにか面白い本を教えて」→「アリュージョニストを読みましょう」

一つだけ必ず作る会話集が「end」という名前で電話を終わりにする会話集です。
「ありがとうございました」とか「終わり」とか電話を終了させる言葉を登録してください。

作成が終わったらDialogflow の設定からAPIのバージョンをV2にします。
その後、GCPの認証情報ページから、
認証情報を作成→サービスアカウントキー→サービスアカウントでDialogflowを選択→作成でDialogflowをTwilioで使うためのjsonファイルがダウンロードできます。

Twilio FunctionでDialogflowにリクエストを投げるための関数をつくる

Twilioにログインし、Twilio Runtime を開きます。
Assets を開き、先程ダウンロードしたjsonプライベートでアップロードします。パブリックで公開するとお金的に死ぬ可能性があります
そうすると、Twilio Functionで実行するときにそのファイルを読み込めるパスが入手できます。 Runtime.getAssets()['Dialogflow-*******.json'].open() みたいな。

次にTwilio Functionを開き、設定のDependenciesという項目からdialogflowのnpmモジュールを登録しましょう。saveを押すとTwilio Functionでdialogflowのnode.jsモジュールが使えるようになります。

準備が終わったので、管理から新しいFunctionをBlankで作成します。
名前は「dialogflow_get_intent」にしましょう。 Functionに登録する関数は次のコードを貼り付けてください。
鍵のファイル名やdialogflowの名前を変えることを忘れずに。SAVEをしたら完成です。

gist.github.com

Twilio Studioで会話フローを作る。

基本、上のようなフローを作っていけばOKです。
以下、手順と詳細な設定について解説していきます。

Twilio Studio を開いて、新しくFLOWを作ります。
名前は任意で問題ありません。今回は「Twilio2Dialogflow」とします。
テンプレートは用いないので「Start from scratch」を選択してください。

  • 会話のスタートと音声のテキスト化

まず、Gather Input on Callをドラッグして、Incoming Call Triggerに接続します。
名前は「gather_dialogflow_command」にして、次のように設定します。
これだけで、会話内容が自動でテキスト化されます。

WIDGET NAME:
gather_dialogflow_command

SAY OR PLAY MESSAGE:
Say a Message

TEXT TO SAY:
{% if  widgets.dialogflow_intent_processing.parsed.intent_response %}
{{widgets.dialogflow_intent_processing.parsed.intent_response}}
{% else %}
こんにちは. せにょーるサポートセンターにようこそ.  この自動応答は自然言語に対応しています. 
なにかお困りでしょうか
{% endif %}

  • テキスト化した音声をDialogflow送る

Run Functionをドラッグして、TwilioとDialogflowをつなげる仕組みをつくります。
名前は「dialogflow_intent_processing」にして、

WIDGET NAME:
dialogflow_intent_processing

FUNCTION URL:
dialogflow_get_intent

Function Parameters:
speech_results  {{widgets.gather_dialogflow_command.SpeechResult}}
call_sid    {{trigger.call.CallSid}}
from    {{ trigger.call.From}}

これをgather_dialogflow_commandのUser Said Somethingとつなげましょう。

  • 会話の終了条件判定をする

Split Based On をドラッグして、次のように指定します。 Dialogflowで作った「end」の会話が来た場合は電話を終了する設定を追加します。 (ここを増やせば会話の内容で、使うDialogflowのエージェントを分岐させることができるので自動応答が充実します)

WIDGET NAME:
split_dialogflow_end

VARIABLE TO TEST:
widgets.dialogflow_intent_processing.parsed.intent_name

translationsタブ:
IF NO CONDITION MATCHES:
gather_dialogflow_command

Equal to end の分岐を設定

endの会話をしない限りは、gather_dialogflow_commandに戻り、
TEXT TO SAYのIF文に記載してあるとおり、 dialogflowの台本に登録した回答が電話から合成音声となり再生されます。

  • 会話終了 Say/ Playをドラッグして、次のように指定。
    作り終えたら、split_dialogflow_endのend時の分岐とつなげましょう。
WIDGET NAME:
say_play_last

SAY OR PLAY MESSAGE:
Say a Message

TEXT TO SAY:
ありがとうございました.
またなにかございましたら.お電話ください.

これでフローの作成はだいたい終わりです。右上にあるPublishからフローをアップロードしましょう。

会話の入力がない場合は発生を急かすフローを作ったり、細かいところを手直しする必要がありますが、
基本的な会話の流れは上記の手順で完成したので問題なく応答できます。

なお、作ってはいませんがdialogflowのパラメータが足りないときに聞き返すフローも作成できます。
(widgets.dialogflow_intent_processing.parsed.status で分岐させましょう。)

電話番号を購入し、Twilio Studioと関連付ける

Twilioのコンソールから電話番号の管理を選択し、IVRと接続したい電話番号を選択します(電話番号買ってないなら買いましょう!)

通話着信時をStudio Flowを選択し、更に「Twilio2Dialogflow」を選択し保存すれば完了です。
問題なければ購入した電話番号で自然言語処理による電話の自動応答が完成します。

使いみち

電話対応の一次受付や、簡単な問い合わせに対する解答、もともとDialogflowでスマートスピーカーやチャットボットのサービスを作っていたらその資産を流用したりすることも可能だと思います。
更に自動応答で回答できない質問が来た場合は、人間の電話に転送することも可能なので便利な気がします。

応用

自動で応答できるということは、そのログを自動で記録化することもできるということなので、 kintoneで電話内容を記録してみました。
Twilio Functionsを次のとおりに書き換えてください。

gist.github.com

これでkintoneでかかってきた電話番号と問い合わせ内容が自動で記録化できます。
良かったですね。

参考URL

GitHub - googleapis/nodejs-dialogflow: Node.js client for Dialogflow: Design and integrate a conversational user interface into your applications and devices.
Twilio StudioでIVRを構築する - Twilio
https://www.linkedin.com/pulse/build-conversational-ivr-60-minutes-twilio-studio-ameer-badri/