kun432's blog

Alexaなどスマートスピーカーの話題中心に、Voiceflowの日本語情報を発信してます。たまにAWSやkubernetesなど。

〜スマートスピーカーやVoiceflowの記事は右メニューのカテゴリからどうぞ。〜

Voiceflow TIPS #14 Googleスプレッドシート連携で作るゼロカロリースキルもどき 〜スプレッドシートへの登録〜

Voiceflow夏休みAdvent Calendarの14日目です。

Googleスプレッドシート連携シリーズ第3回です。前回、検索機能まで実装した「ゼロカロリースキル」に「登録」機能を追加していきたいと思います。

前回のあらすじはこちら。

ではまずスキルの実行イメージから。


アレクサ、「ゼロカロリースキル」をひらいて

ゼロカロリースキルです。カロリーを知りたい食べ物の名前を言ってください

カツカレーを登録

カツカレーを登録します。理由をお聞きます。最初に、理由、最後に、から、をつけていってください。例えば、理由、ほにゃほにゃだから、という感じで言ってください。

理由、カツとカレーのカロリーが相殺されるから

カツカレーは、カツとカレーのカロリーが相殺されるから、カロリーゼロ、で登録します。よろしいですか?

はい

カツカレーを登録しました。カロリーを知りたい食べ物の名前を言ってください・・・


オリジナルの方では、LINE BOTで実装されていましたが、今回はすべて音声でやってみたいと思います。果たしてうまくいくでしょうか?例によって、エラー処理は最低限の処理のみとします。

スキルの全体図

下のほうが今回新たに追加したブロックです。このブロックで登録処理を実装します。

f:id:kun432:20190814222313p:plain

前回作成したブロックのうち、Interaction Blockだけは、登録を受け付けるためのインテントを追加する必要がありますので、修正します。

では順に見ていきましょう。

Interaction Blockに登録用インテントを追加

前回作成したときには、検索用のインテントだけを追加しました。

f:id:kun432:20190814224220p:plain

f:id:kun432:20190814224228p:plain

f:id:kun432:20190814224240p:plain

今回は、同様にして、登録用のインテントを作成します。なお、手前のSpeak Blockのところで登録を促すメッセージを入れてもよいのですが、今回、登録機能はちょっと隠し機能的な意味合いとして、割愛します。Interaction Blockをクリックして、順に設定します。

まずSlotタブ。ここは変更の必要はありません。「○○○を登録」と発話した場合、○○○に入るのは食べ物名、すなわち、前回検索で登録したスロット "slot_recipe" がそのまま使えます。

f:id:kun432:20190814225545p:plain

次にIntentsタブです。検索用のインテントが見えていますね。ここに登録用インテントのサンプル発話とスロットを設定していきます。"Add Intent"をクリックします。

f:id:kun432:20190814225627p:plain

新しいインテント名を"add_intent"として、以下のようにサンプル発話を入力します。スロットの部分は、"["を入力してから表示されるスロット名を選択することに注意してください。

f:id:kun432:20190814225755p:plain

最後にChoicesタブです。インテントに合致したサンプル発話を受けてフローを分岐させます。"Add Choice"をクリックします。

f:id:kun432:20190814225907p:plain

Interaction Blockに新たな分岐(「2」)が追加されましたね。これで新しいインテントへのフローが作成されました。設定のほうにも新しい入力が追加されているので、先程作成した"add_intent"をドロップダウンから選択して、スロット"[slot_recipe]" と 変数 "{varRecipe}"を選択してください。

f:id:kun432:20190814225918p:plain

これでInteraction Blockの変更は完了です。

登録フローへのブロック追加

新しく追加された登録用の分岐にブロックを追加していきます。

1. Speak Blockを追加

登録の仕方を促すSpeak Blockを以下の通り追加して、先程のInteraction Blockの新しい分岐とつなぎます。

f:id:kun432:20190814231040p:plain

2. Interaction Blockで理由を受け取るインテントを追加

次にInteraction Blockを追加して、理由を受け取るためのインテントを設定します。このインテント、最初の例で「理由 ほにゃほにゃだから」みたいな形にしたのは理由があります。

通常、インテントの中に含めるスロットは、予め用意されたタイプから選択する必要があります。例えば最初の食べ物名で使用した「AMAZON.Food」とかがそうですね。これ以外にユーザがスロット候補を用意する「カスタムスロットタイプ」もあります。今回の「理由」のような「比較的自由な発話」を取る場合を想定した「AMAZON.SearchQuery」というスロットタイプも用意されていますのでこれを使うのですが、このスロットタイプは他のスロットタイプと違い、スロットだけでの発話を取ることができません。必ず、スロットの前か後に、何らかの表現を含める必要があります。

可否 サンプル発話例
[SearchQueryスロット]
[SearchQueryスロット] について検索して
キーワード [SearchQueryスロット]
キーワード [SearchQueryスロット] について検索して

なので今回は、最初に「理由」と言ってから、実際の理由を話すような感じでサンプル発話を設定していきます。

利用可能なスロットタイプについては以下も参照してみてください。

ではインテントを作りましょう。まずSlotタブ。「理由」をスロットとして受け取りますので、今回はスロットの登録が必要です。

と、おや、、、、前に登録した「slot_recipe」が見えていますね・・・?

f:id:kun432:20190814234452p:plain

