Amazon AlexaAWS

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です。

ブックマークや限定記事(予定)など

WP Kyotoサポーター募集中

WordPressやフロントエンドアプリのホスティング、Algolia・AWSなどのサービス利用料を支援する「WP Kyotoサポーター」を募集しています。
月額または年額の有料プランを契約すると、ブックマーク機能などのサポーター限定機能がご利用いただけます。

14日間のトライアルも用意しておりますので、「このサイトよく見るな」という方はぜひご検討ください。

広告ここから
広告ここまで

Related Category posts