基于websocket协议的产品接入

一、产品介绍

基于websocket协议的API请求DUI全链路产品,获得对话交互结果

1.1 适用场景

1)轻量级嵌入式设备,基于协议开发

2)采用云对云的方式,使用DUI全链路产品,基于协议开发

3)其他特殊场景,需要基于协议开发

4)支持语音、文本、意图三种输入

1.2 使用限制

需要先前往控制台创建全链路产品,并且将产品成功发布,才能正常使用基于websocket协议的API。

二、接入说明

2.1 接入前的准备

1)登录DUI控制台

2)创建全链路产品

3)进行产品配置

4)添加技能

5)进行产品技能测试

6)配置授权

7)发布产品

2.2 建立websocket连接

本API正式环境的地址是wss://dds.dui.ai/dds/v2/[分支号],其中[分支号]是DUI控制台分支管理页面的内容。如下图所示: 在产品详情页的发布管理页面,选择分支管理,获取分支号。

2.2.1 连接上需要携带的公共参数

参数名 含义 是否必须 取值示例
serviceType 表示使用何种协议 websocket
productId 产品标识 278578090
productVersion 指定使用的产品版本 1

 

连接上需要携带的参数,包含了授权参数,授权有两种场景,一种是设备对接云,一种是云对云。具体参数信息如下:

2.2.2 设备对接云端API的授权参数

参数名 含义

是否必须

取值示例
deviceName 设备激活时获取到的device profile中deviceName字段

0ddddeeeeeeeeeeee88888888260c8ab
nonce 随机字符串, 32字符以内 bf7c8674
sig 签名,对query parameter中的参数按照预先约定的顺序排序 (devicename + nonce + productId + timestamp),然后基于 deviceSecret对参数做签 名:hmacsha1(deviceSecretSecret, devicename + nonce + productId + timestamp) 0ddddddddd94dd87788888888260c8ab
timestamp unix时间戳(毫秒) 1546059559999

 

特别说明:获取DeviceName,需要走设备激活流程,请求设备激活接口,接口详情如下:

 

设备激活接口简介

设备使用前必须的鉴授权环节,设备通过此接口,与DUI产品绑定并获得鉴权秘钥(device profile),后续基于鉴权秘钥与云端进行语音对话请求。设备方需要妥善保管鉴权秘钥,如丢失可调用此接口进行重新获取,重新获取的秘钥与原来的秘钥不相同,且原秘钥会失效。

 

接口请求地址

https://auth.dui.ai/auth/device/register

 

接口请求类型

POST

 

接口请求参数

Headers

参数名 参数值 是否必须
Content-Type application/json

 

Query

参数名

是否必须

示例 备注
productKey 0d397453dd94dd87788888888260c8cb 来自dui控制台,产品授权管理页面
format

plain

传入plain即可
productId 100000001 产品id,来自dui控制台,产品授权管理页面
timestamp 1546059559999 unix时间戳(毫秒)
nonce bf7c8674 随机字符串,32字符以内
sig 0ddddddddd94dd87788888888260c8ab 签名,对query parameter中的参数按照预先约定的顺序排序 (productKey + format+ nonce + product id + timestamp),然后基于product secret对参数做签名:hmacsha1(productSecret,productKey + format+ nonce + product id + timestamp) ,本文末尾有签名示例代码。

 

Request Body

request body中通过json格式上报设备信息,上报到思必驰的设备信息有三个作用:
1)确认设备的唯一性(针对各种设备的必填字段)
2)方便后续针对不同类型的设备进行优化(针对各种设备的选填字段)
3)查询统计分析,方便客户按照不同维度统计自己设备的激活情况
Android
名称 类型

是否必须

字段说明

示例
platform string

平台类型,android设备填android即可

