Skill Connectionsを使用したタスクのリクエスト
Alexaスキルは、Skill Connectionsを使って、Amazonまたはプロバイダースキルのタスクをリクエストできます。たとえば、レシピスキルは、印刷スキルにレシピを印刷するようリクエストできます。スキルをリクエスタースキルにする前に、プロバイダースキルに実行させたいタスクを決めて、Amazon定義済みタスクとプロバイダースキルが提供するカスタムタスクのどちらを使うかを決定します。Skill Connectionsの概要については、Skill Connectionsとはを参照してください。
プロバイダースキルのタスクをリクエストする
リクエスタースキルは、プロバイダースキルのタスクをリクエストします。可能であれば、プロバイダースキルはリクエスタースキルのリクエストを実行します。
プロバイダーに制御を渡すには、スキルがConnections.StartConnection
ディレクティブを送信します。ユーザー検証後にスキルに制御を戻すには、AlexaがスキルにSessionResumedRequest
を送信します。既存のスキルをリクエスタースキルに変更し、プロバイダースキルにタスクをリクエストできるようにします。
プロバイダースキルのタスクをリクエストする場合、リクエスタースキルは、タスク実行後に制御を戻すかどうかを指定できます。その場合、onCompletion
フィールドを次のように設定します。
RESUME_SESSION
を指定すると、制御がリクエスタースキルに戻り、ユーザーは元のリクエスタースキルセッションの同じ場所に戻ります。SEND_ERRORS_ONLY
を指定すると、エラーの場合には通知しますが、制御は戻りません。- デフォルト設定は、
RESUME_SESSION
です。
スキルをSkill Connectionsタスクのリクエスターにする
Connections.StartConnection
ディレクティブを返すハンドラーを実装します。重要: リクエストにTasks.CompleteTask
ディレクティブまたはConnections.StartConnection
ディレクティブで応答する場合、応答にオーディオまたはビデオのプレイヤーディレクティブを含めることはできません。- リクエスタースキルの
Connections.StartConnection
ディレクティブで指定したonCompletion
値に応じて、次のいずれかを実装します。- リクエスタースキルが
RESUME_SESSION
を指定した場合、SessionResumedRequest
リクエストからの応答を受信するハンドラーを実装します。プロバイダースキルがタスクを完了すると、このハンドラーはプロバイダースキルからリクエスタースキルに制御を戻せるようにします。 - リクエスタースキルが
SEND_ERRORS_ONLY
を指定した場合、System.ExceptionEncountered
リクエストからの応答を受信するハンドラーを実装します。プロバイダースキルがタスクを完了できない場合、このハンドラーはAlexaからリクエスタースキルにエラー通知を返せるようにします。
- リクエスタースキルが
遷移プロンプト
リクエスタースキルからプロバイダースキルへの遷移中、Alexaは常にリクエストの転送を示すプロンプトを出します。これは、リクエスタースキルがConnections.StartConnection
ディレクティブにRESUME_SESSION
、SEND_ERRORS_ONLY
のどちらを指定した場合でも同じです。このプロンプトはカスタマイズできません。
- わかりました。{requester_skill_name}は{provider_skill_name}スキルを使ってリクエストを実行します。{provider_skill_name}にリクエストを送信していいですか?
リクエスタースキルがSEND_ERRORS_ONLY
を指定した場合、Alexaは制御を返すプロンプトを出しません。リクエスタースキルがRESUME_SESSION
を指定した場合、プロバイダースキルからリクエスタースキルに制御を戻す間、Alexaは常に制御を戻すプロンプトを出します。このプロンプトはカスタマイズできません。
- {requester_skill_name}に戻ります。
Connections.StartConnection
ディレクティブを返すハンドラーを実装してSkill Connectionsを使用する
応答オブジェクトにConnections.StartConnection
ディレクティブをセットすることで、リクエスタースキルはSkill Connectionsリクエストを送信できます。以下の例を参照してください。
Tasks.CompleteTask
ディレクティブまたはConnections.StartConnection
ディレクティブで応答する場合、応答にオーディオまたはビデオのプレイヤーディレクティブを含めることはできません。明示的またはデフォルトでRESUME_SESSION
を指定したConnections.StartConnection
ディレクティブを返す
onCompletion
フィールドにRESUME_SESSION
をセットした場合、Connections.StartConnection
ディレクティブを返す際にサービスコードのshouldEndSession
フラグを未定義のままにする必要があります。
onCompletion
フィールドに値をセットしない場合も、shouldEndSession
フラグを未定義のままにする必要があります。Managed Skill Connectionsの場合
Managed Skill Connectionsでは、Amazon定義済みタスクのみがサポートされます。以下の例では、task_name
は常にAMAZON.{name}
の形式にする必要があります。例:AMAZON.PrintPDF
return handlerInput.responseBuilder
.addDirective({
'type': 'Connections.StartConnection',
'uri': 'connection://{task_name}/{version_number}',
'input': {
...
},
'onCompletion': 'RESUME_SESSION',
'token': '...'
})
.getResponse();
onCompletion
フィールドは必須ではなく、RESUME_SESSION
はデフォルト値のため、以下の例の実行結果は前の例と同じになります。
return handlerInput.responseBuilder
.addDirective({
'type': 'Connections.StartConnection',
'uri': 'connection://{task_name}/{version_number}',
'input': {
...
},
'token': '...'
})
.getResponse();
Direct Skill Connectionsの場合
Direct Skill Connectionsでは、Amazon定義済みタスクとカスタムタスクの両方がサポートされます。以下の例では、task_name
の形式は2通りあります。
- Amazonの定義済みタスクの場合、形式は
AMAZON.{name}
(AMAZON.PrintPDF
など)になります。 - カスタムタスクの場合、形式は
{provider_skill_id}.{name}
(amzn1.ask.skill.12345678-90ab-cdef-1234-567890abcdef.CountDown
など)になります。
return handlerInput.responseBuilder
.addDirective({
'type': 'Connections.StartConnection',
'uri': 'connection://{task_name}/{version_number}?provider={provider_skill_id}',
'input': {
...
},
'onCompletion': 'RESUME_SESSION',
'token': '...'
})
.getResponse();
SEND_ERRORS_ONLY
を指定したConnections.StartConnection
ディレクティブを返す
onCompletion
フィールドにSEND_ERRORS_ONLY
を指定する場合、サービスコードのshouldEndSession
フラグをtrue
にセットする必要があります。
Managed Skill Connectionsの場合
Managed Skill Connectionsでは、Amazon定義済みタスクのみがサポートされます。以下の例では、task_name
は常にAMAZON.{name}
の形式にする必要があります。例:AMAZON.PrintPDF
return handlerInput.responseBuilder
.addDirective({
'type': 'Connections.StartConnection',
'uri': 'connection://{task_name}/{version_number}',
'input': {
...
},
'onCompletion': 'SEND_ERRORS_ONLY'
})
.withShouldEndSession(true)
.getResponse();
Direct Skill Connectionsの場合
Direct Skill Connectionsでは、Amazon定義済みタスクとカスタムタスクの両方がサポートされます。以下の例では、task_name
の形式は2通りあります。
- Amazonの定義済みタスクの場合、形式は
AMAZON.{name}
(AMAZON.PrintPDF
など)になります。 - カスタムタスクの場合、形式は
{provider_skill_id}.{name}
(amzn1.ask.skill.12345678-90ab-cdef-1234-567890abcdef.CountDown
など)になります。
return handlerInput.responseBuilder
.addDirective({
'type': 'Connections.StartConnection',
'uri': 'connection://{task_name}/{version_number}?provider={provider_skill_id}',
'input': {
...
},
'onCompletion': 'SEND_ERRORS_ONLY'
})
.withShouldEndSession(true)
.getResponse();
応答のアトリビュート
アトリビュート | 説明 |
---|---|
type | 必須です。ディレクティブの種類を指定します。この場合はConnections.StartConnection です。
|
uri | 必須です。タスクとタスクのバージョンを定義するリソースです。 |
input | 任意です。送信するタスクリクエストのリクエストオブジェクトを含みます。 |
token | 任意です。トークンは、そのままスキルのSessionResumedRequest に返されます。タスクリクエストの完了後、このトークンを使用して、リクエスタースキルを再開できます。
|
onCompletion | 任意です。タスクの完了後にリクエスタースキルを再開するかどうかを定義する列挙フィールドです。RESUME_SESSION またはSEND_ERRORS_ONLY を指定できます。RESUME_SESSION の場合、タスクが完了するとリクエスタースキルはSessionResumedRequest を受け取ります。SEND_ERRORS_ONLY の場合、エラーが発生した場合のみ、リクエスタースキルはSystem.ExceptionEncountered を受け取ります。デフォルト値は RESUME_SESSION です。
|
Skill Connectionsリクエストから応答を受け取るハンドラーを実装する
onCompletion
アトリビュートにSEND_ERRORS_ONLY
を指定しない場合でも、リクエスタースキルは元のタスクリクエストのSkill Connections応答を受け取るハンドラーを実装する必要があります。応答ハンドラーを実装しない場合、スキルに処理されない例外が発生し、リクエスタースキルにはプロバイダースキルから制御が戻されなくなります。
タスクリクエストに対するSkill Connectionsの応答を受け取るハンドラーを実装するには
- 次の例に示すように、
SessionResumedRequest
ハンドラーをスキルに追加します。リクエスタースキルがSessionResumedRequest
を受け取ると、Connections.StartConnection
ディレクティブが返されたときに、スキルの以前のセッションに戻ります。
例:応答ハンドラーを実装する
次の例は、Skill Connectionsリクエストの応答を受け取るハンドラーを実装する方法を示しています。
const SessionResumedRequestHandler = {
canHandle(handlerInput) {
const request = handlerInput.requestEnvelope.request;
return request.type === 'SessionResumedRequest';
},
handle(handlerInput) {
const status = handlerInput.requestEnvelope.request.cause.status;
const code = status.code;
const message = status.message;
console.log(`SessionResumedRequestがステータスコード${code}とメッセージ「${message}」を受け取りました`);
// 現在のsessionIdは、元のConnections.StartConnectionディレクティブが返されたときの前回のIntentRequestと同じです。
const currentSessionId = handlerInput.requestEnvelope.session.sessionId;
// リクエスタースキルのエクスペリエンスが継続します。この例では、音声をレンダリングします。
return handlerInput.responseBuilder
.speak("リクエスタースキルがSessionResumedRequestを受け取りました")
.getResponse();
}
};
例: SessionResumedRequest
リクエストのJSONスキーマ
onCompletion
にRESUME_SESSION
をセットすると、リクエスターはSessionResumedRequest
オブジェクトを受け取ります。リクエストのresult
はタスク定義で定義されます。
result
オブジェクトの例です。ただし、このオブジェクトの具体的な内容はリクエストを処理するスキルによって異なります。result
は、選択されたプロバイダースキルが返すキーと値のペアを含むJSONオブジェクトと想定されます。{
"type": "SessionResumedRequest",
"requestId": "string",
"timestamp": "string",
"locale": "string",
"cause": {
"type": "ConnectionCompleted",
"token": "...",
"status": {
"code": "200",
"message": "OK"
},
"result": {
"key1": "value1",
"key2": "value2"
}
}
}
SessionResumedRequest
のステータスコードアトリビュート
Managed Skill Connectionsの場合
Alexaは、タスクリクエスト呼び出しで以下のステータスコードをどれでも返すことができます。
タスクリクエストを実行しているプロバイダースキルは、任意の有効なHTTPコードを返すことができます。
status
: リクエストのステータスです。code
:ステータスコードです。200
: リクエストは正常に実行されました。204
: ユーザーがSkill Connectionsの使用を拒否しました。227
: プロバイダーがアカウントリンクされていません。400
: 不正なリクエスト - リクエストは無効です。403
: リクエスターはプロバイダーを呼び出すことができません。404
: 現在利用可能なプロバイダーがありません。500
: サーバーエラーです。
message
: リクエストの結果を表すテキスト文字列のメッセージです。たとえば、「配車予約が正常に完了しました」などのようになります。
Direct Skill Connectionsの場合
リクエスタースキルは、以下のステータスコードのみを返します。タスクリクエストを実行しているプロバイダースキルは、以下のHTTPコードのいずれかのみを返すことができます。
status
: リクエストのステータスです。code
:ステータスコードです。200
: リクエストは正常に実行されました。400
: 不正なリクエスト - リクエストは無効です。403
: リクエスターはプロバイダーを呼び出すことができません。404
: 現在利用可能なプロバイダーがありません。500
: サーバーエラーです。
message
: リクエストの結果を表すテキスト文字列のメッセージです。たとえば、「配車予約が正常に完了しました」などのようになります。
詳細については、Alexaから送信されたリクエストを処理するを参照してください。
System.ExceptionEncountered
を処理するハンドラーを実装する
リクエスタースキルがonCompletion
にSEND_ERRORS_ONLY
を指定し、リクエストされたタスクが完了しなかったときに通知を受け取る場合は、リクエスタースキルにSystem.ExceptionEncountered
リクエストを処理するハンドラーを実装する必要があります。System.ExceptionEncountered
リクエストは、次の例のようになります。
{
"type": "System.ExceptionEncountered",
"requestId": "unique.id.for.the.request",
"timestamp": "次の形式のリクエストのタイムスタンプ: 2018-04-11T15:15:25Z",
"locale": "en-USなどのロケールコード",
"error": {
"type": "INVALID_RESPONSEなどのエラーコード",
"message": "発生したエラーの説明"
},
"cause": {
"requestId": "エラーの原因となったリクエストの一意のID"
}
}
以下は、System.ExceptionEncountered
を処理するコードの例です。注: このリクエストは通知専用です。すべての応答は無視されます。
const SystemExceptionEncounteredHandler = {
canHandle(handlerInput) {
const request = handlerInput.requestEnvelope.request;
return request.type === 'System.ExceptionEncountered';
},
handle(handlerInput) {
console.dir(handlerInput.requestEnvelope.request);
return handlerInput.responseBuilder
.getResponse();
},
};
System.ExceptionEncountered
リクエストのエラータイプ
Managed Skill Connections、Direct Skill Connectionsのいずれの場合も、リクエスタースキルがSystem.ExceptionEncountered
リクエストで受け取るエラーは以下のタイプのみです。
error
: エラー情報を持つオブジェクトが含まれています。type
: 特定のタイプのエラーを識別します。INVALID_RESPONSE
: リクエスタースキルからの接続開始の応答は無効です。INTERNAL_ERROR
: 内部サービスエラーが発生しました。
message
: デバイスが検出したエラーの説明です。例:「配車予約リクエストが失敗しました」
タスクリクエストの例
以下は、スキルがIntentRequest
の処理時に、Amazon定義済みタスクのAMAZON.PrintPDF
とカスタムタスクのamzn1.ask.skill.12345678-90ab-cdef-1234-567890abcdef.CountDown
の実行をリクエストする方法の例です。
RESUME_SESSION
を指定したManaged Skill Connectionsの場合
const TestIntentRequestHandler = {
canHandle(handlerInput) {
const request = handlerInput.requestEnvelope.request;
return request.type === 'IntentRequest'
&& request.intent.name === 'TestIntent';
},
handle(handlerInput) {
return handlerInput.responseBuilder
.addDirective({
'type': 'Connections.StartConnection',
'uri': 'connection://AMAZON.PrintPDF/1',
'onCompletion': 'RESUME_SESSION',
'input': {
'@type': 'PrintPDFRequest',
'@version': '1',
'title': 'タイトル',
'description': '説明',
'url': 'http://www.example.com/flywheel.pdf'
},
'token': '...'
})
.getResponse();
}
};
SEND_ERRORS_ONLY
を指定したManaged Skill Connectionsの場合
const TestIntentRequestHandler = {
canHandle(handlerInput) {
const request = handlerInput.requestEnvelope.request;
return request.type === 'IntentRequest'
&& request.intent.name === 'TestIntent';
},
handle(handlerInput) {
return handlerInput.responseBuilder
.addDirective({
'type': 'Connections.StartConnection',
'uri': 'connection://AMAZON.PrintPDF/1',
'onCompletion': 'SEND_ERRORS_ONLY',
'input': {
'@type': 'PrintPDFRequest',
'@version': '1',
'title': 'タイトル',
'description': '説明',
'url': 'http://www.example.com/flywheel.pdf'
}
})
.withShouldEndSession(true)
.getResponse();
}
};
RESUME_SESSION
を指定したAmazon定義済みタスクのDirect Skill Connectionsの場合
const TestIntentRequestHandler = {
canHandle(handlerInput) {
const request = handlerInput.requestEnvelope.request;
return request.type === 'IntentRequest'
&& request.intent.name === 'TestIntent';
},
handle(handlerInput) {
return handlerInput.responseBuilder
.addDirective({
'type': 'Connections.StartConnection',
'uri': 'connection://AMAZON.PrintPDF/1?provider=amzn1.ask.skill.12345678-90ab-cdef-1234-567890abcdef',
'onCompletion': 'RESUME_SESSION',
'input': {
'@type': 'PrintPDFRequest',
'@version': '1',
'title': 'タイトル',
'description': '説明',
'url': 'http://www.example.com/flywheel.pdf'
},
'token': '...'
})
.getResponse();
}
};
SEND_ERRORS_ONLY
を指定したAmazon定義済みタスクのDirect Skill Connectionsの場合
const TestIntentRequestHandler = {
canHandle(handlerInput) {
const request = handlerInput.requestEnvelope.request;
return request.type === 'IntentRequest'
&& request.intent.name === 'TestIntent';
},
handle(handlerInput) {
return handlerInput.responseBuilder
.addDirective({
'type': 'Connections.StartConnection',
'uri': 'connection://AMAZON.PrintPDF/1?provider=amzn1.ask.skill.12345678-90ab-cdef-1234-567890abcdef',
'onCompletion': 'SEND_ERRORS_ONLY',
'input': {
'@type': 'PrintPDFRequest',
'@version': '1',
'title': 'タイトル',
'description': '説明',
'url': 'http://www.example.com/flywheel.pdf'
}
})
.withShouldEndSession(true)
.getResponse();
}
};
RESUME_SESSION
を指定したカスタムタスクのDirect Skill Connectionsの場合
const TestIntentRequestHandler = {
canHandle(handlerInput) {
const request = handlerInput.requestEnvelope.request;
return request.type === 'IntentRequest'
&& request.intent.name === 'TestIntent';
},
handle(handlerInput) {
return handlerInput.responseBuilder
.addDirective({
'type': 'Connections.StartConnection',
'uri': 'connection://amzn1.ask.skill.12345678-90ab-cdef-1234-567890abcdef.CountDown/1?provider=amzn1.ask.skill.12345678-90ab-cdef-1234-567890abcdef',
'onCompletion': 'RESUME_SESSION',
'input': {
'upperLimit': 10,
'lowerLimit': 1
},
'token': '...'
})
.getResponse();
}
};
SEND_ERRORS_ONLY
を指定したカスタムタスクのDirect Skill Connectionsの場合
const TestIntentRequestHandler = {
canHandle(handlerInput) {
const request = handlerInput.requestEnvelope.request;
return request.type === 'IntentRequest'
&& request.intent.name === 'TestIntent';
},
handle(handlerInput) {
return handlerInput.responseBuilder
.addDirective({
'type': 'Connections.StartConnection',
'uri': 'connection://amzn1.ask.skill.12345678-90ab-cdef-1234-567890abcdef.CountDown/1?provider=amzn1.ask.skill.12345678-90ab-cdef-1234-567890abcdef',
'input': {
'upperLimit': 10,
'lowerLimit': 1
},
'onCompletion': 'SEND_ERRORS_ONLY'
})
.withShouldEndSession(true)
.getResponse();
}
};
リクエスタースキルをテストする
スキルをリクエスタースキルに変更したら、ほかの呼び出しのテストと同様にテストできます。リクエスタースキルがタスクリクエストを開始したら、Alexaは可能性のあるプロバイダーリストからタスクリクエストに最適なプロバイダーを選択し、選択された公開中のプロバイダースキルにAlexaサービスがリクエストをルーティングします。
さらに、リクエスタースキルでRESUME_SESSION
を指定する場合、受け取る可能性のあるさまざまなステータスコードの処理方法もテストする必要があります。特定のステータスコードのSessionResumedRequest
を受け取ったときにスキルがどう応答するかをテストするには、AMAZON.TestStatusCode
タスクを定義したConnections.StartConnection
ディレクティブを返すようリクエスタースキルを変更します。このディレクティブが返される応答の本文には、inputにテスト対象のステータスコードが含まれます。
例:SessionResumedRequest
ハンドラーが404
ステータスコードを処理する方法をテストする
SessionResumedRequest
ハンドラーが404
のステータスコードを受け取った場合の処理方法をテストするには、スキルが以下のディレクティブを返す必要があります。
return handlerInput.responseBuilder
.addDirective({
'type': 'Connections.StartConnection',
'uri': 'connection://AMAZON.TestStatusCode/1',
'input': {
'code': '404'
}
})
.getResponse();
その後、リクエスタースキルは、inputで定義されたステータスコードを含むSessionResumedRequest
オブジェクトを受け取ります。
{
"type": "SessionResumedRequest",
"requestId": "string",
"timestamp": "string",
"locale": "string",
"cause": {
"type": "ConnectionCompleted",
"status": {
"code": "404",
"message": "ステータスコードのテストに成功しました"
}
}
}
リクエスタースキルを公開する
リクエスタースキルの認定要件は、リクエスター以外のスキルの要件と同じです。
リクエスタースキルをまだ公開していない場合は、通常どおりテストしてスキル申請の要件を満たしてから、スキルの認定を申請します。Amazonがそのスキルを認定すると、そのスキルは一般に公開され、リクエスタースキルとして機能するようになります。Amazonで既に認定されているスキルを後からリクエスタースキルに変更する場合は、開発者がそのスキルを公開すると、変更が一般に公開されます。
Alexaスキルを公開する方法の詳細については、スキルの認定と公開を参照してください。
開発者サポート
問い合わせやサポートについては、Skill Connectionsチームにお問い合わせください。メールアドレスは、skill-connections-v2-beta@amazon.comです。
関連トピック
最終更新日: 2020 年 10 月 16 日