[Alexaスキル] AudioPlayerスキルのセッションとイベント
渡辺です。
AudioPlayerでハローワールドでは、AudioPlayerスキルの概要を解説しました。 今回は、実用レベルのスキルを作るために必要なポイントを解説します。
セッションとAudioPlayerスキル
一般的なカスタムスキルでは、スキルの起動後、ユーザの発話でリクエストが発生しインテント関数が呼び出されます。 インテント関数では、応答メッセージを返し、ユーザの応答に対し次のインテント関数が呼び出される流れです。 この時、一連のリクエストではセッションが確立され、セッション情報を利用できます。
インテント関数でイベントを確認すると次のように、セッション情報が格納されています。
{ "version": "1.0", "session": { "new": true, "sessionId": "amzn1.echo-api.session.xxxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", "user": { "userId": "amzn1.ask.account.xxxx" } }, "request": { "type": "LaunchRequest" } }
session.new
が true
となっていることで、セッションの初回リクエストと判断できます。
2回目のリクエストは、次のようにセッションが維持されています。
{ "version": "1.0", "session": { "new": false, "sessionId": "amzn1.echo-api.session.xxxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", "attributes": { "repeatSpeech": "タイマースキルへようこそ。" }, "user": { "userId": "amzn1.ask.account.xxxx" } }, "request": { "type": "IntentRequest" } }
セッションが維持され、セッション情報(attributes)が保持されていることが確認出来ます。
ところが、AudioPlayerスキルではセッションが維持されません。 ステートレスを前提とした設計を行う必要があります。
AudioPlayerイベントのセッション
音楽再生時に呼び出されるPlaybackStartedイベントなど、AudioPlayerスキルでは多くのイベントが発生します。 この時、すべて新しいセッションとして呼び出されます。 セッション情報(attributes)は利用できません。
{ "version": "1.0", "session": { "new": true, "sessionId": "amzn1.echo-api.session.xxxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" }, "context": { "AudioPlayer": { "offsetInMilliseconds": 0, "token": "https://s3-ap-northeast-1.amazonaws.com/xxxxxx/xxx.m4a", "playerActivity": "STOPPED" } }, "request": { "type": "AudioPlayer.PlaybackStarted", "locale": "ja-JP", "token": "https://s3-ap-northeast-1.amazonaws.com/xxxxxx/xxx.m4a", "offsetInMilliseconds": 0 } }
セッションは維持されず、session.new がtrueになっており、attributeはありません。 ただし、context.AudioPlayer から、再生された音楽ファイルのパスや再生位置などは取得可能です。
インテントでも同様です。 一時停止を行った場合に、呼び出されるPauseIntentでは、次のようなリクエストが行われます。
{ "version": "1.0", "session": { "new": true, "sessionId": "amzn1.echo-api.session.xxxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" }, "context": { "AudioPlayer": { "offsetInMilliseconds": 40075, "token": "https://s3-ap-northeast-1.amazonaws.com/xxxxxx/xxx.m4a", "playerActivity": "STOPPED" } }, "request": { "type": "IntentRequest", "intent": { "name": "AMAZON.PauseIntent" } } }
AudioPlayerスキルで永続化情報を扱う
AudioPlayerで音楽が再生されると、セッションは維持されません。 セッション情報が利用できないため、情報は外部データベースに保存する必要があります。
AlexaのSDKを利用するならば、DyanmoDBにセッション情報を保存できるため、DynamoDBを有効にしてください。 DynamoDBを有効にすれば、同一ユーザのセッション情報は永続化されるため、イベント時にも利用できます。
exports.handler = function (event, context, callback) { const alexa = Alexa.handler(event, context, callback); // DynamoDBの有効化 alexa.dynamoDBTableName = 'your-dynamodb-table'; // 中略 alexa.execute(); };
例えば、スロットに含まれるタイマー時間をセッションに保存し、DynamoDBに保存します。
'StartTimerIntent': function () { var num = this.event.request.intent.slots.Num.value; // セッションに保存(DynamoDBに自動保存) this.attributes['timer'] = num; // 省略 },
再生の再開を実装する
前回の実装では、再生の再開時に曲の最初から再生を行っていました。
context.AudioPlayer
のパラメータを使用すれば、中断したところから再生可能です。
'AMAZON.PauseIntent': function () { this.response.audioPlayerStop(); this.emit(':responseReady'); }, 'AMAZON.ResumeIntent': function () { var offset = this.event.context.AudioPlayer.offsetInMilliseconds; var url = this.event.context.AudioPlayer.token; this.response.audioPlayerPlay('REPLACE_ALL', url, url, null, offset); this.emit(':responseReady'); }
再生終了時のハンドリング
AudioPlayerで音楽を再生した時、再生終了時にPlaybackFinishedイベントが発生します。 しかし、PlaybackFinishedイベントにレスポンスを返し、Alexaに発話させるようなアクションは行えません。
PlaybackFinishedイベントは、他のイベントと同様に、AudioPlayerが特定のタイミングで発生させるリクエストです。 イベントを受けてLambdaで処理は行えますが、メッセージをレスポンスに含めることができません。 Alexaでは、ユーザの発話に対するレスポンスとして応答メッセージを返すことしかできないのです。
それでは、再生終了時にどのようなステータスとなるのでしょうか?
答えは、スキルを起動していないデフォルト状態です。 ただし、Alexaは最後に起動したスキルを記憶しています。
再生終了後、利用者がAlexaに話しかけた場合、発話内容を解釈し、いずれかのアクションを取ります。
- Alexaの組み込み機能による応答
- 直前に起動していたAudioPlayerスキルによる応答
発話内容が、AudioPlayerスキルのインテントでマッチした場合、スキルのインテント関数が呼び出されます。
例えば、音楽再生完了後、「Alexa, 繰り返して」と発話するならば、スキルのAMAZON.RepeatIntent
が呼び出されるでしょう。
この時も、セッションは維持されず、新しいセッションとして処理されることは注意してください。
音楽再生終了後、「Alexa, XXを開いて」と発話するならば、XXスキルが起動します。
まとめ
AudioPlayerスキルで音楽を再生した時に発生するイベントは、セッション情報を持たないステートレスリクエストです。 セッション情報を扱いたい場合はDynamoDB機能を有効にしてください。 ただし、再生した音楽のURLや中断位置などはコンテキスト情報として取得可能です。
また、音楽再生終了時にスキルからアクション(応答)を行うことはできません。 利用者から発話がある場合、スキルのインテント関数で処理が行われるため、再生終了時のフローを整理すると良いでしょう。