android
deviceId string 设备ID 5235894f-3028-33f4-a948-c86549cc4808
packageName string 包名 com.aispeech.dui.demo
applicationLabel string 应用名称 DUI Demo
applicationVersion string 版本 0.1.0-20171031163815
buildVariant string 构建类型: debug 或 release release
buildSdkInt string framework level 19
displayMatrix string 屏幕分辨率 720*1280
buildModel string 型号 Coolpad 8675
buildManufacture string 制造商 XiaoMi
buildDevice string 设备名称 8675
imei string IMEI号 356704081123748
mac string MAC地址 44:45:53:54:00:00
androidId string Android ID 9774d56d682e549c

 

iOS

名称 类型 是否必须

字段说明

备注
platform string

平台类型,ios设备填ios即可

ios
deviceId string 设备ID 0060D69C-AB7A-44E9-8754-7A12EC2AEDAD
packageName string 包名 com.aispeech.dui.demo
applicationLabel string 应用名称 DUI Demo
applicationVersion string 版本 0.1.0-20171031163815
buildSdkInt string framework level level 19
displayMatrix string 屏幕分辨率 750x1334
buildModel string 型号 iPhone 6
buildManufacture string 制造商 Apple
buildDevice string 设备名称 iPhone

 

嵌入式

名称

类型

是否必须

字段说明

备注
platform string

平台类型,嵌入式设备填嵌入式操作系统或芯片型号即可

linux
deviceName string 设备名称,要求是接入方所有设备中唯一的一个字段,比如mac地址、uid号等 0060D69C-AB7A-44E9-8754-7A12EC2AEDAD
instructionSet string 指令集 armv6
chipModel string 芯片型号 RK3308

 

正确返回示例

{
    "deviceInfo": {
        ......
    },
    "deviceName": "0000-0001",
    "deviceSecret": "1518b5f911864150a092ba6952be534d",
    "productId": "666666"
}

 

错误返回示例

{
    "errId": 401,
    "error": "signature mismatch."
}

 

通用http status解释

  • 200 ok
  • 400 请求错误
  • 401 因为权限问题激活失败
  • 500 内部系统错误

 

特别说明

嵌入式设备的请求body里,deivceName字段,需要有唯一性保证,否则如不同设备使用相同的deviceName,第二个激活的设备会使第一个激活设备的设备秘钥失效,可能会对用户体验造成不确定的影响。

 

附录 签名代码示例

JAVA

String content = productKey + format + nonce + productId + timestamp;
String signature = SecureUtil.hmacSha1(productSecret).digestHex(content);

2.2.3 云端对接云端的授权参数

参数名 含义

是否必须

取值示例
apikey DUI控制台生成的绑定过ip的访问标识

0ddddeeeeeeeeeeee88888888260c8ab

2.2.4 一条完整的云端对接云端的连接示例

wss://dds.dui.ai/dds/v2/test?serviceType=websocket&productId=278578090&apikey=0ddddeeeeeeeeeeee88888888260c8ab

2.2.5 在以下情况下建立连接会失败

1)产品没有发布

2)产品分支号没有对应已经发布过的产品版本

3)授权参数不正确,服务端鉴权不通过

2.2.6 正确建立websocket连接的报文

2.3 发送语音请求

websocket连接建立成功之后,调用端首先向服务端发送一个opcode为text的报文;这个报文的payload是一个json字符串。

2.3.1 语音请求text参数

参数名 含义 是否必须 取值示例
topic 用于区分语音请求,文本请求 recorder.stream.start
recordId uuid,标识一次请求,32字符 DUIddeeeeeeeeeeee88888888260c8ab
sessionId

uuid,服务端通过相同的sessionId关联多轮请求的上下文;

首轮对话请求不需要携带;

非首轮对话请求取值是上一轮服务端返回结果中的sessionId

