スロットを使って任意の入力を受け付けよう

Alexaとの複数回に渡るやりとり(ダイアログ)
ダイアログとは
Alexa Skills Kitにおけるダイアログとは、ユーザーによる一度の発話では収集しきれない情報を、何度かのやりとりを通じて得る方法です。このやりとりの間、収集途中の情報などを覚えておく、いわゆる状態管理を行う必要がありますが、これはスキル・インターフェース側でやってくれます。したがって、AWS Lambdaを使ったプログラム・コードでは、パラメーターとして渡されてくる情報に基づいて処理をすればよく、簡単に期待する動作結果を得られます。スキル・インターフェースとスキル・サービスの間の、ダイアログに関する動作の流れは次のようになっています。
一連の会話である「ダイアログ」が開始すると、「STARTED」というダイアログの状態コードがスキル・サービスに渡されます。このとき、スキル・サービスは、ダイアログの続きをスキル・インターフェースに委ねるために「Delegate」という返答をするとともに、スロットの既定の値をスキル・インターフェースに返すことができます。ダイアログの途中、まだ情報収集が完了していない間は「IN_PROGRESS」という状態コードが渡されます。このとき、スキル・サービスは単に「Delegate」と返答するだけで構いません。
ダイアログが完了すると「COMPLETED」という状態コードが渡されるため、スキル・サービスはスロットの値がそろっていることを期待して、処理を進めることができます。
ダイアログを追加する
開発者コンソールを開き、スキル編集画面の左メニューから「eventName」のスロット名をクリックすると、eventNameスロットの詳細を設定するページが開きます。イベント名を必須項目とするため、「このインテントを完了させるために、このスロットは必須ですか?」を選択します。
「Alexaの音声プロンプト」の欄には以下の内容を入力して[Enter]を押します。
どのイベントについて調べますか
イベント名を伝えずに来場者数を尋ねた場合に、Alexaはここに入力した言葉を使ってイベント名を聞き返します。
「ユーザーの発話」欄には、以下のように入力して[Enter]を押します。
{eventName}です
{eventCity}で開催の{eventName}です
こちらは、上記の音声プロンプトに対するユーザーの返答例となります。設定が完了したら保存とビルドを忘れずに行いましょう。
スキル・サービスをダイアログに対応させる
さっそくコード例を示します。
リスト3:コード例2:code2-2/index.js
'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」を処理するハンドラーの中では、以下のようにダイアログの状態別に処理をしています。
リスト4:ダイアログの状態別の処理
if (this.event.request.dialogState === 'STARTED') {
〜 STARTEDの場合の処理 〜
} else if (this.event.request.dialogState !== 'COMPLETED') {
〜 途中(COMPLETED以外)の場合の処理 〜
} else {
〜 COMPLETEDの場合の処理 〜
}
ダイアログの継続を指示するのは、下記に示した部分になります。
リスト5:ダイアログの継続指示
this.emit(':delegate', updatedIntent); //初期値あり
リスト6:別のダイアログの継続指示
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




