车载语音一语直达
更新时间:2021-09-28
车载语音一语直达
一语直达介绍:
可在小程序内和小程序外,通过一句话直达小程序任一子页面;举例:“小度小度,找个【中石化】加油站加【300块】【95号】油”→ 小程序对应支付页面“小度小度,查询【12月10号】【北京】到【上海】的【国航】机票”→ 小程序对应查询结果页面
一、快速开发
- 方案介绍
1.开发者通过在小程序开发者平台订阅意图来实现一语直达的能力,由于小程序开发者平台暂未开放 ,这部分订阅的工作暂时可由百度代为开发;
2.当用户说一语query后语音语义会解析出具体的意图和槽位,然后把意图和槽位在调用开发者的云端API时通过参数的形式传到开发者小程序的云端;
3.小程序云端根据意图和槽位处理业务,处理完成后给语义服务端返回打开小程序具体页面的url(页面path,页面擦数)
4.在小程序端上需要添加标签,把控件和订阅意图的垂类做绑定,以便与用户在界面上手动选择了的这部分槽位也能同时带到云端;
- 业务流程图如下
二、小程序客户端处理
- 介绍
当小程序的宿主app收到一语直达的指令后会调起相应的小程序。根据当前的场景,小程序的一语直达分为两种方式,分别代表不同的场景。
方式1: 小程序未打开或已打开,但是当前页面不是一语直达目标页。
一语直达可以理解为宿主会打开一个带参数的小程序页面。而且,在Page的onLoad中会拿到这些参数。
示例:
Page({
onLoad(options) {
var id = opt.id;// id 是小程序和小程序server 端协议好的参数
},
getDetail(id){
// 获取详情接口
}
}
方式2: 当前页面为一语直达目标页
如果当前小程序已经是打开的状态,而且正好处于一语直达的目标页。这种情况为了更好的交互体验,不会重新打开页面,而是通过iovauto-vsl组件把参数传递过来。
示例:
swan:
<iovauto-vsl bindOnRefresh="onRefresh">
// 其他业务内容
<iovauto-vsl>
js:
Page({
onLoad(options) {
const id = opt.id;// id 是小程序和小程序server 端协议好的参数
this.getDetail(id);
},
onRefresh(options) {
const id = opt.id;~~~~
this.getDetail(id);
},
getDetail(id){
// 获取详情接口
}
}
所以在代码中对这两种方式都需要做处理。
三、百度开发者工具调试
-
介绍
在开发的过程中,目前百度小程序开发者工具不支持第二种bindOnRefresh的方式,第一种方式可以通过修改百度开发者工具中编译配置来实现。
示例:
输入约定好的参数,点击添加。这样每次打开的时候都会携带固定的参数。
- 端状态同步 有些业务可能依赖于端上的一些状态,这时候在小程序打开的情况下可以在小程序端上报端状态业务需要的数据上报 通过调用API 上报端状态
addVoiceConfig(e) {
let config = {
fafa:'faf',
fafasfs:'afsfafa',
aaaa:'asfafa'
}
swan.iovauto.addVoiceConfig(JSON.stringify(config));
}
- 槽位上报
小程序端需要添加voice-slot-name 和voice-slot-value 标签,当用户已经手动选择的一些slot,会通过端上报的语义远端,并在语义识别结束后一并带到加油小程序服务端 - example
如果此时页面在前台 用户可以说去第一个加油站加95号油,“滨海加油站” 就能作为SLOT_GAS_STATION这个槽位的值带到小程序server 端html <iovauto-vsl> <view class="card-area"> <view class="top-description">加油站列表 </view> <scroll-view voice-type="scroll-horizontal" voice-tag="加油站列表" class="scroll-view" scroll-x="{{true}}" scroll-left="{= scrollLeft =}" bindvsl="scroll"> <view class="color-a row-view" bindvsl="phone" voice-type="phone" voice-tag="滨海加油站" voice-index="1" slot-name="SLOT_GAS_STATION" slot-value='滨海加油站' >滨海加油站 </view> <view class="color-b row-view" bindvsl="phone" voice-type="phone" voice-tag="中石油加油站南山店" voice-index="2" slot-name="SLOT_GAS_STATION" slot-value='中石油加油站南山店四' >中石油加油站南山店 </view> <view class="color-c row-view" bindvsl="phone" slot-name="SLOT_GAS_STATION" slot-value='中石油加油站南山店' voice-type="phone" voice-tag="中石油加油站南山店" voice-index="3">中石油加油站南山店 </view> </scroll-view> </view> </iovauto-vsl>
- 小程序server端处理(宿主云端与业务方协议)接口地址
1. 线上域名:由业务方提供
2.沙盒域名:由业务方提供
3.开发机域名:由业务方提供
- 接口部分
请求类型: post - 接口请求参数列表
字段名称 | 字段含义 | 字段类型 | 是否必填 | 备注 |
---|---|---|---|---|
intent | 意图 | String | 是 | 由业务方与语义共同定义 大写 如 GAS_ADD_OIL |
slots | 槽位 | json | 是 | 由语义解析出槽位变量 组装成json字符串 可为空json串 |
clientContext | 业务方自定义参数 | json | 是 | 由业务方自定义,语义透传 组装成json字符串 可为空json串 |
timestamp | 当前时间戳 | Integer | 是 | |
sign | 签名 | String | 是 | 签名生成方法见附录1 |
version | 客户端版本号 | Integer | 是 | 固定值1 |
ak | 云端分配 | String | 是 | 如 nc,fordedge |
cn | 渠道号 | String | 是 | 渠道号 |
c | 客户端 | String | 是 | a 安卓 i ios |
uuid | 车机唯一标识 | String | 是 | uuid |
project | 子项目 | String | 是 | 业务方提供 |
mode | 接口模式 | String | 是 | 固定值 app |
longitude | 用户当前经度 | String | 是 | |
latitude | 用户当前纬度 | String | 是 | |
userPhone | 百度账号对应的手机号 | String | 是 | AES加密 |
uid | 百度用户uid | String | 是 | |
cityName | 城市名 | String | 是 |
接口返回参数规范
字段名称 | 字段含义 | 字段类型 | 是否必填 | 备注 |
---|---|---|---|---|
code | 错误码 | Integer | 是 | code为1时,表示一语直达成功召回数据,此时data数据中的 path、intent、tts不为空 当code非1时,表示服务有异常,调用方拿data中的tts消息提示 |
cityName | 错误信息 | String | 是 | |
msg | 本次请求的logid | String | 是 | |
logId | 本次请求的logid | Integer | 是 | 接口调用异常,可使用此Logid查询日志 |
costtime | 本次请求总耗时 | String | 是 | |
data | 数据集 | Object | 是 | |
data.intent | 意图标识 | String | 是 | 本次请求的意图标识 |
data.path | 跳转地址 | String | 是 | 本次请求成功后跳转的地址,如果请求失败,此值为空 |
data.tts | 语音提示 | String | 是 | 本次请求语音播报tts 由业务方自定义 |
返回示例
{
"code":1,
"msg":"success",
"logId":"1588700353",
"data":{
"path":"/pages/detail/index?gasId=482&oilId=4",
"tts":"为你找到如下内容"
},
"time":1602559588,
"requestId":"1588700353",
"costtime":"0.07"
}
当code非1时,返回示例如下
{
"code":2,
"msg":"fail", //当code非1时,如果data数据中不存在tts,则宿主云端会使用此msg作为tts,
"logId":"1588700353",
"data":{
"path":"",
"tts":"服务出现异常,请稍后再试"
},
"time":1602559588,
"requestId":"1588700353",
"costtime":"0.07"
}
- 附录宿主小程序请求小程序云端参数签名字段生成方法(仅供参考)
1.请求参数地址
http://test/testproject=scenicspot&pageNo=1&pageSize=2×tamp=1548232552
2. 请求参数按照key字典升序排序(sign删除)
str=pageNo=1pageSize=2project=scenicspottimestamp=1548232552
3.拼接前后prefix+str+postfix后,前后缀由小程序开发云端提供给宿主云端
prefix=123456;
postfix=123456;
123456pageNo=1pageSize=2project=scenicspottimestamp=1548232552123456
-
字符串哈希再转小写
1. strtolower(sha1($string));
代码示例public static function sign($param, $prefix, $postfix){ if(isset($param['sign'])){ unset($param['sign']); } ksort($param); $string = ''; foreach ($param as $key=>$val){ $string .= $key.'='.$val; } $string = $prefix.$string.$postfix; return strtolower(sha1($string)); }
2.AES加密示例
public static function aesEncrypt($data,$aesKey,$aesIv){ if (!is_string($data)) { $data = json_encode($data,JSON_UNESCAPED_UNICODE); } return openssl_encrypt($data,'AES-128-CBC',$aesKey, 0,$aesIv); }