DUIddeeeeeeeeeeee88888888260c8ab
audio.audioType 音频类型,推荐使用压缩过的音频格式,以节省带宽,推荐ogg,不支持ogg vorbis,只支持ogg speex ogg, wav,mp3,flv,amr,opus
audio.sampleRate 音频数据采样率,推荐使用16000; (ogg支持8000、16000;wav支持8000、16000;mp3支持16000、22050、44100;amr支持8000) 16000
audio.channel 声道 1
audio.sampleBytes 音频数据每采样点大小 2
wakeupWord 触发当次请求的唤醒词,用于oneshot使用场景 你好小驰
asrParams.enableVAD 是否使用云端vad true,false
asrParams.realBack 是否使用实时识别结果 true,false
asrParams.enablePunctuation 识别结果是否开启标点符号 true,false
asrParams.enableTone 是否使用拼音带声调 true,false
asrParams.enableConfidence 识别结果是否返回置信度 true,false
asrParams.enableNumberConvert 识别结果中文数字转成阿拉伯数字 true,false
asrParams.phraseHints 使用热词识别(pattern要在第二路,或者第三路lm中存在) [{"type": "vocab", "name": "行政区", "data":["黄浦区"]}]
asrParams.enableEmotion
开启情感识别,返回性别、年龄、情绪 true,false
asrParams.res
切换识别生效的语言模型 aienglish(此处填写三路模型对应的识别引擎)
context.skill.task 在非首轮中可能用到,用于指定调用端使用了上一轮nbest结果中的哪一个task 查天气
aiType 指定云端服务的类型,asr表示识别结果,不设置该字段表示对话结果 asr
asrPlus.enableAsrPlus 是否开启声纹 true,false
asrPlus.users 注册的声纹用户列表,开启声纹后此字段必须填 ["user1", "user2"]
asrPlus.organization 注册的声纹厂商、机构、组织,开启声纹后此字段必须填 "AISPEECH"

2.3.2 语音请求binary数据

调用端发送完opcode为text的报文之后,接着发送语音数据,opcode为binary,payload是语音数据;

语音数据建议分帧发送,每帧包含的语音时长是100毫秒;

语音数据发送完毕之后,再发送一个opcode为binary,payload是空,表示语音数据发送完毕。

2.4 发送文本请求

2.4.1 文本请求参数

参数名 含义 是否必须 取值示例
topic 用于区分语音请求,文本请求 nlu.input.text
recordId uuid,标识一次请求,32字符 DUIddeeeeeeeeeeee88888888260c8ab
sessionId

uuid,服务端通过相同的sessionId关联多轮请求的上下文;

首轮对话请求不需要携带;

非首轮对话请求取值是上一轮服务端返回结果中的sessionId

DUIddeeeeeeeeeeee88888888260c8ab
refText 请求的文本 苏州的天气
aiType 指定云端服务的类型,asr表示识别结果,不设置该字段表示对话结果 asr

2.5 发送触发意图请求

2.5.1 触发意图请求参数

参数名 含义 是否必须 取值示例
topic 用于区分语音请求,文本请求,指定意图请求 dm.input.intent
recordId uuid,标识一次请求,32字符 DUIddeeeeeeeeeeee88888888260c8ab
sessionId

uuid,服务端通过相同的sessionId关联多轮请求的上下文;

首轮对话请求不需要携带;

非首轮对话请求取值是上一轮服务端返回结果中的sessionId

DUIddeeeeeeeeeeee88888888260c8ab
intent 意图名称 查天气
task 任务名称 查天气
skillId 技能id,和skill两个字段中必须有一个 0000000000000000
skill 技能名称,和skillId两个字段中必须有一个 查天气
slots 语义槽名称,语义槽取值集合 {"城市":"苏州"}

2.6 上传自定义配置

自定义配置配合技能开发进行生效,具体请参照 配置对话回复 中的 资源查询结果引用——$参数名称$。

2.6.1 上传技能级配置

上传的数据仅在指定的技能中使用,如用户微信是否在登录状态。

 

参数名 含义 是否必须 取值示例
topic string类型,表示技能级配置topic

skill.settings

recordId string类型,uuid,标识一次请求,32字符

DUIddeeeeeeeeeeee88888888260c8ab

skillId string类型,技能ID标识

