Amazon Alexaask-sdkask-utils

AlexaのAMAZON.RepeatIntentをシンプルに実装する方法

Alexaスキルは、「もう一度言って」のように話しかけた際に先ほど話した内容を復唱できるように作れます。この際、AMAZON.RepeatIntentというインテントを利用すると、よくある復唱をお願いする言い回しをビルト […]

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

Alexaスキルは、「もう一度言って」のように話しかけた際に先ほど話した内容を復唱できるように作れます。この際、AMAZON.RepeatIntentというインテントを利用すると、よくある復唱をお願いする言い回しをビルトインのモデルでハンドルできるようになります。

で、このインテントの実装で問題なのが「前のレスポンスを復元する」という実装です。

いろいろ試してみたのですが、おそらく一番シンプルな方法はこれかなと思ったので紹介します。

ResponseInterceptorでレスポンスをまるごとキャプチャする

これまではインテント別にコンテンツをsessionAttributesに保存して、RepeatIntentが来たらもう一度そのハンドラーのhandleメソッドを実行したりしていました。が、これでは実装したインテントでしかリピートができません。

一方でResponseInterceptorを使えば、すべてのレスポンスをキャプチャすることができます。

import { ResponseInterceptor } from 'ask-sdk-core'
import {
    updateSessionAttributes,
} from 'ask-utils'

const RecordTheResponseInterceptor:ResponseInterceptor  = {
    process(handlerInput, response) {
        // No response text
        if (!response) return
        // Session should be closed
        if (response.shouldEndSession === true) return
        // Skill will be closed
        if (!response.reprompt) return
        updateSessionAttributes(handlerInput, {
            lastResponse: response
        })
    }
}

このようにすると、会話が継続する状態=AMAZON.RepeatIntentが呼ばれる可能性がある状態の時のみレスポンスのオブジェクトをまるごとキャプチャできます。

今回はsessionAttributesに保存していますが、セッションが切れた状態から復元したいという場合は、persistantAttributesの方に保存すればよいでしょう。

RepeatIntentHandlerを実装する

あとはハンドラーを作成して、先ほどのレスポンスを復元するだけです。

import { RequestHandler } from 'ask-sdk-core';
import { Response } from 'ask-sdk-model'
import {
    getSessionAttribute,
    isMatchedIntent
} from 'ask-utils'

const RepeatIntentHandler: RequestHandler = {
    canHandle(handlerInput) {
        return isMatchedIntent(handlerInput, 'AMAZON.RepeatIntent')
    },
    handle(handlerInput) {
        const lastResponse = getSessionAttribute(handlerInput, 'lastResponse') as Response | null
        if (!lastResponse) throw new Error('No repeat content')
        return lastResponse
    }
}

これなら余計なステート更新が発生したり、ランダムなコンテンツが入れ替わってしまったりすることもありません。

万が一リピートしてほしくない内容がある場合は、キャプチャする側で除外するか、RepeatIntentHandler側でthrow new Errorしてやればよいでしょう。

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

WP Kyotoサポーター募集中

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

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

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

Related Category posts