これ、問題ではないので安心してください。Interaction Blockでは、スロットやサンプル発話、インテントなど、一度登録したものは他のInteraction Blcokでも共有されます。ただし、共有されているといっても、設定を変更しなければ影響はありませんし、あとで出てくるChoiceタブで対象のインテントを選択しない限りは呼び出されることはありません。

インテントは会話フローの特定の場面で1回だけで出てくるわけではありません。会話の流れによっては別の場所で同じようなインテントを使うこともありますよね。そういった場合に1回登録したものを再利用できる、というふうに考えてもらえればよいかと思います。

話が脱線しましたが、スロットを登録しましょう。"Add Slot”をクリックして、以下のように理由を受け取るための新しいスロット、"slot_reason"を設定します。ここで先程のSearchQueryタイプを選択します。

f:id:kun432:20190814235332p:plain

次にIntentsタブです。ここも以前登録した「検索用インテント(search_intent)」と、先程登録した「登録用インテント(add_intent)」が見えていますね。ここに理由を受け取るインテントのサンプル発話とスロットを設定していきます。"Add Intent"をクリックして、以下のように新しいインテント、"capture_reason"を設定します。

f:id:kun432:20190814235647p:plain

最後にChoicesタブです。先ほどとは異なり、ここにはこれまで登録したインテントへのフローが見えないですよね。"Add Choice"をクリックして、ドロップダウンを開いてみてください。

f:id:kun432:20190814235930p:plain

はい、先程のインテントが見えましたね。このようにここで呼び出すことによって初めてそのインテントが呼び出されるというわけです。なので、前に登録したものが見えても、ここで指定しない限りは使われないということがわかっていただけるかと思います。では気を取り直して、先程追加した"capture_reason"インテントを選択、そして、スロットと変数のマッピングです。スロットは"[slot_reason]"、変数は前回登録している"{varReason}"を選択します。

f:id:kun432:20190815000535p:plain

はい、これで理由が変数で取れるようになりました。

3. 食べ物名と理由の確認

受け取った理由で登録してもよいかを確認するために、Speak BlockとInteraction Blockを追加して、以下のように設定します。

f:id:kun432:20190815001110p:plain

f:id:kun432:20190815001123p:plain

「はい」の場合は「登録」すなわちGoogleスプレッドシートへのレコード追加に進むので後で説明するとして、先に「いいえ」のフローを作ります。「いいえ」の場合は、最初のカロリー検索のところまで戻してしまうのがよいでしょう。

f:id:kun432:20190815001812p:plain

4. Googleスプレッドシートへの登録

さあ、いよいよスプレッドシートへの登録をやります。Integration Blockを配置して、順に設定していきましょう。Google Sheetsを選択します。

f:id:kun432:20190815002845p:plain

登録なので"Create Data"を選択します。

f:id:kun432:20190815004426p:plain

スプレッドシート連携に使うアカウントを選択します。前回の検索時にアカウント連携は終わっているので、今回は選択するだけです。

f:id:kun432:20190815004441p:plain

連携するスプレッドシート名およびシート名を設定します。前回と同様に、スプレッドシート名「ゼロカロリースキル」、シート名「recipes」を選択します。

f:id:kun432:20190815013821p:plain

スプレッドシートの各カラムごとに登録する内容を設定します。recipeNameカラムにレシピ名、すなわち"varRecipe"、reasonカラムに理由、すなわち"varReason"を設定します。入力が終わったら"Next"をクリックします。

f:id:kun432:20190815013840p:plain

これで設定完了です。実際のテストの前にここで登録のテストをやってみましょう。"Test Integration"をクリックします。

f:id:kun432:20190815004719p:plain

テスト用のフォームが表示されます。変数部分が入力項目になりますので、食べ物名と理由を適当に入力して”Run”をクリックしてみてください

f:id:kun432:20190815005003p:plain

登録処理が終わると、Test Integraionに結果が表示されます。"Created row in Sheet ・・・"と表示されれば、登録が成功しています。

f:id:kun432:20190815005131p:plain

実際のGoogle スプレッドシートの方も見てみましょう。

f:id:kun432:20190815010907p:plain

おー、ちゃんと登録されていますね!これでGoogleスプレッドシートとの連携は完了です。

5. 成功時と失敗時のメッセージ

テストでは一応登録が成功していましたが、場合によっては失敗する可能性もありますし、成功した場合もその旨を伝える必要があります。失敗した場合はエラーを伝えてスキルを終了し、成功した場合は登録完了を伝えて、最初のカロリー検索のところまで戻してしまえば、登録した内容をすぐに確認できますね。

f:id:kun432:20190815013051p:plain

f:id:kun432:20190815013108p:plain

はい、これで完了です。お疲れさまでした!

テスト

では、テストしてみましょう。

f:id:kun432:20190815010255p:plain

ちゃんと登録ができて、それを検索で呼び出せていることがわかりましたね!もちろんGoogleスプレッドシートへの登録もちゃんとできています!

f:id:kun432:20190815010455p:plain


検索と登録ができると一気にスキルらしくなってきましたね!ただし、今の状態だと、同じ食べ物名があっても登録が可能で、かつ、最初に登録したものしか読み出されません。

ということで、次回は登録しようとした食べ物がすでに登録済みの場合を踏まえて「スプレッドシートの更新」をやってみたいと思います。またご覧いただければ幸いです。