Amazon AlexaAWS

Alexa Skills KitのAMAZON.RepeatIntentをためす

元記事:Alexa Skill Recipe: Using Session Attributes to Enable Repeat Responses 面白そうだったので試してみました。 AMAZON.RepeatInt […]

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

元記事:Alexa Skill Recipe: Using Session Attributes to Enable Repeat Responses

面白そうだったので試してみました。

AMAZON.RepeatIntentとは?

Amazonが提供するビルトインインテントの1つで、最後のアクションを繰り返すようにAlexaへ求めることができるインテントです。ドキュメントによると、日本語では「もう一度言って」や「繰り返して」と話しかけることで利用できます。

インテントを登録する

このインテントはビルトインなので、「アレクサのビルトインライブラリから既存のインテントを使用」で検索して追加することで自分のスキルに追加できます。

Fact Skill(豆知識スキル)で利用する

Fact SkillはAWS Lambdaを新規作成時に利用できる設計図の1つです。alexa-sdkを含むLambdaファンクションをちょっと試したい時などに便利ですので、今回もこれを実験材料にします。日本語での作り方は、公式のドキュメントが参考になります。

そのままで使ってみる

想定する会話の流れは以下のようになります。

ユーザー「アレクサ、豆知識を開いて」
アレクサ「(豆知識について話す)」
ユーザー「もう一度言って」
アレクサ「(先程の内容を繰り返す)」

実装前の素の状態で試すと以下のようになりました。

これはデフォルトではレスポンスを返した段階でセッションが終了するようになっているからです。以下がLambdaからのレスポンスですが、body.response.shouldEndSessiontrueになっている場合はここでスキルが終了してしまいます。

{
	"body": {
		"version": "1.0",
		"response": {
			"outputSpeech": {
				"type": "SSML",
				"ssml": "<speak> Here's your fact: On Mars, the Sun appears about half the size as it does on Earth. </speak>"
			},
			"card": {
				"type": "Simple",
				"title": "Space Facts",
				"content": "On Mars, the Sun appears about half the size as it does on Earth."
			},
			"shouldEndSession": true
		},
		"sessionAttributes": {},
		"userAgent": "ask-nodejs/1.0.25 Node/v6.10.3"
	}
}

ということで、Lambdaのソースコードを変更して、もう一度繰り返してもらえるようにしていきましょう。

LambdaをAMAZON.RepeatIntentに対応させる

ここからはLambdaのソースコードを変更します。

1: セッションを継続させる

まずは豆知識をアレクサが話した後にセッションが継続している状態にする必要があります。以下は豆知識を話すための処理部分をLambdaからとってきたものです。

    'GetNewFactIntent': function() {
        var factArr = data;
        var factIndex = Math.floor(Math.random() * factArr.length);
        var randomFact = factArr[factIndex];
        var speechOutput = GET_FACT_MESSAGE + randomFact;
        this.emit(':tellWithCard', speechOutput, SKILL_NAME, randomFact)
    },

:tellWithCardshouldEndSessiontrueで返しますので、falseで返す:askWithCardに変更しましょう。また、askの場合は一定時間ユーザーが返事をしなかった場合にもう一度だけ話しかけることができますので、その際の発話内容も追加する必要があります。

this.emit(':askWithCard', speechOutput, repromptSpeech, cardTitle, cardContent, imageObj);

// via: https://github.com/alexa/alexa-skills-kit-sdk-for-nodejs/blob/master/Readme.jp.md#%E3%83%AC%E3%82%B9%E3%83%9D%E3%83%B3%E3%82%B9-vs-responsebuilder

ということで以下のように変更しましょう。varconstに変わっているのはそういうものだと思ってください。

 'GetNewFactIntent': function() {
        const factArr = data;
        const factIndex = Math.floor(Math.random() * factArr.length);
        const randomFact = factArr[factIndex];
        const speechOutput = GET_FACT_MESSAGE + randomFact + '他に聞きたいことはありますか?';
        const reprompt = 'もう一度聞きたい場合は、「もう一度言って」と話しかけてください。終了する場合は、「ストップ」と言ってください。'
        this.emit(':askWithCard', speechOutput, reprompt, SKILL_NAME, randomFact)
    },

これでレスポンスが以下のように変わりました。body.response.repromptが追加され、body.response.shouldEndSessionfalseに変わっています。

