一旦与Alexa的语音服务连接(AVS)是成功,你的客户会使用HTTP / 2编码的多部分消息的Alexa的沟通。从你的客户发送的事件,以及Alexa发送的指令,指定服务器或客户端应该采取行动。下面的图说明了一个识别事件发送到AVS。多部分消息是由两部分组成。第一,一个JSON格式的事件,第二,捕获的音频产品的麦克风。
HTTP2消息头
每次调用AVS需要以下消息头:
:method = {{verb}}
:scheme = https
:path = /{{API version}}/{{events or directives}}
authorization = Bearer {{access_token}}
content-type = multipart/form-data; boundary={{boundary_term}}
方法
AVS支持以下方法:
POST:对所有事件发送到AVS使用此方法
GET:获得使用指令建立的下降通道
方案
访问AVS API是HTTPS方案。
路径
所有事件使用下列路径:
:path = /v20160207/events
所以指令使用下列路径:
:path = /v20160207/directives
授权
当一个用户授权访问你的产品,登录亚马逊返回一个access_token用来授权。access_token必须包含在每个请求的头。
authorization = Bearer {{access_token}}
内容类型
内容类型描述包含在正文中的数据。这使得AVS妥善处理请求。boundary_term和不同部位的多方消息。在Alexa的话,JSON和二进制音频。
内容类型应该是multipart/form-data。你可以自由地决定自己的boundary_term。唯一的要求是,boundary_term一致使用,boundary_term不存在的数据。
content-type = multipart/form-data; boundary={{boundary_term}}
HTTP / 2多部分消息
AVS希望HTTP / 2编码的多部分消息。多部分消息是由一个或多个JSON格式的指令/事件及其关联的二进制音频附件(如果需要)。
JSON Headers
下面的headers是每个部分请求JSON部分要求:
Content-Disposition: form-data; name="metadata"
Content-Type: application/json; charset=UTF-8
JSON内容
所有的JSON格式的事件发送到AVS格式如下:
{
"event":{
"header": {
"namespace": "{{STRING}}",
"name": "{{STRING}}",
"messageId": "{{STRING}}",
},
"payload": {
}
}
}
每个事件都有唯一的头和有效载荷。在事件头上,确定接口和事件命名空间和名称,是一种独特的标识符和messageId客户端必须发送每个请求.
二进制音频头
下面的Hearders是每个部分要求二进制音频附件要求:
Content-Disposition: form-data; name="audio"
Content-Type: application/octet-stream
二进制音频内容
这部分的多部分消息是二进制音频。唯一需要音频附件的事件是识别事件。
HTTP 2响应
AVS将两种类型的反应,你的客户。第一种类型,像是多部分消息的请求,由一个或多个JSON格式的指令和相关的二进制音频附件(如果需要)。第二类是例外。例外情况是不多的信息和返回到您的客户端时,出现错误。每个异常将包括错误代码和说明。
实例
例1:
这个例子显示了一个识别事件,它接收一个指令作为响应。
Request:
// Note: HTTP2 is a binary protocol and the payload is not human-readable. This is for illustrative purposes only.
:method = POST
:scheme = https
:path = /v20160207/events
authorization = Bearer foo-bar
content-type = multipart/form-data; boundary=this-is-a-boundary
--this-is-a-boundary
Content-Disposition: form-data; name="metadata"
Content-Type: application/json; charset=UTF-8
{
"context": [
{
"header": {
"namespace": "AudioPlayer",
"name": "PlaybackState"
},
"payload": {
"token": "abcd1234",
"offsetInMilliseconds": 7000,
"playerActivity": "PLAYING"
}
},
{
"header": {
"namespace": "Alerts",
"name": "AlertsState"
},
"payload": {
"allAlerts": [
{
"token": "foo-bar",
"type": "ALARM",
"scheduledTime": "2015-10-30T22:34:51+00:00"
}
],
"activeAlerts": [
]
}
},
{
"header": {
"namespace": "Speaker",
"name": "VolumeState"
},
"payload": {
"volume": 25,
"muted": false
}
},
{
"header": {
"namespace": "SpeechSynthesizer",
"name": "SpeechState"
},
"payload": {
"token": "zxcv8523",
"offsetInMilliseconds": 0,
"playerActivity": "FINISHED"
}
}
],
"event": {
"header": {
"namespace": "SpeechRecognizer",
"name": "Recognize",
"messageId": "messageId-123",
"dialogRequestId": "dialogRequestId-321"
},
"payload": {
"profile": "CLOSE_TALK",
"format": "AUDIO_L16_RATE_16000_CHANNELS_1"
}
}
}
--this-is-a-boundary
Content-Disposition: form-data; name="audio"
Content-Type: application/octet-stream
{{binary audio attachment}}
--this-is-a-boundary--
Response
:status = 200
content-type = multipart/related; boundary=this-is-a-boundary; type="application/json"
--this-is-a-boundary
Content-Type: application/json; charset=UTF-8
{
"directive": {
"header": {
"namespace": "SpeechSynthesizer",
"name": "Speak",
"messageId": "ewq-321",
"dialogRequestId": "dialogRequestId-321"
},
"payload": {
"url": "cid:1234",
"format": "AUDIO_MPEG"
"token": "kr17447380422"
}
}
}
--this-is-a-boundary
Content-Type: application/octet-stream
Content-ID: 1234
{{binary audio attachment}}
--this-is-a-boundary--
例2:
此示例显示一个识别事件,该事件接收一个指令指令和一个侦听指令作为响应。
Request
// Note: HTTP2 is a binary protocol and the payload is not human-readable. This is for illustrative purposes only.
:method = POST
:scheme = https
:path = /v20160207/events
authorization = Bearer foo-bar
content-type = multipart/form-data; boundary=this-is-a-boundary
--this-is-a-boundary
Content-Disposition: form-data; name="metadata"
Content-Type: application/json; charset=UTF-8
{
"context": [
{
"header": {
"namespace": "AudioPlayer",
"name": "PlaybackState"
},
"payload": {
"token": "1234",
"offsetInMilliseconds": "15874",
"playerActivity": "PLAYING"
}
},
{
"header": {
"namespace": "Alerts",
"name": "AlertsState"
},
"payload": {
"allAlerts": [
{
"token": "foo-bar",
"type": "ALARM",
"scheduledTime": "2015-10-30T22:34:51+00:00"
}
],
"activeAlerts": [
]
}
},
{
"header": {
"namespace": "Speaker",
"name": "VolumeState"
},
"payload": {
"volume": 25,
"muted": false
}
},
{
"header": {
"namespace": "SpeechSynthesizer",
"name": "SpeechState"
},
"payload": {
"token": "zlkv8723",
"offsetInMilliseconds": 0,
"playerActivity": "FINISHED"
}
}
],
"event": {
"header": {
"namespace": "SpeechRecognizer",
"name": "Recognize",
"messageId": "bnm-123",
"dialogRequestId": "dialogRequestId-201"
},
"payload": {
"profile": "CLOSE_TALK",
"format": "AUDIO_L16_RATE_16000_CHANNELS_1",
}
}
}
--this-is-a-boundary
Content-Disposition: form-data; name="audio"
Content-Type: application/octet-stream
{{binary audio attachment}}
--this-is-a-boundary--
Response
status = 200
content-type = multipart/related; boundary=this-is-a-boundary; type="application/json"
--this-is-a-boundary
Content-Type: application/json; charset=UTF-8
{
"directive": {
"header": {
"namespace": "SpeechSynthesizer",
"name": "Speak",
"messageId": "lkj-321",
"dialogRequestId": "dialogRequestId-201"
},
"payload": {
"url": "cid:1234",
"format": "AUDIO_MPEG",
"token": "sn2716057"
}
}
}
--this-is-a-boundary
Content-Type: application/octet-stream
Content-ID: 1234
{{binary audio attachment}}
--this-is-a-boundary
Content-Type: application/json; charset=UTF-8
{
"directive": {
"header": {
"namespace": "SpeechRecognizer",
"name": "ExpectSpeech",
"messageId": "fyr-212",
"dialogRequestId": "dialogRequestId-201"
},
"payload": {
"timeoutInMilliseconds": 8000
}
}
}
--this-is-a-boundary--