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

    広告ここから
    広告ここまで
    Home
    Search
    Bookmark