小程序客服能力,复用QQ聊天机器人能力,以下以QQ聊天机器人指代客服号。 当前,客服能力仅支持在用户主动发消息后,客服号才能进行回复,不支持主动向用户推送消息。 开发者需要在管理端申请开通,目前功能正在内测中,满足内测资格即可在开发者管理端看到开通入口。
打开客服入口:
<button open-type="contact" bindcontact="onEnterContact"> 进入机器人客服 </button>
每轮交互由 QQ 发起(步骤2),机器人接收到消息之后,应先立即给 QQ 回确认包(包体内容可以为空;步骤3);然后再异步回调 QQ 接口,将机器人回复的消息推送给QQ(步骤4)。 步骤2中,QQ 会带上消息唯一标识MsgId给机器人;机器人在异步回调时,需要将MsgId原样带回给QQ。
MsgId 有有效期,目前为3分钟,所以请在3分钟内回复消息,超过3分钟会话会过期,就无法回复消息了。
POST
https://app.qun.qq.com/robotapi/msg_reply/v2?ts=xxx&appid=123&nonce=123&sig=abcd
Content-Type: application/json, text/json
[
{
"receiverId": "abcdef",
"groupId": "abcdef",
"content": [
{"type":0,"data":"文本消息内容"},
{"type":1,"data":"被@用户ID","info":"被@用户昵称"},
{"type":2,"data":"图片文件ID","info":"pic","mediaInfo":"图片文件信息"},
{"type":3,"data":"语音文件ID","info":"语音文件格式","size":"语音文件大小","md5":"语音文件md5值"},
{"type":4,"data":"微笑","info":"face"}
],
"msgType": 0,
"masterId": "SampleString4",
"msgId": "SampleString5",
"timestamp": 1559032351,
"status": 7,
"errorMsg": "SampleString8"
},
{
"receiverId": "abcdef123123",
"groupId": "abcdef22",
"content": [
{"type":0,"data":"文本消息内容"},
{"type":1,"data":"被@用户ID","info":"被@用户昵称"},
{"type":2,"data":"图片文件ID","info":"pic","mediaInfo":"图片文件信息"},
{"type":3,"data":"语音文件ID","info":"语音文件格式","size":"语音文件大小","md5":"语音文件md5值"},
{"type":4,"data":"微笑","info":"face"}
],
"msgType": 0,
"masterId": "SampleString4",
"msgId": "demoMsgId",
"timestamp": 1559032351,
"status": 7,
"errorMsg": "SampleString8"
}
]
该接口支持同时向多个群回复消息,用于减少接口交互,提升发消息效率。
此接口为批量接口,body 为 json数组,数组的每一项为一条消息。
消息内容各个字段含义:
字段名 | 是否必填 | 字段含义 |
---|---|---|
receiverId | 是 | 消息要发送到的用户Id,值取自QQ聊天机器人富媒体消息中的senderId |
groupId | 群消息必填 | 消息要发送到的群Id,值取自QQ聊天机器人富媒体消息中的groupId |
content | 是 | 消息内容,参考聊天协议描述 |
msgType | 是 | 0 为群消息,1 为c2c消息 |
masterId | 是 | 机器人平台内部使用字段,值取自QQ聊天机器人富媒体消息中的masterId |
msgId | 是 | 消息的id,值取自QQ聊天机器人富媒体消息中的msgId |
timestamp | 是 | 消息的触发时间,值取自QQ聊天机器人富媒体消息中的timestamp |
status | 否 | |
errorMsg | 否 |
200 Created; 400 Bad Request;
消息类型中,type=2 和 type=3 为富媒体消息,需要先调用下述QQ聊天机器人富媒体消息接口上传文件,才能够发消息。 富媒体文件上传到QQ平台后,有有效期,如果资源过期,会有包体提示:
Content-Type: application/json, text/json
[
{
"errorCode": "-5103059",
"msgId": "abcd"
},
{
"errorCode": "-5103059",
"msgId": "efgh"
}
]
当前支持图片、语音富文本消息,以及图文混排消息 等富媒体消息。和普通文本消息相比,机器人发送富文本消息之前需要先将文件上传到 QQ 后台(步骤4),获取到文件存储在 QQ 后台的相关信息(如mediaid 和 mediainfo,步骤5),然后再把文件相关信息和文本消息一起推送给 QQ 接口(步骤6)。 文件 md5 和 mediaid、mediainfo 三元组构成文件在 QQ 后台内部的唯一标识,有效期是7天,其中图片三元组数据可重复使用的最大次数为200(语音无次数限制)。第三方可以缓存该三元组数据,提高机器人响应用户的速度和节约流量。
QQ接收到富文本消息之后会校验文件 md5 和 mediaid、mediainfo 三元组信息。如果校验失败(失效或者不可重复使用)QQ将在回包里以错误码形式告知机器人(步骤7),机器人可以对这种情况进行柔性处理,比如改为下发文本消息(步骤8)。
接入方统一使用该方法进行签名验证,假设目前有如下参数
参数 | 类型 | 值 | 说明 |
---|---|---|---|
appid | uint32 | 2222222 | 申请到的appid |
ts | uint32 | 1465185768 | 请求时间 |
nonce | uint32 | 562341234 | 随机正整数 |
json | {"xxxx": 123} | post body,没有参数名,这里直接对于 post body 后续直接称为 body |
首先对所有请求参数按参数名的字典序( ASCII 码)升序排序
注意:
1)只按参数名进行排序,参数值保持对应即可,不参与比大小;
2)按 ASCII 码比大小,如 InstanceIds.2 要排在 InstanceIds.12 后面,不是按字母表,也不是按数值。
用户可以借助编程语言中的相关排序函数来实现这一功能,如 php 中的 ksort 函数。
上述示例参数的排序结果如下:
'appid' : 2222222
'nonce' : 562341234,
'ts' : 1465185768
此步骤生成请求字符串。 将把上一步排序好的请求参数格式化成“参数名称”=“参数值”的形式
注意:“参数名称“和“参数值”为原始值而非url编码后的值。
然后将格式化后的各个参数用"&"拼接在一起。
最终生成的请求字符串为:
appid=2222222&nonce=562341234&ts=1465185768
此步骤生成签名原文字符串。 签名原文字符串由以下几个参数构成:
请求方法: 支持 POST 和 GET 方式,样例使用 POST 请求,注意方法为全大写。
请求主机: 根据实际请求的域名填写
接口域名:app.qun.qq.com
请求路径:/robotapi/msg_reply/v2
请求字符串: 即上一步生成的请求字符串
请求body: post 请求的时候,发出的包体原文(如果是上传文件等操作,则不需要拼接body)
签名原文串的拼接规则为:
请求方法 + 请求域名 + 请求路径 + ? + 请求字符串 + 请求body
示例的拼接结果为:
POSTapp.qun.qq.com/robotapi/msg_reply/v2?appid=2222222&nonce=562341234&ts=1465185768&{"xxxx": 123}
此步骤生成签名串。 首先使用 HMAC-SHA1 算法对上一步中获得的签名原文字符串进行签名,然后将生成的签名串使用 Base64 进行编码,即可获得最终的签名串。
具体代码如下,以 PHP 语言为例:
$appkey = 'fakeAppkey';
$srcStr = 'POSTapp.qun.qq.com/robotapi/msg_reply/v2?appid=2222222&nonce=562341234&ts=1465185768&{"xxxx": 123}';
$signStr = base64_encode(hash_hmac('sha1', $srcStr, $appkey, true));
echo $signStr;
最终得到的签名串为:
whXBY/0lXFDtYGj0FvTTjem0tlw=
使用其它程序设计语言开发时,可用上面示例中的原文进行签名验证,得到的签名串与例子中的一致即可。
生成的签名串并不能直接作为请求参数,需要对其进行 URL 编码。
非 ASCII 字符在 URL 编码前需要先以 UTF-8 进行编码。
如上一步生成的签名串为:
whXBY/0lXFDtYGj0FvTTjem0tlw=
经过 urlencode 之后,最终得到的签名串请求参数(SIGNTURE)为:
whXBY%2F0lXFDtYGj0FvTTjem0tlw%3D
注意:有些编程语言的 http 库会自动为所有参数进行 urlencode ,在这种情况下,就不需要对签名串进行 URL 编码了,否则两次 URL 编码会导致签名失败。
参数 | 类型 | 说明 |
---|---|---|
ts | uint32 | 请求时间 |
sig | string | 请求包签名,不同场景生成方式不同 |
appid | uint32 | 申请到的appid |
参数 | 类型 | 说明 |
---|---|---|
msgType | uint32 | 1为C2C消息 |
senderId | string | QQ用户ID |
senderNickname | string | QQ用户昵称 |
location | 复合类型 | 经纬度 |
type | uint32 | 消息内容类型,取值参考下面表格 |
data | string | 消息内容 |
info | string | 消息内容扩展 |
md5 | string | 文件md5值 |
size | uint32 | 文件大小 |
duration | uint32 | 语音时长 |
msgId | string | QQ生成,机器人不需要理解;机器人推消息给QQ时带上 |
masterId | string | QQ生成,机器人不需要理解;机器人推消息给QQ时带上 |
mediaId | string | 文件标识 |
mediaInfo | string | 文件信息 |
thirdTopicId | int | 第三方在设置页面设置保存的会话主题ID,用于识别群的会话主题,进行处理,有总量限制,需要特殊申请 |
根据 type 不同,data 与 info 的含义不同,具体如下:
type | data | info | 备注 |
---|---|---|---|
0 | "文本消息内容" | 无 | |
1 | "被@的QQ用户ID" | "被@用户昵称" | |
2 | "图片文件mediaid" | "pic" | |
3 | "语音文件mediaid" | "silk" | |
4 | "QQ系统表情文字" | "face" | |
15 | 视频消息 | 上传后返回的videoId | 无 |
已支持长消息
POST
https://app.qun.qq.com/robotapi/media_upload/v2?ts=xx&info=silk&size=1234&md5=abc&msgid=aaa&duration=123&appid=1&sig=abcd
https://app.qun.qq.com/robotapi/media_upload/v2?ts=xx&info=silk&size=1234&md5=abc&c2c=1&duration=123&appid=1&sig=abcd
语音文件上传QQ请求参数sig只计算url参数,不计算文件本身
语音仅支持silk格式
https://app.qun.qq.com/robotapi/media_upload/v2?ts=xx&info=pic&size=1234&md5=abc&msgid=aaa&appid=1&sig=abcd
https://app.qun.qq.com/robotapi/media_upload/v2?ts=xx&info=pic&size=1234&md5=abc&c2c=1&appid=1&sig=abcd
图片文件上传QQ请求参数sig只计算url参数,不计算文件本身
图片支持jpg,png,gif格式
请求包 Content-Type: multipart/form-data
,图片和语音文件的form-data字段名为file
[
"Multipart格式保存二进制数据"
]
Content-Type: application/json, text/json
{
"mediaId": "abcd",
"md5": "abcd",
"size": "123",
"msgid": "abcd",
"mediaInfo": "abcd"
}
获取到的相关信息,可以用于在发送消息的接口中,发送富媒体消息。
GET
https://app.qun.qq.com/robotapi/media_download/v2?msgid=abc&mediaid=abcd&md5=abc&size=123&info=abc&ts=xxx&appid=123&nonce=123&sig=abcd
[
"图片/音频等二进制数据"
]
注: 语音下载,对于60秒以内的语音,如果语音转文本成功,会在http 回包的header中增加key value的param: metadata:{"srResult":"url base64编码的utf8语音识别结果"}, srResult值: utf8编码的中英文识别结果,再通过url base64编码得到的字符串(http 标准中的header并没有明确支持汉字,所以通过url base64编码)