{
	"body": {
		"version": "1.0",
		"response": {
			"outputSpeech": {
				"type": "SSML",
				"ssml": "<speak> 知ってましたか?金星は水星と比べて太陽より遠くにありますが、気温は水星よりも高いです。他に聞きたいことはありますか? </speak>"
			},
			"card": {
				"type": "Simple",
				"title": "豆知識",
				"content": "金星は水星と比べて太陽より遠くにありますが、気温は水星よりも高いです。"
			},
			"reprompt": {
				"outputSpeech": {
					"type": "SSML",
					"ssml": "<speak> もう一度聞きたい場合は、「もう一度言って」と話しかけてください。終了する場合は、「ストップ」と言ってください。 </speak>"
				}
			},
			"shouldEndSession": false
		},
		"sessionAttributes": {},
		"userAgent": "ask-nodejs/1.0.25 Node/v6.10.3"
	}
}

ビルドツールでのテストでも会話が継続していることがわかります。

2: AMAZON.RepeatIntentに対応させる

それではいよいよ繰り返しに対応させましょう。まずはGetNewFactIntentで取得した豆知識の内容をattributesに保存して再利用できるようにします。

    'GetNewFactIntent': function() {
        const factArr = data;
        const factIndex = Math.floor(Math.random() * factArr.length);
        const randomFact = factArr[factIndex];
         this.attributes.lastSpeech = randomFact;
        const speechOutput = GET_FACT_MESSAGE + randomFact + '他に聞きたいことはありますか?';
        const reprompt = 'もう一度聞きたい場合は、「もう一度言って」と話しかけてください。終了する場合は、「ストップ」と言ってください。'
        this.emit(':askWithCard', speechOutput, reprompt, SKILL_NAME, randomFact)
    }

続いて、AMAZON.RepeatIntentでのリクエストを処理するコードを追加します。


    'AMAZON.RepeatIntent': function () { 
        const reprompt = 'もう一度聞きたい場合は、「もう一度言って」と話しかけてください。終了する場合は、「ストップ」と言ってください。'
        this.response.speak(this.attributes.lastSpeech + " 他に聞きたいことはありますか?").listen(reprompt); 
        this.emit(':responseReady'); 
    },

これでAMAZON.RepeatIntentがリクエストされた場合、その前のGetNewFactIntentでattributesに追加された内容を繰り返すようになります。

ちなみにthis.attributesの値は、Lambdaの中ではevent.session.attributesの中にオブジェクト形式で送信されてきます。

{
	"version": "1.0",
	"session": {
		"new": false,
		"sessionId": "amzn1.echo-api.session.XXXXX",
		"application": {
			"applicationId": "amzn1.ask.skill.XXXXX"
		},
		"attributes": {
			"lastSpeech": "太陽の質量は全太陽系の質量の99.86%を占めます。"
		},
		"user": {
			"userId": "amzn1.ask.account.XXXXX"
		}
	},
	"request": {
		"type": "IntentRequest",
		"requestId": "amzn1.echo-api.request.xxxxx",
		"timestamp": "2018-04-07T06:57:05Z",
		"locale": "ja-JP",
		"intent": {
			"name": "AMAZON.RepeatIntent",
			"confirmationStatus": "NONE"
		}
	},
...

Lambdaのテストを書かれる場合の参考になればです。

会話をより続けやすくする

最後に「他に聞きたいことはありますか?」という返答を処理できるようにしておきましょう。「はい」か「いいえ」の返答が想定されますので、AMAZON.YesIntentAMAZON.NoIntentの2つを追加しておきます。

    'AMAZON.YesIntent': function () { 
        this.emit("GetNewFactIntent"); 
    }, 
    'AMAZON.NoIntent': function () { 
        this.response.speak(STOP_MESSAGE); 
        this.emit(':responseReady'); 
    } 

これで繰り返したい場合も他の豆知識が聞きたい場合も両方サポートできるようになりました。

終わりに

予約システムやスケジュールの照会などを行うスキルを作る場合、AMAZON.RepeatIntentをサポートするとユーザーにとってより使いやすいスキルになるでしょう。

日本ではまだ使えない便利なビルトインインテントなどもありますので、またそちらもトライしてみます。

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

WP Kyotoサポーター募集中

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

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

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

Related Category posts