0000000000000000

option string类型,执行选项,设置、删除或查询

set(默认)/ delete / get

settings json数组类型,每个元素标识一组设置的k-v列表

[{"key":"key1","value":"value1"}]

settings[0].key string类型,自定义key名称

city

settings[0].value string类型,自定义key对应的取值,当option是delete和get时不需要 否 

苏州

 

2.6.2 上传系统级配置

上传的数据是公用的,有多个技能会关心并使用此类配置。如设备所在位置信息。

 

参数名 含义 是否必须 取值示例
topic string类型,表示系统级设置topic

system.settings

recordId string类型,uuid,标识一次请求,32字符

DUIddeeeeeeeeeeee88888888260c8ab

option string类型,执行选项,设置、删除或查询

set(默认)/ delete / get

settings json数组类型,每个元素标识一组设置的k-v列表

[{"key":"key1","value":"value1"}]

settings[0].key string类型,自定义key名称

city

settings[0].value string类型或者json,自定义key对应的取值,当option是delete和get时不需要

苏州

 

2.6.3 上传配置的响应

参数名 含义 取值示例
recordId string类型,uuid, 标识一次请求 DUIddeeeeeeeeee88888888260c8ab
settings[0].key option是get时返回,string类型,查询自定义的key名称 city
settings[0].value option是get时返回, string类型,查到的value,如果没查到则是一个null 苏州
error.errId 错误码,出错时返回 1
error.errMsg 错误信息,出错时返回 params error

 

2.7 回复的对话结果(包括触发意图回复结果)

当请求的text报文没有aiType字段时,回复的是对话结果。

2.7.1 对话结果参数

参数名 含义 取值示例
dm.intentName 意图名称 查天气
dm.input 识别结果或者客户端发送的文本  
dm.intentId 意图id 0000000000000000
dm.runSequence 本地执行command和播报nlg的先后顺序 nlgFirst
dm.widget 显示控件  
dm.widget.widgetName 控件名称,冗余为了兼容老字段 card
dm.widget.subTitle 副标题 好听的歌
dm.widget.name 控件名称 card
dm.widget.extra 用于透传webapi返回字段  
dm.widget.title 主标题 忘情水
dm.widget.buttons[].name 按钮显示提示 播放
dm.widget.duiWidget 控件类型,冗余为了兼容老字段 media
dm.widget.type 控件类型 media
dm.widget.count 列表控件内容数 1
dm.widget.content 列表控件内容  
dm.widget.currentPage 列表控件当前页 2
dm.widget.totalPages 列表总共页数 5
dm.widget.itemsPerPage 每页显示数 5
dm.widget.match 内容是否匹配 1
dm.nlg 系统生成的对话回复 今天的天气是晴
dm.task 任务名称 查天气
dm.shouldEndSession 表示对话是否结束 true,false
skillId 技能id 0000000000000000
speakUrl 语音播报nlg的链接 https://dds.dui.ai/xxx
error.errId 错误id 010400
error.errMsg 错误信息 It's time to do qa.
recordId uuid,标识一次请求,32字符 DUIddeeeeeeeeeeee88888888260c8ab
sessionId

uuid,服务端通过相同的sessionId关联多轮请求的上下文;

首轮对话请求不需要携带;

非首轮对话请求取值是上一轮服务端返回结果中的sessionId

DUIddeeeeeeeeeeee88888888260c8ab
contextId

向前兼容(sessionId替代了)待废弃

 

2.8 回复的识别结果

当请求的text报文有aiType字段,并且aiType字段为asr时,回复的是识别结果。

2.8.1识别结果参数

参数名 含义 取值示例
recordId 请求id DUIddeeeeeeeeeeee88888888260c8ab
eof 标识识别是否结束 1表示结束,0表示未结束
var 识别中间结果 播放
text 识别最终结果 播放西游记
conf 置信度,开启enableConfidence后返回 1
age 年龄段,开启enableEmotion后返回

