スロットを使って任意の入力を受け付けよう
Alexaとの複数回に渡るやりとり(ダイアログ)
ダイアログとは
Alexa Skills Kitにおけるダイアログとは、ユーザーによる一度の発話では収集しきれない情報を、何度かのやりとりを通じて得る方法です。このやりとりの間、収集途中の情報などを覚えておく、いわゆる状態管理を行う必要がありますが、これはスキル・インターフェース側でやってくれます。したがって、AWS Lambdaを使ったプログラム・コードでは、パラメーターとして渡されてくる情報に基づいて処理をすればよく、簡単に期待する動作結果を得られます。スキル・インターフェースとスキル・サービスの間の、ダイアログに関する動作の流れは次のようになっています。
一連の会話である「ダイアログ」が開始すると、「STARTED」というダイアログの状態コードがスキル・サービスに渡されます。このとき、スキル・サービスは、ダイアログの続きをスキル・インターフェースに委ねるために「Delegate」という返答をするとともに、スロットの既定の値をスキル・インターフェースに返すことができます。ダイアログの途中、まだ情報収集が完了していない間は「IN_PROGRESS」という状態コードが渡されます。このとき、スキル・サービスは単に「Delegate」と返答するだけで構いません。
ダイアログが完了すると「COMPLETED」という状態コードが渡されるため、スキル・サービスはスロットの値がそろっていることを期待して、処理を進めることができます。
ダイアログを追加する
開発者コンソールを開き、スキル編集画面の左メニューから「eventName」のスロット名をクリックすると、eventNameスロットの詳細を設定するページが開きます。イベント名を必須項目とするため、「このインテントを完了させるために、このスロットは必須ですか?」を選択します。
「Alexaの音声プロンプト」の欄には以下の内容を入力して[Enter]を押します。
どのイベントについて調べますか
イベント名を伝えずに来場者数を尋ねた場合に、Alexaはここに入力した言葉を使ってイベント名を聞き返します。
「ユーザーの発話」欄には、以下のように入力して[Enter]を押します。
{eventName}です {eventCity}で開催の{eventName}です
こちらは、上記の音声プロンプトに対するユーザーの返答例となります。設定が完了したら保存とビルドを忘れずに行いましょう。
スキル・サービスをダイアログに対応させる
さっそくコード例を示します。
'use strict'; const Alexa = require('alexa-sdk'); //============================================================================= //TODO: The items below this comment need your attention. //============================================================================= //Replace with your app ID (OPTIONAL). You can find this value at the top of your skill's page on http://developer.amazon.com. //Make sure to enclose your value in quotes, like this: const APP_ID = 'amzn1 .ask.skill.bb4045e6-b3e8-4133-b650-72923c5980f1'; const APP_ID = 'amzn1.ask.skill.b6030ab0-d878-4bd3-bff0-790750d638d2'; const SKILL_NAME = '来場者カウント'; const HELP_MESSAGE = '来場者数を教えて、で今日の来場者数をお知らせします'; const HELP_REPROMPT = '何をお調べしますか'; const STOP_MESSAGE = '終了します'; const visitorCount = 156; //============================================================================= //Editing anything below this line might break your skill. //============================================================================= const handlers = { 'LaunchRequest': function () { // このスキルを「開いて」とリクエストした場合に呼び出される // 今回は既定では何もしない this.emit(':responseReady'); }, 'VisitorCountIntent': function () { // VisitorCountIntent に対応して呼び出される if (this.event.request.dialogState === 'STARTED') { // インテントObjectを取得する let updatedIntent = this.event.request.intent; // スロットの初期値をセットする updatedIntent.slots.eventDate.value = '2018-04-03'; // スキル・インターフェースにダイアログの継続を依頼する this.emit(':delegate', updatedIntent); // 初期値あり } else if (this.event.request.dialogState !== 'COMPLETED') { // スキル・インターフェースにダイアログの継続を依頼する this.emit(':delegate'); } else { // インテントObjectを取得する let intent = this.event.request.intent; // スロットの値を取得する var eventCity = intent.slots.eventCity.value; var eventName = intent.slots.eventName.value; var eventDate = intent.slots.eventDate.value; // 結果を生成する const speechOutput = eventCity + 'の' + eventName + 'の' + eventDate + 'の来場者数は' + visitorCount + '人です'; // Alexa アプリで参照できる情報 (カード) を返す this.response.cardRenderer(SKILL_NAME, speechOutput); // 音声で返答する this.response.speak(speechOutput); this.emit(':responseReady'); } }, 'AMAZON.HelpIntent': function () { const speechOutput = HELP_MESSAGE; const reprompt = HELP_REPROMPT; this.response.speak(speechOutput).listen(reprompt); this.emit(':responseReady'); }, 'AMAZON.CancelIntent': function () { this.response.speak(STOP_MESSAGE); this.emit(':responseReady'); }, 'AMAZON.StopIntent': function () { this.response.speak(STOP_MESSAGE); this.emit(':responseReady'); }, 'SessionEndedRequest': function () { // Do nothing }, }; exports.handler = function (event, context, callback) { const alexa = Alexa.handler(event, context, callback); alexa.APP_ID = APP_ID; alexa.registerHandlers(handlers); alexa.execute(); };
「VisitorCountIntent」を処理するハンドラーの中では、以下のようにダイアログの状態別に処理をしています。
if (this.event.request.dialogState === 'STARTED') { 〜 STARTEDの場合の処理 〜 } else if (this.event.request.dialogState !== 'COMPLETED') { 〜 途中(COMPLETED以外)の場合の処理 〜 } else { 〜 COMPLETEDの場合の処理 〜 }
ダイアログの継続を指示するのは、下記に示した部分になります。
this.emit(':delegate', updatedIntent); //初期値あり
this.emit(':delegate');
参考情報ですが、この連載ではスキル・サービスをAlexa Skills Kit SDK for Node.jsを使って実装しています。同SDKの詳しい説明は、GitHubのページで参照できます(英文)。
https://github.com/alexa/alexa-skills-kit-sdk-for-nodejs
テストしてみましょう。期待通りの結果になりましたか?
次回はいよいよ、Amazon Echo、Echo DotなどのAlexa対応デバイスを使ったテストに挑戦します。スキル・サービス側のプログラムも充実させていきますので、ご期待ください。
連載バックナンバー
Think ITメルマガ会員登録受付中
全文検索エンジンによるおすすめ記事
- Alexaのスキルを作ってみよう
- Alexa Skills Kit SDK for Node.jsについて知る
- Androidの重要な機能、インテント
- LINE、開発者向けカンファレンスでスマートスピーカーWAVEを実現するAI、Clovaの概要などを解説
- ECMAScript
- 「Ace」を使って「TAURI」で「テキストエディタ」アプリを作ろう
- IBMとAmazonのAIプラットフォーム
- Socket.IOを使ってNode.jsでリアルタイムWebアプリを開発する
- Amazonの今後の展開は? 音声アシスタント『Alexa』がより使いやすくアップデート
- ES2015で導入された、より洗練された構文 Part 1