alexa-sdkで簡単なセッション管理を用いたAlexaの会話スキルを作る
音声アプリを作れるようになったらやりたくなるのは「会話」ですよね。 とはいえいままで紹介したやり方だけでは、一問一答レベルのやりとりしかAlexaとやりとりすることができません。 ということで今回は簡単なセッション管理機 […]
目次
音声アプリを作れるようになったらやりたくなるのは「会話」ですよね。
とはいえいままで紹介したやり方だけでは、一問一答レベルのやりとりしかAlexaとやりとりすることができません。
ということで今回は簡単なセッション管理機構を用意して、数往復できる会話を作る方法を紹介します。
NewSession
でセッションを開始する
これまではLaunchRequest
インテントから作り始めていましたが、セッションを利用する場合はNewSession
を使います。
この中でthis.handler.state
に現在の状態(state)を追加し、this.emit(':ask')
で質問をさせることで会話を開始することができます。
'NewSession': function () {
this.handler.state = '_STARTMODE'
this.emit(':ask', 'Welcome to simple quiz game. Would you like to play?',
'Say yes to start the game or no to quit.')
}
state別にhandlerを登録する
alexa-sdkで登録するhandlerはthis.handler.state
別にdispatchされる仕様です。
そのため、this.handler.state
を使用する場合はそのstateの数だけhandlerを作成して登録する必要があります。
stateに対応したhandlerを作る
stateに応じてdispatchするhandlerはCreateStateHandler
を用いて作成します。
const Alexa = require('alexa-sdk')
const handler1 = Alexa.CreateStateHandler('_STARTMODE', {
'NewSession': function () {
this.handler.state = ''
this.emitWithState('NewSession') // Equivalent to the Start Mode NewSession handler
},
'AMAZON.HelpIntent': function () {
this.emit(':ask', 'This is a sample skill using session state', 'Would you like to play ?')
},
'AMAZON.NoIntent': function () {
this.emit(':tell', 'Ok, see you next time!')
}
})
各handlerでもNewSession
は用意する必要がある様子で、この場合はthis.emitWithState('NewSession')
としてはじめに登録したIntentの処理を実行させるようにします。
また、AMAZON.NoIntent
のみがthis.emit(':tell')
を使用しているのもポイントです。
:tell
を使用すると、Alexaがユーザーの返答を待たずに会話を終了させます。
そのため会話として続けたいやり取りでは:ask
を使い、そうでない場合は:tell
を使うようにしましょう。
handlerを登録する
あとは先ほど作成したhandlerと、通常のhandlerをそれぞれ登録させます。
const Alexa = require('alexa-sdk')
exports.handler = function (event, context, callback) {
var alexa = Alexa.handler(event, context, callback)
alexa.registerHandlers(handler, handler1)
alexa.execute()
}
stateの数を増やした場合は、この作業を繰り返して登録していきましょう。
const Alexa = require('alexa-sdk')
exports.handler = function (event, context, callback) {
var alexa = Alexa.handler(event, context, callback)
alexa.registerHandlers(handler, handler1, handler2, handler3, ...)
alexa.execute()
}
ここまでのコードをalexa-conversationでテストする
ここまでの実装を使って、3往復ほど会話するサンプルをテストしてみましょう。
会話の流れは以下のようになります。
- [User]スキルを起動する
- [Alexa]クイズゲームをやりますか?と質問する
- [User]ヘルプを起動する
- [Alexa]スキルの紹介をして、ゲームを開始するか質問する
- [User]やらないと回答する
- [Alexa]Thanks Messageをだして終了する
alexa-conversationでテストにするとこうです。
const conversation = require('alexa-conversation')
const app = require('./index.js')
const opts = {
appId: 'your-app-id',
app: app,
handler: app.handler
}
opts.name = 'Use help and exit'
conversation(opts)
.userSays('LaunchRequest')
.plainResponse
.shouldContain('Welcome to simple quiz game. Would you like to play?')
.userSays('AMAZON.HelpIntent')
.plainResponse
.shouldContain('This is a sample skill using session state')
.userSays('AMAZON.NoIntent')
.plainResponse
.shouldContain('Ok, see you next time!')
.end()
そして実装コードがこちらです。
const Alexa = require('alexa-sdk')
const handler = {
'NewSession': function () {
this.handler.state = '_STARTMODE'
this.emit(':ask', 'Welcome to simple quiz game. Would you like to play?',
'Say yes to start the game or no to quit.')
}
}
const handler1 = Alexa.CreateStateHandler('_STARTMODE', {
'NewSession': function () {
this.handler.state = ''
this.emitWithState('NewSession') // Equivalent to the Start Mode NewSession handler
},
'AMAZON.HelpIntent': function () {
this.emit(':ask', 'This is a sample skill using session state', 'Would you like to play ?')
},
'AMAZON.NoIntent': function () {
this.emit(':tell', 'Ok, see you next time!')
}
})
exports.handler = function (event, context, callback) {
var alexa = Alexa.handler(event, context, callback)
alexa.registerHandlers(handler, handler1)
alexa.execute()
}
テスト実行結果がこうなります。
$ ./node_modules/mocha/bin/_mocha test.js
Executing conversation: Use help and exit
✓ Finished executing conversation
Conversation: Use help and exit
User triggers: LaunchRequest
✓ Alexa's plain text response should contain: Welcome to simple quiz game. Would you like to play?
User triggers: AMAZON.HelpIntent
✓ Alexa's plain text response should contain: This is a sample skill using session state
User triggers: AMAZON.NoIntent
✓ Alexa's plain text response should contain: Ok, see you next time!
4 passing (15ms)
おわりに
このほかにも会話の中でデータを引き継ぐ方法などもありますが、それはまた後ほど別記事にて紹介します。
なお、今回参考にしたサンプルスキルは、Alexa High Low Game Skillです。