child 儿童

adult 成人

elder 老人

ageScore 年龄段得分,开启enableEmotion后返回 10.31
gender 性别,开启enableEmotion后返回

male 男性

female 女性

genderScore 性别得分,开启enableEmotion后返回 11.021
emotion 情绪,开启enableEmotion后返回

happy 高兴

angry 生气

sad 伤心

neutral 中性

emotionScore 情绪得分,开启enableEmotion后返回 10.31

2.9 声纹结果

当请求参数携带asrPlus,并且开启时,会有声纹相关的topic返回

2.9.1声纹结果参数

参数名
含义
类型
取值示例
topic topic string asrplus.voiceprint.result
recordId 请求id string DUIddeeeeeeeeeeee88888888260c8ab
sessionId 会话id string 96e446beee364ce4ab8fb7899609861b
speakerLabels[0].bg 音频开始时间 int 160
speakerLabels[0].ed 音频结束时间 int 4380
speakerLabels[0].rec 识别结果 string "今天天气怎么样"
speakerLabels[0].speakerId 说话人id string "100001"

2.10 错误码列表

errId errMsg 含义
010104 product info error 产品id错误
010105 检测到敏感词 检测到敏感词
010304 asr calc service internal error. 请求识别服务错误
010305 asr result is null 识别结果为空
010306 asr calc service connect timeout. 连接识别服务超时
010307 asr calc service close socket. 识别服务关闭连接
010308 asr calc service socket send error. 发送识别报文错误
010309 server receive audio in wrong sequence. 服务收到识别报文乱序
010310 asr calc service server busy. 识别服务过载
010311 asr calc service audio too large. 服务收到音频过大
010316 connect asr service error. 连接识别服务错误
010400 It's time to do qa. 说法未标注
010402 nlu service error. 请求语义服务出错
010403 meet exiting command. 说法命中退出词
010404 no dispatch status. 技能调度失败
010405 request cnluserver error. 请求语义服务错误
010406 request oliveserver error. 请求内置语义服务错误
010410 request body invalid. 请求中控的body非法
010411 Do not have product info. 获取不到对应产品信息
010412 Do not have bundle info, can not get skillId. 获取不到之前上下文信息(execute return信息没有找到之前上下文信息,查询数据返回理论上只出现在非首轮)
010413 Do not find this skillId. 未找到skillId对应技能配置信息(triggerIntent和sysnc接口)
010414 Do not contain sessionId. 请求中控时未携带sessionId
010415 Do not contain retry audio. 命中透传音频技能时,传输音频的body未携带audio数据
010501 connect dm service error. 请求cdmserver失败
010502 dm service error. 对话服务内部错误
010504 over max retry times 错误重试次数超过限制
010505 fallback skill respond ok. 命中兜底技能
010507 ba skill respond ok. 命中BA技能
010801 RUYI service error. 请求RUYI服务错误
080002 webhook timeout. 请求web api超时
080003 webhook error. 请求web api错误
080004 Semantic parsing failure 首轮语义结果为空
080005 Do not support this task 不支持的技能任务
080007 The input sequence is incorrect 当前输入不在之前条件输入的下一轮对话列表中
080008 Do not hava asr result 首轮识别为空;对话中识别为空
080010 Do not hava any matching condition 定制的输出nlg条件出错
080012 响应超时,暂时不能为你提供服务 本地api调用超时
080013 Api can not be null 数据源未定义
080014 Retrytime up to maximum 到达错误重试次数退出
080015 ba timeout 请求BA服务超时
080016 proxy invalid. 自定义技能未按协议返回
080017 proxy return empty. 自定义技能服务返回nlg为空
080018 proxy service error. 请求自定义技能服务错误
080019 Do not have this intent 不存在意图的对话资源
010700 request dm dispatcher error. 请求新中控对话服务错误

三、示例代码

3.1多轮对话交互python示例代码

查看示例代码

3.2多轮对话交互java示例代码

查看示例代码