# 在线系统
# 消息接口
七鱼消息接口向开发者服务器提供了与七鱼服务器交互的接口,通过消息接口,开发者服务器可以自己控制访客与客服的交互行为。关于消息接口调用方式的参考代码以及将微信消息转发到七鱼的快捷方式,可参考github (opens new window)。
注:现阶段,该功能只针对专业版及以上企业开放,具体后台模块位置如下图:
AppKey和AppSecret是调用接口的两个必要参数,在首次进入该界面时会看到AppSecret为空,点击“重置”后会第一次生成,之后再次重置即为更换。
# 调用流程
下面是一次完整的访客咨询客服的调用时序图:
正常流程说明:
- 发送消息:用户发送消息给应用服务器,触发请求分配客服的动作。除了发送消息触发外,应用服务器也可以使用指定命令来触发分配。例如在微信公众号中,添加一个单独的客服菜单,用户点击后触发分配客服,只有点击过这个菜单后,用户消息才转到七鱼客服。
- 应用服务器向七鱼服务器请求分配客服。请求中必须带上用户的ID,以标致来自于哪个用户。除此之外,还可以带上指定的客服分组ID,客服ID等参数。
- 七鱼服务器根据请求参数分配空闲的客服。分配成功后,服务器会生成一个新会话,然后通知客服有访客进入。
- 七鱼服务器将分配结果返回给应用服务器。建议应用服务器将会话状态缓存下来,当用户在继续说话时,应用服务器查询到用户已经在会话中了,只需要将消息转给七鱼服务器即可,无需再次请求分配客服。
- 更新用户的最新资料,可以包括用户的昵称,电话,邮件等基础信息,还可以包含用户的最近订单,最新状态等扩展信息。更新用户资料接口可以随时调用,调用后立即生效,客服可以马上看到。
- 将新的用户资料通知给客服,显示在会话窗口的右上角。
- 应用服务器将用户消息传到七鱼服务器。
- 用户消息传递给客服。
- 客服回复消息。
- 七鱼服务器将客服消息传到应用服务器。
- 应用服务器将消息回复给用户。
- 用户咨询完毕,客服主动关闭会话,或者用户长时间没有回答,系统判断超时自动关闭后,会话结束。
- 七鱼服务器通知应用服务器会话结束。如果应用服务器缓存了会话信息,可在此时移除相关缓存。
- 如果需要告知用户会话已经结束,或者需要邀请用户对客服服务进行评价,可进行此步骤。
- 用户对服务进行评价。除了会话结束时,在会话过程中任意时候,用户其实都可以进行评价。
- 应用服务器将用户评价结果告诉七鱼服务器。
异常流程说明:
- 用户发送消息后,如果应用服务器不经过请求分配客服,就直接将消息转到七鱼服务器,七鱼服务器将自动触发客服分配流程。如果企业开通了机器人服务,且用户为第一次访问,则将自动分配给机器人,由机器人自动回复;若用户之前已经有人工接待过,则将继续分配给之前的客服。
- 请求分配的客服不在线时,将返回14005,并附上在后台设置客服不在线提示文案。此时消息仍然可以继续转发到七鱼服务器,这些消息将进入留言列表,等客服上线后,可以从留言列表中重新发起会话,进行回复。进入留言后,如果超过5分钟用户都没有再发送消息,这条留言就会关闭,这时客服才能在留言列表中看到。当用户再次发消息时,将重新触发客服分配的流程。
- 如果请求分配的客服接待的访客已经达到上限,将返回14006,表示访客需要排队。应用服务器可以通过查询排队状态的接口查看当前队列中有多少人,并反馈给用户。
# 调用说明
- 所有接口都只支持POST请求;
- 除上传文件外,其他所有接口请求Content-Type类型为:application/json;charset=utf-8;
- 所有接口返回类型为JSON,同时进行UTF-8编码。
# 数据校验
参考通用说明-数据校验 (opens new window)
# 设置接收事件地址
除了向七鱼服务器发送消息和请求,七鱼也会向开发者服务器推送一些消息和事件。目前会推送以下事件:
- 客服发送的消息。
- 会话开始通知。此事件只有通过发消息触发分配客服时才会发送。
- 会话结束通知。
为了接收这些事件通知,开发者需要在管理后台->系统->扩展与集成->开发者ID->消息与事件接收url 设置接收的 url。
请注意:
- 接收到所有通知事件后,请在 10s 内返回一个空字符串。超过 10 s没有返回或者返回字符串非空,七鱼服务器将会认为请求发送失败,并进入重发。
- 如果是普通消息,请使用 msgId 字段做去重。
- 所有请求的内容都是 json 格式字符串,为了避免消息泄露,保护用户隐私,强烈建议用于接收通知的 url 使用 https 协议。
# 常见错误码
错误码 | 说明 |
---|---|
14001 | appKey 不正确 |
14002 | checksum 校验出错 |
14003 | 传递的 time 参数不正确 |
14004 | 内容格式不是json,或者缺乏必备的字段,或者参数不正确 |
14005 | 没有客服在线 |
14006 | 用户需要排队 |
14007 | 用户没有请求过客服 |
14008 | IP 被禁或不在白名单中 |
14009 | 接口调用太频繁,请等会再试 |
14010 | 没有客服在线,且留言功能是关闭的 |
14011 | 没有调用该接口的权限 |
14500 | 服务器内部错误 |
14515 | 没有权限 |
14301 | 参数错误 |
14500 | 系统错误 |
14200 | 参数类型不支持 |
# 消息收发
使用消息接口的方式接入七鱼客服时,如果用户需要联系客服,则先将消息发送到开发者服务器,然后在用应用服务器发送到七鱼的服务器,有七鱼服务器再发送给对应的客服。客服回复消息后,消息先走到七鱼的服务器,然后由七鱼服务器发送给在管理后台填写的事件接收 url 上,最后再发给用户。
# 给七鱼发送消息
目前仅支持开发者服务器替用户向客服发送消息。
发送消息时,如果用户尚未分配过客服,该消息将自动转给机器人,由机器人回答。如果需要发送消息给人工客服,可以先调用 请求分配客服,等分配到一个客服后再发送消息。
为了防止因网络延时造成的错误,如果用户在上一次会话结束后的10秒内又发了消息,这条消息将会自动发给上一个会话的客服。
POST 请求为:
POST https://qiyukf.com/openapi/message/send?appKey=1064deea1c3624c9ee26d1de5ce8481f&time=1463216914&checksum=e72be4487b6fc03e0f914fc11e4053d771598d93
Content-Type:application/json;charset=utf-8
请求内容示例如下:
文本消息:
{
"uid":"user1",
"msgType":"TEXT",
"content":"七鱼,你好。"
}
图片消息:
{
"uid":"user1",
"msgType":"PICTURE",
"content":
{
"url": "http://url_of_image",
"size": 10000,
"md5": "xxxx",
"w": 200,
"h":200
}
}
语音消息:
{
"uid":"user1",
"msgType":"AUDIO",
"content":
{
"url": "http://url_of_audio",
"size": 10000,
"dur": 10000,
"md5": "xxxx"
}
}
参数 | 是否必须 | 参数说明 |
---|---|---|
uid | 是 | 开发者的应用里的用户ID。 |
msgType | 是 | 消息类型。(目前仅支持 TEXT, PICTURE, AUDIO 三种,分别是文本,图片和语音消息)。 |
content | 是 | 消息内容。文本消息是文本内容,图片和语音消息则是描述的 json, 该字段长度限制最大为 4000 个字符。 |
url | 是 | 图片,语音消息的文件 url。请保证该 url 不会存在跨域访问问题。 如果不能跨域访问,请使用下面的文件上传接口将文件上传到七鱼服务器,然后使用返回的 url。 |
size | 是 | 文件大小,单位为 byte。 |
md5 | 是 | 文件内容的 MD5。 |
w | 否 | 图片消息中图片的宽度,正确传递该值可以提升客服的浏览体验。 |
h | 否 | 图片消息中图片的高度,正确传递该值可以提升客服的浏览体验。 |
dur | 是 | 语音消息中语音的持续时间,单位为 毫秒。 |
一触即达流程消息:
{
"uid":"user1",
"msgType":"WORKFLOW",
"content":"{\"target\":\"6C0810BC0CCD635B-9ca9cffd531346c9\",\"params\":\"_preRequestId=faa9cb89-5c54-49ca-870c-c7a0c86e00c9&_sessionId=xxxx&_preNodeId=6C0810BC0CCD635B-836c57f5fe04fe65&_token=e203c94c07ee10aed8f257a1384e1694&_flowId=6C0810BC0CCD635B-BF906E4977A35884\",\"templateId\":\"qiyu_template_text\",\"template\":{\"label\":\"测试消息\",\"id\":\"qiyu_template_text\"},\"cmd\":202}"
}
参数 | 是否必须 | 参数说明 |
---|---|---|
uid | 是 | 开发者的应用里的用户ID。 |
msgType | 是 | 消息类型。(WORKFLOW,一触即达流程消息)。 |
params | 是 | 节点参数,取系统返回的数据 |
target | 是 | 节点跳转的目标节点id,取系统返回的数据 |
templateId | 是 | 样式模版id,可取值范围:qiyu_template_text、drawer_list、bubble_list、qiyu_template_item |
template | 是 | 模版数据 |
cmd | 是 | 模版发送的命令,固定值202,卡片列表加载更多则为205 |
template数据格式由templateId决定,格式对应如下:
- templateId:qiyu_template_text文本模版
字段 | 类型 | 注释 |
---|---|---|
label | string | 文本文案,取系统返回数据 |
- templateId:qiyu_template_item卡片模版详情
字段 | 类型 | 注释 |
---|---|---|
p_attr_1 | string | 卡片属性1,取系统返回数据 |
p_attr_2 | string | 卡片属性2,取系统返回数据 |
p_attr_3 | string | 卡片属性3,取系统返回数据 |
p_img | string | 卡片图片,取系统返回数据 |
p_title | string | 卡片标题,取系统返回数据 |
p_sub_title | string | 卡片子标题,取系统返回数据 |
- templateId:drawer_list、bubble_list卡片列表加载更多
此时template传空即可。
卡片消息
目前只有新版访客端支持发送卡片消息,老版访客端不支持卡片消息。
请求参数
参数 | 是否必须 | 参数说明 |
---|---|---|
uid | 是 | 开发者的应用里的用户ID。 |
msgType | 是 | 消息类型。(CARD_MSG,卡片消息)。 |
content | 是 | 消息内容。 |
content字段object结构
参数 | 是否必须 | 参数说明 |
---|---|---|
cards | 是 | 卡片消息内容 |
floatCards | 否 | 浮动卡片消息内容 |
请求示例:
{
"uid": "user1",
"msgType": "CARD_MSG",
"content": {
"cards": [
{
"type": "title",
"content": "这个是标题组件。",
"img": "https://qiyukf.com/docs/logo.png",
"url": "https://www.qiyukf.com",
"style": {
"divider": 1,
"fontSize": 20,
"fontColor": "#ff00aa"
}
},
{
"type": "rich",
"content": "<p style=\"color: red; font-size: 36px;\">红色、36px字号的文本。--- 这个是富文本。</p>",
"style": {
"divider": 1,
"pt": "20",
"pb": "20",
"pl": "20",
"pr": "20"
}
}
],
"floatCards": [
{
"type": "product",
"data": [
{
"id": 18379874912,
"picture": "https://qiyukf.com/docs/logo.png",
"desc": "商品描述",
"title": "标题",
"price": "¥999",
"url": "https://www.qiyukf.com",
"action": 0
}
],
"style": {
"divider": 1
}
},
{
"type": "button",
"numInRow": 2,
"data": [
{
"title": "按钮0",
"action": 0,
"url": "https://www.qiyukf.com"
},
{
"title": "按钮1",
"action": 0,
"url": "https://qiyukf.com/docs"
}
],
"style": {
"divider": 1,
"backgroundColor": "#222222",
"fontSize": 33,
"fontColor": "#222222"
}
}
]
}
}
卡片消息【cards】支持所有的9种类型卡片,分别是:标题类型、富文本类型、副标题类型、图片类型、节点流程类型、商品类型、订单类型、按钮类型、跳转链接类型。一条卡片消息可以包含多种类型的模板组合。
悬浮卡片消息【floatCards】只支持商品类型和按钮类型。
9种类型卡片的消息格式定义请见 - 自定义卡片消息(new)
响应示例如下:
{
"code": 200
}
响应参数说明如下:
参数 | 参数说明 |
---|---|
code | 错误码。200表示发送成功。 |
# 给访客发送消息
用于开发者服务器替客服向访客发送消息,目前仅支持会话中的人工会话和机器人会话。 当访客处于会话中的人工会话或机器人会话中时,可调用此接口发送客服消息给访客,并记录到会话中。 目前支持两种消息格式的内容推送:纯文本、图片。
POST 请求为:
POST https://qiyukf.com/openapi/message/staff/send?appKey=1064deea1c3624c9ee26d1de5ce8481f&time=1463216914&checksum=e72be4487b6fc03e0f914fc11e4053d771598d93
Content-Type:application/json;charset=utf-8
请求内容示例如下:
文本消息:
{
"uid":"user1",
"sessionId":"1234567",
"msgType":"TEXT",
"content":"七鱼,你好。"
}
图片消息:
{
"uid":"user1",
"msgType":"PICTURE",
"sessionId":"1234567",
"content":
{
"url": "http://url_of_image",
"size": 10000,
"md5": "xxxx",
"w": 200,
"h":200
}
}
参数 | 是否必须 | 参数说明 |
---|---|---|
uid | 是 | 开发者的应用里的用户ID。 |
sessionId | 是 | 用户对应的会话id |
msgType | 是 | 消息类型。(目前仅支持 TEXT, PICTURE两种,分别是文本,图片)。 |
content | 是 | 消息内容。文本消息是文本内容,图片和语音消息则是描述的 json, 该字段长度限制最大为 4000 个字符。 |
url | 是 | 图片,语音消息的文件 url。请保证该 url 不会存在跨域访问问题。 如果不能跨域访问,请使用下面的文件上传接口将文件上传到七鱼服务器,然后使用返回的 url。 |
size | 是 | 文件大小,单位为 byte。 |
md5 | 是 | 文件内容的 MD5。 |
w | 否 | 图片消息中图片的宽度,正确传递该值可以提升客服的浏览体验。 |
h | 否 | 图片消息中图片的高度,正确传递该值可以提升客服的浏览体验。 |
卡片消息
目前只有新版访客端支持发送卡片消息,老版访客端不支持卡片消息。
请求参数
参数 | 是否必须 | 参数说明 |
---|---|---|
uid | 是 | 开发者的应用里的用户ID。 |
msgType | 是 | 消息类型。(CARD_MSG,卡片消息)。 |
content | 是 | 消息内容。 |
content字段object结构
参数 | 是否必须 | 参数说明 |
---|---|---|
cards | 是 | 卡片消息内容 |
floatCards | 否 | 浮动卡片消息内容 |
请求示例:
{
"uid": "user1",
"msgType": "CARD_MSG",
"content": {
"cards": [
{
"type": "title",
"content": "这个是标题组件。",
"img": "https://qiyukf.com/docs/logo.png",
"url": "https://www.qiyukf.com",
"style": {
"divider": 1,
"fontSize": 20,
"fontColor": "#ff00aa"
}
},
{
"type": "rich",
"content": "<p style=\"color: red; font-size: 36px;\">红色、36px字号的文本。--- 这个是富文本。</p>",
"style": {
"divider": 1,
"pt": "20",
"pb": "20",
"pl": "20",
"pr": "20"
}
}
],
"floatCards": [
{
"type": "product",
"data": [
{
"id": 18379874912,
"picture": "https://qiyukf.com/docs/logo.png",
"desc": "商品描述",
"title": "标题",
"price": "¥999",
"url": "https://www.qiyukf.com",
"action": 0
}
],
"style": {
"divider": 1
}
},
{
"type": "button",
"numInRow": 2,
"data": [
{
"title": "按钮0",
"action": 0,
"url": "https://www.qiyukf.com"
},
{
"title": "按钮1",
"action": 0,
"url": "https://qiyukf.com/docs"
}
],
"style": {
"divider": 1,
"backgroundColor": "#222222",
"fontSize": 33,
"fontColor": "#222222"
}
}
]
}
}
卡片消息【cards】支持所有的9种类型卡片,分别是:标题类型、富文本类型、副标题类型、图片类型、节点流程类型、商品类型、订单类型、按钮类型、跳转链接类型。一条卡片消息可以包含多种类型的模板组合。
悬浮卡片消息【floatCards】只支持商品类型和按钮类型。
9种类型卡片的消息格式定义请见 - 自定义卡片消息(new)
{
"code": 200
}
响应参数说明如下:
参数 | 参数说明 |
---|---|
code | 错误码。200表示发送成功。 |
# 接收七鱼消息
当客服(人工或者机器人)回复消息后,七鱼平台会把消息推送给开发者。推送地址是开发者在七鱼管理后台->系统->扩展与集成->开发者ID处,填写的消息与事件接收URL。
收到的POST请求如下:
POST https://QIYU_MSG_URL?eventType=MSG&time=1463217187&checksum=2f13932c4b7c6888b12360a85261a11b8b543f64
Content-Type:application/json;charset=utf-8
请求内容示例为:
{
"uid":"user1",
"content":"2222",
"staffId":143,
"timeStamp":1463216914316,
"staffName":"lantian",
"msgId":"8ca1c9fb30c40aa6cc390844e2756fac",
"msgType":"TEXT"
}
除了和发送接口相同的参数外,其他参数说明如下:
参数 | 参数说明 |
---|---|
timeStamp | 消息时间戳,从 1970 年 1 月 1 日 0 点 0 分 0 秒开始到现在的毫秒数。 |
staffId | 发送该消息的客服ID。 |
staffName | 发送该消息的客服名字。 |
# 上传文件
我们提供了两种上传文件的方式,一种是 MultiPart 方式,一种是发送文件内容 base64 运算后的字符串的方式。 上传文件时,同样需要计算checksum,在这两种上传方式中,计算 checksum 的 md5 均为文件内容的 md5 的小写。 两种方式对于文件大小限制均为 5M。
MultiPart 方式
使用 MultiPart 方式上传的 POST 请求为:
POST https://qiyukf.com/openapi/message/uploadFile?appKey=1064deea1c3624c9ee26d1de5ce8481f&time=1463217187&checksum=2f13932c4b7c6888b12360a85261a11b8b543f64
Content-Type:multipart/form-data;charset=ISO-8859-1
构造 POST 请求 body 的 java 示例代码如下:
try {
HttpPost post = new HttpPost(url);
MultipartEntityBuilder builder = MultipartEntityBuilder.cr
builder.setMode(HttpMultipartMode.BROWSER_COMPA
FileBody fileBody = new FileBody(new File(path)); // 构造 FileBody
builder.addPart("file", fileBody); // 这里 key 必须是 file
post.setEntity(builder.build());
CloseableHttpResponse response = HttpClients.custom().build().execute(post);
// check response
} catch (IOException e) {
e.printStackTrace();
}
返回的响应内容为:
{
"code": 200,
"url": "url_of_file"
}
响应参数说明如下:
参数 | 参数说明 |
---|---|
code | 错误码。200表示上传成功。 |
url | 该文件的下载地址。 |
base64 方式
使用 base64 方式上传的 POST 请求为:
POST https://qiyukf.com/openapi/message/sendFile?appKey=1064deea1c3624c9ee26d1de5ce8481f&time=1463217187&checksum=2f13932c4b7c6888b12360a85261a11b8b543f64
Content-Type:text/plain;charset=ISO-8859-1
POST 请求内容为文件内容的 base64 编码字符串,构造 POST 请求 body 的 java 示例代码如下:
try {
HttpPost post = new HttpPost(url);
String content = base64(new File(path));
post.setEntity(new StringEntity(content, ContentType.TEXT_PLAIN));
CloseableHttpResponse response = client().execute(post);
InputStream is = response.getEntity().getContent();
System.out.print(isToString(is));
is.close();
} catch (IOException e) {
e.printStackTrace();
}
返回的响应内容为:
{
"code": 200,
"url": "url_of_file"
}
响应参数说明如下:
参数 | 参数说明 |
---|---|
code | 错误码。200表示上传成功。 |
url | 该文件的下载地址。 |
# 未读消息查询接口
查询最近72小时未读消息数,请求频率限制:1次/每秒
POST 请求为:
POST https://qiyukf.com/openapi/message/getUnread?appKey=1064deea1c3624c9ee26d1de5ce8481f&time=1463217187&checksum=2f13932c4b7c6888b12360a85261a11b8b543f64
Content-Type:application/json;charset=utf-8
构造 POST 请求 body 的 java 示例代码如下:
{
"foreignId":"qwewedsd"
}
返回的响应内容为:
{
"code": 200,
"message": "success",
"data": {
"count": 3,
"lastMessage": {
"content": "33",
"msgIdClient": "8324731945#9685e63b3a02df1cae6777996a48f3ef",
"sessionStartTime": 1697539905316,
"time": 1697539964122,
"type": "text"
}
}
}
响应参数说明如下:
参数 | 参数说明 |
---|---|
code | 错误码。200表示成功。 |
message | 错误提示信息。 |
count | 未读消息数。 |
lastMessage | 最后一条消息的json数据。 |
content | 消息体内容。 |
msgIdClient | 消息id。 |
sessionStartTime | 会话开始时间。 |
time | 消息发送时间。 |
type | 消息类型。 |
# 事件
# 请求分配客服
POST 请求为:
POST https://qiyukf.com/openapi/event/applyStaff?appKey=1064deea1c3624c9ee26d1de5ce8481f&time=1463217187&checksum=2f13932c4b7c6888b12360a85261a11b8b543f64
Content-Type:application/json;charset=utf-8
请求内容示例如下:
{
"uid": "user1",
"fromPage": "www.163.com",
"fromTitle": "Netease",
"fromIp": "220.220.2.1",
"deviceType": "Android#xiaomi#5.0",
"productId": "Android package name",
"staffType": 1,
"staffId": 0,
"groupId": 0,
"robotShuntSwitch":0,
"level":0,
"robotId":22
}
请求参数说明如下:
参数 | 是否必须 | 参数说明 |
---|---|---|
uid | 是 | 开发者的应用里的用户 ID。 |
fromPage | 否 | 用户发起咨询客服操作的页面 url,比如商品链接,订单页面等。 |
fromTitle | 否 | fromPage 页面的标题。 |
deviceType | 否 | 用户设备类型信息。 |
productId | 否 | 产品标识,可以是 Android 应用的包名,iOS 应用的 bundleid 等。 |
staffType | 否 | 请求分配的客服类型,如果传0,表示机器人,传1表示人工。默认为机器人。 |
staffId | 否 | 只请求该 ID 的客服,客服 ID 可在管理后台查看。 |
groupId | 否 | 只请求该客服分组 ID 内的客服,分组 ID 可在管理后台查看。 |
robotShuntSwitch | 否 | 申请人工客服之前是否先申请机器人开关,0代表关闭,1代表启用。 |
level | 否 | 该访客这次会话的vip等级,从0到11 |
robotId | 否 | 有多个机器人时,指定接入某一个机器人。 |
分配客服的逻辑如下,按照优先级从高到低匹配:
- 如果指定了客服 ID(staffId),则忽略 staffType 和 groupId 两个参数, 只会分配到该客服,如果这个客服不在线,则返回客服不在线,如果该客服已排满,则返回需要排队。如果当前用户已经有另外一个客服在服务,则会先关闭与前一个客服的会话。
- 如果指定了客服分组 ID(groupId), 则忽略 staffType 这个参数,只会分配到该分组内的客服,如果该分组内没有客服在线,则返回客服不在线,如果该分组内客服已排满,则返回需要排队。如果当前用户已经有另外一个分组内的客服在服务,则先回关闭与前一个客服的会话。
- 如果指定了客服类型(staffType),如果用户当前已经有客服在服务中,且 staffType 为 0 或者没有传 staffType,则直接返回该会话客服。否则,如果该参数为 0 或者没有传递,则会返回机器人会话,如果该参数为1,且robotShuntSwitch参数为1,则在申请人工客服之前先申请机器人客服,转人工后再申请人工客服,若robotShuntSwitch为0或不传则直接申请人工客服,在所有在线客服中分配一个空闲客服,如果没有客服在线,则返回客服不在线,如果所有客服都已经排满,则会返回需要排队。
- 如果指定了robotId,那么当需要生成机器人会话时,会进入到该robotId对应的机器人中。多机器人配置详见 机器人 -> 机器人列表
- 如果返回客服不在线,服务将自动进入留言模式,用户发送的消息将会保存在留言中,留言过程中,如果客服上线了,将自动转人工客服。
- 如果用户处于机器人服务状态,想要切换为人工服务,将staffType置为1重新调用一遍该接口即可,也可以带上指定的客服或客服分组参数。
- 如果用户处于有客服服务状态,想切换为其他客服,带上想要切换的客服或者客服分组,重新调用一遍该接口即可。
响应示例如下:
{
"code": 200,
"staffId": 1234,
"message": "哈哈",
"count":0,
"sessionId": 62927,
"staffName": "lantian",
"staffType": 0,
"staffIcon": "https://ysf.nosdn.127.net/29C25737ABC2524667D223A90FEF156D",
"evaluationModel": {
"title": "模型一",
"note": "二级评价模型",
"type": 2,
"list": [
{
"name": "满意",
"value": 100
},
{
"name": "不满意",
"value": 1
}
]
}
}
响应参数说明如下:
参数 | 参数说明 |
---|---|
code | 错误码。200表示分配到客服,14005:没有客服在线,14006:需要排队,14010:没有客服在线,且留言功能已关闭。 |
message | 如果分配到客服,此字段是客服的欢迎语,如果没有分配到客服,则是错误提示信息。 |
count | 仅返回需要排队时该参数有效,表明排队队列中排在你前面你的人数。如果为0,则表示你排在队列最前面。 |
sessionId | 会话 ID,后续对会话评价时有用。仅返回分配到客服时该参数有效。 |
staffId | 客服 ID。 |
staffName | 客服名字。 |
staffType | 客服类型,0 表示机器人,1 表示人工会话。 |
staffIcon | 客服头像的 url。 |
evaluationModel | 满意度评价模型,在申请到人工客服时有值,后面根据该模型 value 值进行客服评价。 |
rich_text_greet | 如果设置富文本作为机器人或者人工的欢迎语,这个字段会带上原始的html格式富文本,原message中保留提取出来的纯文本。 |
# 接收会话开始通知
当客服主动发起和客户进入时,或者由其他会话转接时,开发者服务器会收到此通知。目前只有人工会话会收到通知,机器人会话开始不会发送通知。此事件通知仅在OpenApi渠道下的会话生效。
开发者服务器收到的POST请求如下:
POST https://QIYU_MSG_URL?eventType=SESSION_START&time=1463217187&checksum=2f13932c4b7c6888b12360a85261a11b8b543f64
Content-Type:application/json;charset=utf-8
请求内容示例如下:
{
"code": 200,
"staffId": 1234,
"message": "哈哈",
"sessionId": 62927,
"staffName": "lantian",
"staffType": 0,
"staffIcon": "https://ysf.nosdn.127.net/29C25737ABC2524667D223A90FEF156D",
"uid": "user1",
"evaluationModel": {
"title": "模型一",
"note": "二级评价模型",
"type": 2,
"list": [
{
"name": "满意",
"value": 100
},
{
"name": "不满意",
"value": 1
}
]
},
"transferFrom": 62917
}
响应参数中各个 key 意义与分配客服的响应参数相同,其中不同的一个参数意义如下:
参数 | 参数说明 |
---|---|
transferFrom | 如果会话是被转接过来的,会有该字段,值为发起转接的那次会话的ID。 |
# 接收会话结束通知
会话结束后,开发者服务器会收到此通知。此事件通知仅在OpenApi渠道下的会话生效。
开发者服务器收到的POST请求如下:
POST https://QIYU_MSG_URL?eventType=SESSION_END&time=1463217187&checksum=2f13932c4b7c6888b12360a85261a11b8b543f64
Content-Type:application/json;charset=utf-8
请求内容示例如下:
{
"code": 200,
"staffId": 1234,
"message": "哈哈",
"sessionId": 62927,
"staffName": "lantian",
"staffType": 0,
"staffIcon": "https://ysf.nosdn.127.net/29C25737ABC2524667D223A90FEF156D",
"uid": "user1",
"closeReason":0,
"transferTo":62928
}
响应参数中各个 key 意义与分配客服的响应参数相同,另外两个不同的key值意义如下:
参数 | 参数说明 |
---|---|
closeReason | 会话关闭原因:0-客服关闭;1-访客离开页面失效关闭;2-访客离开超时关闭;3-访客申请其他客服关闭;4-网络差客服掉线关闭;5-客服转接关闭;6-管理员接管关闭;7-访客主动关闭;8-系统关闭,静默超时关闭;9-系统关闭,静默转接关闭;10-访客未说话;11-访客排队超时清队列;12-访客放弃排队;13-客服离线清队列;14-访客未选择分流入口;16-系统关闭会话;17-访客超时未填写询前表单;18-智能场控关闭排队会话;19-拉黑关闭会话;其他-机器人转人工;47-访客申请子企业客服关闭;49-访客申请主企业客服关闭。 |
transferTo | 如果会话是被转接出去了,会有该字段,值为转接到的会话ID。 |
# 接收客服主动邀评通知
为了提高用户参评率,七鱼为客服增加了主动邀请用户评价会话的入口。此事件通知仅在OpenApi渠道下的会话生效。对于使用消息接口的企业,此处相应的增加了一种事件类型通知,通知事件类型为:EVA_INVITATION
。
客服主动邀评后,开发者服务器会收到如下POST请求:
POST https://QIYU_MSG_URL?eventType=EVA_INVITATION&time=1463217187&checksum=2f13932c4b7c6888b12360a85261a11b8b543f64
Content-Type:application/json;charset=utf-8
请求内容示例如下:
{
"sessionId": 62927,
"staffId": 1234,
"staffName": "lantian",
"staffType": 0,
"staffIcon": "https://ysf.nosdn.127.net/29C25737ABC2524667D223A90FEF156D",
"uid": "user1"
}
响应参数中各个 key 意义与分配客服的响应参数相同。
# 接收用户进入排队通知
如果用户通过在机器人会话中直接发送rg请求人工客服转到排队,或者直接发送消息,也可能会触发进入人工,导致排队。通过处理这个通知,应用服务器可以更准确的知道用户当前的服务状态。 注意,如果是通过申请客服接口进入排队,不会触发这个通知。此事件通知仅在OpenApi渠道下的会话生效。 触发后,开发者服务器会收到如下POST请求:
POST https://QIYU_MSG_URL?eventType=USER_JOIN_QUEUE&time=1463217187&checksum=2f13932c4b7c6888b12360a85261a11b8b543f64
Content-Type:application/json;charset=utf-8
开发者收到的请求内容与申请客服返回排队状态时一致:
{
"code": 14006,
"message": "排队欢迎语",
"count":1,
"robotInQueue":1
}
其中,如果有 robotInQueue 这个参数,表示可以在排队时同时与机器人聊天。
# 接收用户离开排队通知
在用户离开排队,包括超时退出,主动退出时,开发者服务器会收到该通知。此事件通知仅在OpenApi渠道下的会话生效。
开发者服务器收到的POST请求示例如下:
POST https://QIYU_MSG_URL?eventType=QUEUE_TIMEOUT&time=1463217187&checksum=2f13932c4b7c6888b12360a85261a11b8b543f64
Content-Type:application/json;charset=utf-8
请求内容示例如下:
{
"uid":"user1"
}
# 客服组排队情况查询
该接口提供开放能力,企业可以根据客服组id查询该客服组是否有客服在线和是否需要排队。
POST请求为:
POST https://qiyukf.com/openapi/chat/queue/group/query?appKey=1064deea1c3624c9ee26d1de5ce8481f&time=1463216914&checksum=e72be4487b6fc03e0f914fc11e4053d771598d93
Content-Type:application/json;charset=utf-8
请求内容示例如下:
{
"groupId": 624001
}
请求参数说明如下:
参数 | 是否必须 | 参数说明 |
---|---|---|
groupId | 是 | 只请求该客服分组 ID 内的客服,分组 ID 可在管理后台查看。 |
响应示例如下:
{
"code":200,
"message":"",
"staffInfo":[
{
"id":12712411,
"realname":"李莉莉",
"maxServeCount":20,
"servingCount":10
},
{
"id":12712612,
"realname":"张磊",
"maxServeCount":15,
"servingCount":13
}
]
}
响应参数说明如下:
参数 | 数据类型 | 参数说明 |
---|---|---|
code | Integer | 错误码。200表示查询成功,14004表示客服组参数不正确或者客服组不存在。 |
message | String | 错误提示信息,当code错误码不为200时返回错误提示。 |
staffInfo.id | Long | 客服id。 |
staffInfo.realname | String | 客服姓名。 |
staffInfo.maxServeCount | Integer | 客服最大接待量。 |
staffInfo.servingCount | Integer | 客服当前接待量。 |
# 更新用户资料
使用该接口可以更新用户的详细资料,并展示在客服会话界面的右上侧「用户资料」tab页看到。具体的数据格式定义可参见轻量CRM对接参数说明。
POST 请求为:
POST https://qiyukf.com/openapi/event/updateUInfo?appKey=1064deea1c3624c9ee26d1de5ce8481f&time=1463217187&checksum=2f13932c4b7c6888b12360a85261a11b8b543f64
Content-Type:application/json;charset=utf-8
请求内容如下:
{
"uid": "user1",
"userinfo":
[
{"key":"real_name", "value":"土豪"},
{"key":"mobile_phone", "hidden":true, "value":"13800000000"},
{"key":"email", "value":"13800000000@163.com"},
{"index":0, "key":"account", "label":"账号", "value":"zhangsan" , "href":"http://example.domain/user/zhangsan"},
{"index":1, "key":"sex", "label":"性别", "value":"先生"},
{"index":5, "key":"reg_date", "label":"注册日期", "value":"2015-11-16"},
{"index":6, "key":"last_login", "label":"上次登录时间", "value":"2015-12-22 15:38:54"}
]
}
请求参数说明如下:
参数 | 是否必须 | 参数说明 |
---|---|---|
uid | 是 | 开发者的应用里的用户 ID。 |
userinfo | 是 | 用户资料描述,必须是一个 json 数组。 |
响应示例如下:
{
"code": 200
}
响应参数说明如下:
参数 | 参数说明 |
---|---|
code | 错误码。200表示设置成功。 |
# 获取评价设置
该接口由七鱼提供给第三方调用,用于第三方自己实现满意度评价功能并与七鱼系统进行对接的方式。满意度评价选项配置在七鱼管理后台设置,第三方可以通过该接口拉取该配置,并自己实现用户信息评价功能。评价完成之后,第三方调用下面用户评价接口将评价结果同步给七鱼系统。
POST请求为:
POST https://qiyukf.com/openapi/evaluation/setting/get?appKey=1064deea1c3624c9ee26d1de5ce8481f&time=1463217187&checksum=2f13932c4b7c6888b12360a85261a11b8b543f64
Content-Type:application/json;charset=utf-8
请求内容示例如下:
{
"fromType": "iOS"
}
请求参数说明如下:
参数 | 参数类型 | 参数说明 |
---|---|---|
fromType | String | 访客终端类型:iOS,android,WEB,wx[公众号],wx_ma[小程序],wb[微博] |
响应示例如下:
{
"list": [{
"name": "非常不满意",
"tagList": [],
"value": 1
}, {
"name": "不满意",
"tagList": [],
"value": 25
}, {
"name": "一般",
"tagList": [],
"value": 50
}, {
"name": "满意",
"tagList": [],
"value": 75
}, {
"name": "非常满意",
"tagList": ["幽默","热情"],
"value": 100
}],
"messageInvite": "感谢您的咨询,请对 ${客服名} 的服务做出评价",
"note": "五级评价模式",
"title": "模式三",
"type": 5
}
响应参数说明如下:
参数 | 数据类型 | 参数说明 |
---|---|---|
code | Integer | 错误码。200表示设置成功。 |
message | String | 错误提示信息 |
data | Json | 满意度配置信息 |
data.messageInvite | String | 满意度邀评文案 |
data.title | String | 评价模型名称 |
data.note | String | 评价模型备注 |
data.type | Int | 评价模型类别 |
data.list | List | 满意度评价选项 |
data.list.tagList | List | 评价选项对应可选择的标签 |
data.list.tagRequired | List | 标签是否必选 |
data.list.commentRequired | List | 备注是否必填 |
# 评价客服
该接口允许用户对当前评价当前客服服务的满意度,满意度评价模型数据 evaluationModel 在请求分配客服接口中返回。根据 evaluationModel 中的 list 数组显示满意度评价项,name 为评价项名称,value 为对应评价值,用户选择某评价项时,将对应 value 值作为下面接口参数 evaluation 的参数值。
POST 请求为:
POST https://qiyukf.com/openapi/event/evaluate?appKey=1064deea1c3624c9ee26d1de5ce8481f&time=1463217187&checksum=2f13932c4b7c6888b12360a85261a11b8b543f64
Content-Type:application/json;charset=utf-8
请求内容示例如下:
{
"uid":"user1",
"sessionId":62927,
"evaluation":100,
"evaluation_resolved": 1,
"remarks":"你的服务非常棒",
"tagList":["幽默","热情"]
}
请求参数说明如下:
参数 | 是否必须 | 参数说明 |
---|---|---|
uid | 是 | 开发者的应用里的用户 ID。 |
sessionId | 是 | 待评价的会话 ID。该会话 ID 可由分配客服的接口拿到。 |
evaluation | 是 | 评价值来自请求分配客服接口响应参数中 evaluationModel 中的 value 值。 |
evaluation_resolved | 否 | 用户上报问题解决状态,可以为空。0-未选择,1-已解决,2-未解决。 |
remarks | 否 | 评价备注信息,可以为空 |
tagList | 否 | 评价时给客服打的标签信息 |
响应示例如下:
{
"code": 200
}
响应参数说明如下:
参数 | 参数说明 |
---|---|
code | 错误码。200表示评价成功。 |
# 查询排队状态
POST 请求为:
POST https://qiyukf.com/openapi/event/queryQueueStatus?appKey=1064deea1c3624c9ee26d1de5ce8481f&time=1463217187&checksum=2f13932c4b7c6888b12360a85261a11b8b543f64
Content-Type:application/json;charset=utf-8
请求内容示例如下:
{
"uid":"user1"
}
请求参数说明如下:
参数 | 是否必须 | 参数说明 |
---|---|---|
uid | 是 | 开发者的应用里的用户 ID。 |
响应示例如下:
{
"code": 200,
"count": -1
}
响应参数说明如下:
参数 | 参数说明 |
---|---|
code | 错误码。200表示查询成功,14007表示用户不存在或者没有申请连接客服。 |
count | 排队队列中排在该用户前面的人数。-1表示已经有客服在接待了。 |
# 主动退出排队
如果一个用户已经在排队中,他可以选择主动退出排队,以便继续和机器人会话。通过提示用户自己退出排队,也可以减轻客服的压力。
该请求方法为POST,格式如下:
POST https://qiyukf.com/openapi/event/quitQueue?appKey=1064deea1c3624c9ee26d1de5ce8481f&time=1463217187&checksum=2f13932c4b7c6888b12360a85261a11b8b543f64
Content-Type:application/json;charset=utf-8
内容示例如下:
{
"uid":"user1"
}
请求参数说明如下:
参数 | 是否必须 | 参数说明 |
---|---|---|
uid | 是 | 开发者的应用里的用户 ID。 |
响应示例如下:
{
"code": 200
}
响应参数说明如下:
参数 | 参数说明 |
---|---|
code | 错误码。200表示退出成功,14007表示用户不存在或者没有申请连接客服。 |
# 会话结束推送会话数据
开发者服务器收到的POST请求示例如下:
POST https://QIYU_MSG_URL?eventType=DATA_ONLINE_SESSION_END&time=1463217187&checksum=2f13932c4b7c6888b12360a85261a11b8b543f64
Content-Type:application/json;charset=utf-8
请求内容示例如下:
{
"alarmTimes":1, // 此会话智能监控报警次数
"category":"xx/xx", // 会话分类信息
"closeReason":2, // 会话关闭原因,参照[接收会话结束通知]中的closeReason
"endTime":3, // 会话结束时间
"evaluationType":4, // 评价模型
"evaluation":2, // evaluationType:(evaluation)=> 2:(100满意1不满意); 3(100满意50一般1不满意); 5(100非常满意75满意50一般25不满意1非常不满意) 否则未评价
"evaluationRemark":"xx", // 评价内容
"staffInvitedEvaluateTime":"14014679100973", // 客服邀评时间戳 返回-1则为不存在该时间值
"userJoinEvaluateTime":"14014679100973", // 访客参评时间戳 返回-1则为不存在该时间值
"userResolvedStatus":1, // 用户标记的解决状态,0=未选择 1=已解决 2=未解决
"foreignId":"fs", // 由企业提供
"fromGroupId":999, // 会话来自分流组ID
"fromGroup":"2", // 会话来自分流组名称
"fromIp":"as", // 访客来源ip
"fromPage":"ff", // 来源页
"fromStaff":"3", // 来自哪个客服名
"fromTitle":"aaa",// 来源页标题
"fromType":"ios", // 来源类型 web/ios/android/wx(微信)/wx_ma(微信小程序)/wb(微博)/open(开放接口)
"id":1, // 会话id
"inQueueTime":4, // 排队时间
"interaction":0, // 0=客服正常会话 1=机器人会话
"relatedId":4, // 被关联的会话id
"relatedType":2, // 关联会话类型 0=无关联 1=从机器人转接过来 2=机器人会话转接人工 3=历史会话发起 4=客服间转接 5=被接管
"staffFirstReplyTime":14014679100973, // 客服首次响应的时间戳
"sType":"会话类型", // 0:正常会话.1(2):离线留言,3:排队超时
"staffId":4, // 客服id
"staffName":"f", // 客服名字 或为"机器人"
"startTime":2, // 会话开始时间
"stickDuration":43, // 置顶时长
"userId":43, // userId
"remarks":"会话备注", // 会话备注
"customFiled": [{\"fieldId\":\"自定义的id\",\"fieldName\":\"自定义名称\",\"fieldValue\":\"自定义实际值\"}], // 在线服务记录字段
"status":0, // 客服标记的解决状态
"vipLevel":2, // vip 层级 0=非VIP用户
"visitRange":5, // 与上一次来访的时间差 <=0则忽略
"transferRgType": "主动转人工", // 转人工类型:主动转人工、关键词转人工、回复引导转人工、拦截词转人工、连续未知转人工、差评转人工、情绪识别转人工、图片转人工
"roundNumber": 10 ,// 对话回合数
"clientFirstMessageTime": 14014679100973, //访客首条消息时间
"avgRespDuration": 11212121, //客服平均响应时长
"isValid": 1, //是否是有效会话,1为有效会话,0为无效会话
"humanTransferSessionId": 1212121,//转接来源的会话ID,0代表无转接会话
"transferFromStaffName": "f",//转接来源分流客服名称
"transferFromGroup": "g",//转接来源分流客服组名称
"transferRemarks":"remark",//转接来源备注
"staffMessageCount": 1,//客服消息数
"userMessageCount": 2, //用户消息数
"transferType": "静默转接",//转接类型 静默转接或人工转接
"overflowFrom": "客服组11",//溢出来源,
"isStaffInvited": "0",//是否邀请评价 0-没有邀评,1-客服主动邀评,2-系统自动邀评(注意:该字段已废弃,请使用字段isEvaluationInvited)
"treatedTime": 0, //留言处理时间,若会话不是留言则返回0
"fromHumanTransfer": 0, //是否来自客服转接 0:非转接会话;1:客服转接过来的会话
"firstReplyCost": 112233, //客服首次响应时长(访客首条消息与客服首次回复消息的时间间隔)
"categoryDetail": "xx/xx",//会话咨询分类明细
"isEvaluationInvited": 0, //是否邀请评价 0-没有邀评,1-客服主动邀评,2-系统自动邀评
"beginer": 0, //会话发起方 1:访客,2:客服
"ender": 0, //会话中止方 1:访客,2:客服,3:系统
"originPlatform": "直接访问", //来源渠道
"searchKey": "keyword", //关键词
"landPage": "page", //着陆页url
"satisfyMsgCount": 1, //好评消息数
"unsatisfyMsgCount": 0, //差评消息数
"satisfactionTags": ["评价标签1","评价标签2"] //访客评价时选择的标签
}
其中自定义字段如果是级联类型的,其fieldValue格式如:
{
"path": "1级/1.1级", // 每一级的完整名称
"idpath": [1555974, 1555977], // 每一级对应的ID
"id": 1555977 //级联自定义字段ID
}
# 接收会话变更信息通知
支持修改后实时推的字段:会话分类信息、评价结果、评价内容、会话备注、在线服务记录字段、会话状态。 开发者服务器收到的POST请求示例如下:
POST https://QIYU_MSG_URL?eventType=DATA_ONLINE_SESSION_CHANGE&time=1463217187&checksum=2f13932c4b7c6888b12360a85261a11b8b543f64
Content-Type:application/json;charset=utf-8
请求内容示例如下:
{
"sessionId":1, // 会话ID
"sessionType": "未分类", // 会话咨询分类
"sessionTypePath": "一级分类/二级分类/三级分类", // 会话咨询分类,包含详细分类路径,最多包含五级
"status":1, // 解决状态,0:未解决、1:已解决、2:解决中
"evaluation":1, // 评价结果
"evaluation_remarks": "评价备注", // "评价备注"
"userResolvedStatus": 1, //用户标注问题是否已经解决,0:未解决,1:已解决
"remarks": "备注", // 会话备注
"customField": "fieldKey:fieldValue;" // 在线服务字段内容
}
其中自定义字段如果是级联类型的,其fieldValue格式如:
{
"path": "1级/1.1级", // 每一级的完整名称
"idpath": [1555974, 1555977], // 每一级对应的ID
"id": 1555977 //级联自定义字段ID
}
# 接收会话质检事件通知
开发者服务器收到的POST请求示例如下:
POST https://QIYU_MSG_URL?eventType=DATA_SESSION_QUALITY&time=1463217187&checksum=2f13932c4b7c6888b12360a85261a11b8b543f64
Content-Type:application/json;charset=utf-8
请求内容示例如下:
{
"category":"a/b/c", // 分类
"evaluationType":4, // 评价模型
"evaluation":2, // evaluationType:(evaluation)=> 2:(100满意1不满意); 3(100满意50一般1不满意); 5(100非常满意75满意50一般25不满意1非常不满意) 否则未评价
"evaluationRemark":"xx", // 评价内容
"forbiddenItems":[ // 禁忌项
{
"isDone":1, // 是否发生 1=发生 else 未发生
"name":"禁忌项名称"
}
],
"foreignId":"fs", // 由企业提供
"fromGroup":"2", // 会话来自分流组名称
"id":2, // 会话id
"inspectTime":12, // 质检时间
"inspector":"质检员", // 质检人
"qualityComment":"asas", // 质检备注
"score":21, // 质检分数
"scoreItems":[ // 指标项及评分
{
"max":5.2,
"name":"质检项名称",
"value":1.1
}
],
"staffId":123, // 被质检的客服
"staffName":"被质检客服名字",
"startTime":32, // 会话开始时间
"type":3, // 1:在线;2:呼叫
"userId":12 // 访客id
}
# 消息推送
采用iOS和Android端接入的企业,可以通过该接口,向访客手机推动消息,访客手机端查看消息并回复后,会触发生成新的会话。以此增强企业主动营销能力。
目前支持三种格式的推送内容:纯文本、图片、富文本。
POST 请求为:
POST https://qiyukf.com/openapi/push/msg?appKey=1064deea1c3624c9ee26d1de5ce8481f&time=1463217187&checksum=2f13932c4b7c6888b12360a85261a11b8b543f64
Content-Type:application/json;charset=utf-8
senderInfo为客服信息(客服id,名称,头像),action为按钮信息(名称和url) 1.发送文本时:
{
"userlist":[
"uid1",
"uid2"
],
"bid":"upsh",
"senderInfo":{
"staffName":"三石",
"staffIcon":"http://imgsrc.baidu.com/baike/pic/item/e850352ac65c1038bcba9c0eb9119313b17e8932.jpg",
"staffId":"000"
},
"action":{
"label":"去看看",
"url":"http://www.163.com"
},
"msgtype":"TEXT",
"content":"推送内容xxx"
}
2.发送图片时:
{
"userlist": ["uid1","uid2"],
"bid": "upsh",
"msgtype": "PICTURE",
"senderInfo":{
"staffName":"三石",
"staffIcon":"http://imgsrc.baidu.com/baike/pic/item/e850352ac65c1038bcba9c0eb9119313b17e8932.jpg",
"staffId":"000"
},
"action":{
"label":"去看看",
"url":"http://www.163.com"
},
"content": {
"url": "https://xxxx",
"name": "auth.png",
"size": 198509,
"md5": "6008a3873199b1ab3582a8eaeb62be60",
"w": 329,
"h": 724,
"ext": "png"
}
}
3.发送富文本时:
{
"userlist": ["uid1","uid2"],
"bid": "upsh",
"msgtype": "RICHTEXT",
"senderInfo":{
"staffName":"三石",
"staffIcon":"http://imgsrc.baidu.com/baike/pic/item/e850352ac65c1038bcba9c0eb9119313b17e8932.jpg",
"staffId":"000"
},
"action":{
"label":"去看看",
"url":"http://www.163.com"
},
"content": {
"content": "<div><img src=\"https://xxxx\" width=\"1041\" height=\"1755\" data-url=\"https://xxx\" data-size=\"739320\" title=\"微信图片_20171226144407.jpg\" data-group=\"ysf\"></div>",
"cmd": 65
}
}
请求参数说明如下:
参数 | 是否必须 | 参数说明 |
---|---|---|
userlist | 是 | 对应访客uid 串,uid 为对接时的第三方用户ID |
bid | 否 | 推送消息的商户编号。平台电商企业使用,非平台电商企业不传 |
msgtype | 是 | 消息类型,目前支持TEXT,PICTURE,RICHTEXT三种 |
content | 是 | 消息内容。文本消息是文本内容,图片和语音消息则是描述的 json, 该字段长度限制最大为 4000 个字符。 |
content.url | 是 | 图片,语音消息的文件 url。请保证该 url 不会存在跨域访问问题。 如果不能跨域访问,请使用下面的文件上传接口将文件上传到七鱼服务器,然后使用返回的 url。 |
content.name | 是 | 图片名称 |
content.size | 是 | 文件大小,单位为 byte。 |
content.md5 | 是 | 文件内容的 MD5。 |
content.w | 否 | 图片消息中图片的宽度,正确传递该值可以提升客服的浏览体验。 |
content.h | 否 | 图片消息中图片的高度,正确传递该值可以提升客服的浏览体验。 |
content.ext | 是 | 图片格式,为图片后缀名 |
content.content | 是 | 富文本内容,详细规范请咨询技术支持 |
content.cmd | 是 | 目前固定为65 |
senderInfo | 否 | 客服信息 |
senderInfo.staffId | 是 | 客服id,senderInfo为空时,可以为空 |
senderInfo.staffName | 否 | 客服名称 |
senderInfo.staffIcon | 否 | 客服头像 |
action | 否 | 跳转按钮信息 |
action.label | 是 | 按钮名称(action为空时可以为空) |
action.url | 是 | 按钮跳转地址(action为空时可以为空) |
返回的响应内容为:
{
"code": 200,
"message": "{\"valid\":[\"uid1\",\"uid2\"],\"invalid\":[\"uid3\",\"uid4\"],\"unsupport\":[\"uid5\",\"uid6\"]}"
}
返回参数说明如下:
参数 | 是否必须 | 参数说明 |
---|---|---|
code | 是 | 200表示成功,其他为对应错误码 |
message | 是 | 格式为String,成功时为 json 结果,失败时为对应错误说明 |
valid | 是 | 有效的uid 串,表示在七鱼存在账号且支持推送的访客 |
invalid | 是 | 无效的uid 串,在七鱼不存在对应账号 |
unsupport | 是 | 不支持推送的uid 串,在七鱼存在对应账号,但是由于访客端APP版本过低或者非移动端账号,不支持推送消息 |
# 数据接口
接口鉴权参考通用说明-数据校验 (opens new window)
# 实时数据报表
POST 请求:
https://qiyukf.com/openapi/data/overview/session?appKey=[APP_KEY]&time=[TIME]&checksum=[CHECKSUM]
Content-Type:application/json;charset=utf-8
请求内容如下:
{
"toGroup":[12834, 1234343],
"toStaff":[23456,293940],
"assignStaff":[218282,32293],
"staffGroup":[218282,32909]
}
接口参数说明:
参数 | 是否必须 | 参数说明 |
---|---|---|
toGroup | 否 | 分流客服组 |
toStaff | 否 | 分流客服 |
assignStaff | 否 | 客服id |
staffGroup | 否 | 客服组id |
当上述四个参数不传时认为查询全部数据
返回值说明:
{
"code":200,
"message":"{..}"
}
其中message对象结构如下:
{
"averageServiceTime":0, // 今日平均会话时长(毫秒)
"averageWaitingTime":0, // 今日平均排队时长(毫秒)
"evaluatePercent":0, // 参评率
"kefuCount":1, // 当前在线客服人数
"leaveSessionCount":2, // 未接入会话量
"queueCount":4, // 当前排队人数
"relativeSatisfactionPercent":0,// 今日相对满意度
"servicePercent":0.2, // 接入率
"sessionCount":8, // 当前咨询人数
"totalQueueCount":0, // 今日排队总数, 从0时至今
"totalSessionCount":0, // 今日会话量
"firstResponseTime": 1000, // 今日平均首次响应时长(毫秒)
"averageResponseTime": 2399, // 今日平均响应时长(毫秒)
"evaluationCount": 12, // 参评数量
"inviteEvaluationPercent": 1.0, // 邀评率
"validInviteEvalPercent": 1.0, // 有效会话邀评率
"type":1 // 可忽略
}
# 客服质量报表
提供在线系统->历史数据->坐席报表->工作质量报表,推荐查询周期在一个月(31天)内的数据,频率限制为1分钟一次
接口使用说明
- 请求样例
curl -X POST \ 'http://qiyukf.com/openapi/statistic/staffquality?appKey=3ec34a7ab5305ff49959d5c5023ccabf&time=1534316797&checksum=9b924c7adac9d31a6177fae51cdd86f0e7dee4da' \ -H 'content-type: application/json;charset=utf-8'
- 编写接口
- 接口鉴权参考通用说明-数据校验 (opens new window)
- 接口类型 POST
- 接口参数 主要用于鉴权
参数 | 参数说明 |
---|---|
appKey | 企业的appKey |
checksum | SHA1(appSecret + md5 + time), 三个参数拼接的字符串,进行SHA1哈希计算,转化成16进制字符(String,小写) |
time | 当前 UTC 时间戳,从 1970 年 1 月 1 日 0 点 0 分 0 秒开始到现在的秒数 |
请求字段说明:
参数 | 是否必须 | 参数说明 |
---|---|---|
startTime | 否 | 开始时间 |
endTime | 否 | 结束时间,开始时间和结束时间均不传的情况下,会查询近一个月的数据,不能大于当天的开始时间 |
model | 否 | 模式1 默认全部, 模式2 客服组列表, 模式3 客服 |
staffGroupList | 否 | 客服组id |
staffIdList | 否 | 客服id |
请求内容示例:
{
"startTime": 1594306727942,
"endTime": 1594308204040,
"model": 1,
"staffGroupList": [
63294,
80624,
46334
],
"staffIdList": [
34240,
92461,
74647
]
}
4.接口数据 接口返回数据在请求体内,主要是以JSON格式返回
数据键名 | 数据类型 | 数据说明 |
---|---|---|
id | Long | 客服id |
name | String | 客服名字 |
namePinyin | String | 客服名字拼音 |
avgFirstRespTime | Long | 平均首响 |
avgRespTime | Long | 平均响应时长 |
avgRgTime | Long | 平均人工接待时长 |
replyRatio | Double | 应答率 |
avgTime | Long | 平均会话时长 |
evaRatio | Double | 参评率 |
satisfactionRatio | Double | 满意度 |
role | Integer | 客服角色 |
timestamp | Long | 时间 |
evaluationDetail | String | 满意度详情 |
dynamicTitle | Map<String, Integer> | 动态满意度详情 |
rest | String | 小休明细 |
rest1 | Long | 小休-就餐时长 |
rest2 | Long | 小休-会议时长 |
rest3 | Long | 小休-培训时长 |
rest4 | Long | 小休-休息时长 |
rest5 | Long | 小休-洗手间时长 |
rest90 | Long | 小休-其他 |
evaFromCount | Long | 邀评数 |
evaFromAll | Long | 邀评总数 |
evaFromRatio | Double | 邀评率 |
answerReplyRatio | Double | 答问比 |
oneOffRatio | Double | 一次性解决率 |
withdrawCnt | Long | 撤回消息数 |
userResolvedRatio | Double | 用户解决率 |
answerReplyRatio | Double | 答问比 |
oneOffRatio | Double | 一次性解决率 |
# 客服考勤报表
提供在线系统->历史数据->坐席报表->考勤报表,推荐查询周期在一个月(31天)内的数据,频率限制为1分钟一次,默认只查询所传参数获取数据的前100条数据,若想获取全部客服或客服组的数据,请分批次传客服/客服组 接口使用说明
- 请求样例
curl -X POST \ 'http://qiyukf.com/openapi/statistic/staffAttendance?appKey=3ec34a7ab5305ff49959d5c5023ccabf&time=1534316797&checksum=9b924c7adac9d31a6177fae51cdd86f0e7dee4da' \ -H 'content-type: application/json;charset=utf-8'
- 编写接口
- 接口鉴权参考通用说明-数据校验 (opens new window)
- 接口类型 POST
- 接口参数 主要用于鉴权
参数 | 参数说明 |
---|---|
appKey | 企业的appKey |
checksum | SHA1(appSecret + md5 + time), 三个参数拼接的字符串,进行SHA1哈希计算,转化成16进制字符(String,小写) |
time | 当前 UTC 时间戳,从 1970 年 1 月 1 日 0 点 0 分 0 秒开始到现在的秒数 |
请求字段说明:
参数 | 是否必须 | 参数说明 |
---|---|---|
startTime | 否 | 开始时间 |
endTime | 否 | 结束时间,开始时间和结束时间均不传的情况下,会查询近一个月的数据 |
model | 否 | 模式1 默认全部, 模式2 客服组列表, 模式3 客服 |
staffGroupList | 否 | 客服组id |
staffIdList | 否 | 客服id |
page | 否 | 当前分页查询的页码,从1开始,默认为1 |
pageSize | 否 | 分页查询的数量,取值范围1~1000,默认为100 |
请求内容示例:
{
"startTime": 1594306727942,
"endTime": 1594308204040,
"model": 1,
"staffGroupList": [
63294,
80624,
46334
],
"staffIdList": [
34240,
92461,
74647
]
}
其中message对象结构如下:
{
"id": 1, //客服id
"name": "张三", //客服名字
"account": "Zhangsan", //账户名
"date": 1594308204040, //统计日期时间戳
"firstLoginTs": 1594308204040, //首次登录时间
"firstOnlineTs": 1594308204040, //首次上线时间
"lastHangTs": 1594308204040, //最后挂起时间
"lastLogoutTs": 1594308204040, //最后登出时间
"loginDuration": 12345, //值班总时长
"onlineDuration": 3456, //在线时长
"onlineSessionDuration": 12456, //在线会话时长
"onlineFreeDuration": 34567, //在线空闲时长
"pcOnlineDuration": 12678, //电脑端在线时长
"mobileOnlineDuration": 3467, //手机端在线时长
"restDuration": 1289, //小休时长
"restSessionDuration": 238090, //小休会话时长
"breakTimes": 12, //小休次数
"restMealDuration": 12244, //小休-就餐时长
"restMettingDuration": 4849, //小休-会议时长
"restTrainDuration": 23747, //小休-培训时长
"restShortDuration": 223232, //小休-休息时长
"restWashroomDuration": 12121, //小休-洗手间时长
"restOtherDuration": 13334, //小休-其他时长
"hangDuration": 11212, //挂起时长
"hangSessionDuration": 1233, //挂起会话时长
"hangTimes": 2 //挂起次数
}
4.接口数据 接口返回数据在请求体内,主要是以JSON格式返回
数据键名 | 数据类型 | 数据说明 |
---|---|---|
id | Long | 客服id |
name | String | 客服名字 |
account | String | 账户名 |
date | Long | 统计日期时间戳 |
firstLoginTs | String | 首次登录时间 |
firstOnlineTs | Long | 首次上线时间 |
lastHangTs | Long | 最后挂起时间 |
lastLogoutTs | Long | 最后登出时间 |
loginDuration | Long | 值班总时长 |
onlineDuration | Long | 在线时长 |
onlineSessionDuration | Long | 在线会话时长 |
onlineFreeDuration | Long | 在线空闲时长 |
pcOnlineDuration | Long | 电脑端在线时长 |
mobileOnlineDuration | Long | 手机端在线时长 |
restDuration | Long | 小休时长 |
restSessionDuration | Long | 小休会话时长 |
breakTimes | Long | 小休次数 |
restMealDuration | Long | 小休-就餐时长 |
restMettingDuration | Long | 小休-会议时长 |
restTrainDuration | Long | 小休-培训时长 |
restShortDuration | Long | 小休-休息时长 |
restWashroomDuration | Long | 小休-洗手间时长 |
restOtherDuration | Long | 小休-其他时长 |
hangDuration | Long | 挂起时长 |
hangSessionDuration | Long | 挂起会话时长 |
hangTimes | Long | 挂起次数 |
# 客服考勤明细
提供在线系统->历史数据->坐席报表->考勤报表->考勤明细,单个客服一天的考勤详情。频率限制为1分钟300次。 接口使用说明
- 请求样例
curl -X POST \ 'http://qiyukf.com/openapi/statistic/salaryDetail?appKey=3ec34a7ab5305ff49959d5c5023ccabf&time=1534316797&checksum=9b924c7adac9d31a6177fae51cdd86f0e7dee4da' \ -H 'content-type: application/json;charset=utf-8'
- 编写接口
- 接口鉴权参考通用说明-数据校验 (opens new window)
- 接口类型 POST
- 接口参数 主要用于鉴权
参数 | 参数说明 |
---|---|
appKey | 企业的appKey |
checksum | SHA1(appSecret + md5 + time), 三个参数拼接的字符串,进行SHA1哈希计算,转化成16进制字符(String,小写) |
time | 当前 UTC 时间戳,从 1970 年 1 月 1 日 0 点 0 分 0 秒开始到现在的秒数 |
请求字段说明:
参数 | 是否必须 | 参数说明 |
---|---|---|
startTime | 否 | 开始时间 |
staffId | 是 | 客服id |
请求内容示例:
{
"startTime": 1594308486784, //该字段不传,默认查询当天的考勤明细数据
"staffId": 72142
}
4.接口数据 接口返回数据在请求体内,主要是以JSON格式返回
数据键名 | 数据类型 | 数据说明 |
---|---|---|
id | Long | 客服id |
name | String | 客服名字 |
account | String | 账户名 |
date | Long | 查询所在天的开始时间戳 |
loginRecords | ListList<SalaryDetailVO> | 登录详情 |
SalaryDetailVO
数据键名 | 数据类型 | 数据说明 |
---|---|---|
login | Long | 首次登录时间戳 |
logout | Long | 最后登出时间戳 |
middle | List<StaffRecordDetailVO> | 登录详情 |
StaffRecordDetailVO
数据键名 | 数据类型 | 数据说明 |
---|---|---|
id | Long | 事件id |
name | String | 考勤事件名称 |
time | Long | 事件发生时间 |
# 历史数据总览
提供在线系统->历史数据->总览。默认查询31天内数据之和,频率为1分钟1次,当天数据不支持查询。 接口使用说明
- 请求样例
curl -X POST \ 'http://qiyukf.com/openapi/statistic/overview?appKey=3ec34a7ab5305ff49959d5c5023ccabf&time=1534316797&checksum=9b924c7adac9d31a6177fae51cdd86f0e7dee4da' \ -H 'content-type: application/json;charset=utf-8'
- 编写接口
- 接口鉴权参考通用说明-数据校验 (opens new window)
- 接口类型 POST
- 接口参数 主要用于鉴权
参数 | 参数说明 |
---|---|
appKey | 企业的appKey |
checksum | SHA1(appSecret + md5 + time), 三个参数拼接的字符串,进行SHA1哈希计算,转化成16进制字符(String,小写) |
time | 当前 UTC 时间戳,从 1970 年 1 月 1 日 0 点 0 分 0 秒开始到现在的秒数 |
请求字段说明:
参数 | 是否必须 | 参数说明 |
---|---|---|
startTime | 否 | 开始时间 |
endTime | 否 | 结束时间 |
staffIds | 否 | 客服id List |
sessionOrigin | 否 | 0:所有发起方,会话发起方,1:来访会话,2:主动发起会话 |
distributeIds | 否 | 分流客服组 List |
distributeStaffIds | 否 | 分流客服id List |
请求内容示例:
{
"startTime": 1594308486784,
"endTime": 1594308486784,
"staffIds": [
34240,
92461,
74647
]
}
4.接口数据 接口返回数据在请求体内,主要是以JSON格式返回
数据键名 | 数据类型 | 数据说明 |
---|---|---|
sessions | Long | 总会话数 |
effectSessions | Long | 有效会话数 |
assignedRatio | Double | 接入率 |
effectAssignedRatio | Double | 有效接入率 |
redirectSessionsCount | Long | 转接量 |
realSessionInRatio | Double | 实际接入率 |
messages | Long | 总消息数 |
answerRatio | Double | 问答比 |
specialAnswerRatio | Double | 应答率 |
evaFromCount | Long | 邀评数 |
evaFromRatio | Double | 邀评率 |
satisfactionRatio | Double | 相对满意度 |
relativelySatisfiedCount | Long | 相对满意数 |
relativelySatisfiedAll | Long | 相对满意总数 |
responseTotalLength | Long | 响应总时长 (注意:该字段已废弃) |
responseTotalLengthAll | Long | 响应回合/会话数 (注意:该字段已废弃) |
answerThirtyRatioCount | Long | 30秒应答率分子(注意:该字段已废弃) |
answerThirtyRatioAll | Long | 30秒应答率分母 (注意:该字段已废弃) |
sessionLength | Long | 会话时长 (注意:该字段已废弃) |
sessionLengthAll | Long | 会话时长总数 (注意:该字段已废弃) |
evaluatedCount | Long | 总评价数 (注意:该字段已废弃) |
evaluatedCountAll | Long | 总评价数总数 (注意:该字段已废弃) |
firstResponseTimeCount | Long | 首次响应分子 (注意:该字段已废弃) |
firstResponseTimeAll | Long | 首次响应时长 (注意:该字段已废弃) |
avgSucQueueTimeAll | Long | 排队时长分母 (注意:该字段已废弃) |
evaRatio | Double | 参评率 |
avgTime | Long | 平均会话时长 |
avgRgTime | Long | 平均人工接待时长 |
avgFirstRespTime | Long | 平均首次响应时长 |
avgRespTime | Long | 平均响应时长 |
queueCount | Long | 排队次数 |
avgSucQueueTime | Long | 平均排队时长 |
maxQueueTime | Long | 最长排队时间 |
unAssignedSessions | Long | 排队失败量 |
avgFailureQueueTime | Long | 平均放弃时长 |
oneOffRatio | Double | 一次解决率 |
userResolvedRatio | Double | 用户解决率 |
userResolvedCount | Long | 用户解决数 (注意:该字段已废弃) |
queueCountMessage | Long | 排队转留言的数量 |
visit | Long | 总来访量 |
sessionInCount | Long | 接入会话量 |
sessionNotInCount | Long | 未接入会话量 |
callBackCount | Long | 坐席发起会话量 |
notInServiceCount | Long | 非服务时间来访量 |
slientTransCount | Long | 系统转出量 |
humanTransCount | Long | 人工转出量 |
overflowCount | Long | 系统溢出量 |
evaInviteRatio | Double | 邀评率 |
einsteinTransCount | Long | 机器人转人工量 |
einsteinCount | Long | 机器人会话量 |
totalConsultCount | Long | 总咨询来访量 |
loginStaffCount | Long | 登录账号数 |
einsteinValidCount | Long | 机器人有效会话量 |
einsteinTransValidCount | Long | 机器人有效转人工会话量 |
resumeDuration | Double | 在线总时长(小时) |
# 客服工作量报表
提供在线系统->历史数据->坐席报表->工作量。默认查询31天内数据之和,频率为1分钟1次
接口使用说明
- 请求样例
curl -X POST \ 'http://qiyukf.com/openapi/statistic/staffworklod?appKey=3ec34a7ab5305ff49959d5c5023ccabf&time=1534316797&checksum=9b924c7adac9d31a6177fae51cdd86f0e7dee4da' \ -H 'content-type: application/json;charset=utf-8'
- 编写接口
- 接口鉴权参考通用说明-数据校验 (opens new window)
- 接口类型 POST
- 接口参数 主要用于鉴权
参数 | 参数说明 |
---|---|
appKey | 企业的appKey |
checksum | SHA1(appSecret + md5 + time), 三个参数拼接的字符串,进行SHA1哈希计算,转化成16进制字符(String,小写) |
time | 当前 UTC 时间戳,从 1970 年 1 月 1 日 0 点 0 分 0 秒开始到现在的秒数 |
请求字段说明:
参数 | 是否必须 | 参数说明 |
---|---|---|
startTime | 否 | 开始时间 |
endTime | 否 | 结束时间,开始时间和结束时间均不传的情况下,会查询近一个月的数据 |
model | 否 | 模式1 默认全部, 模式2 客服组列表, 模式3 客服 |
staffGroupList | 否 | 客服组id |
staffIdList | 否 | 客服id |
请求内容示例:
{
"startTime": 1594308486784,
"endTime": 1594308486784,
"model": 3,
"staffIdList": [
34240,
92461,
74647
]
}
4.接口数据 接口返回数据在请求体内,主要是以JSON格式返回
数据键名 | 数据类型 | 数据说明 |
---|---|---|
id | Long | 客服id |
name | String | 客服名字 |
account | String | 账户名 |
date | Long | 统计日期时间戳,该日期无具体意义,仅表示当前查询的开始时间 |
totalSessionCount | Long | 会话总量 |
sessionsCount | Long | 接入会话量 |
initiativeSessionsCount | Long | 发起会话量 |
redirectSessionsCount | Long | 转出量 |
validSessionCount | Long | 有效会话量 |
uselessSessionsCount | Long | 无效会话量 |
noReplySessionsCount | Long | 未回复会话量 |
noReplyRatio | Double | 未回复率 |
messageDealCount | Long | 留言处理量 |
preQueueCount | Long | 提前进线量 |
# 客服满意度报表
提供客服维度的满意度报表数据。默认查询31天内数据之和,频率为1分钟1次
接口使用说明
- 请求样例
curl -X POST \ 'http://qiyukf.com/openapi/statistic/satisfaction/report?appKey=3ec34a7ab5305ff49959d5c5023ccabf&time=1534316797&checksum=9b924c7adac9d31a6177fae51cdd86f0e7dee4da' \ -H 'content-type: application/json;charset=utf-8'
- 编写接口
- 接口鉴权参考[通用说明-数据校验]
- 接口类型 POST
- 接口参数 主要用于鉴权
参数 | 参数说明 |
---|---|
appKey | 企业的appKey |
checksum | SHA1(appSecret + md5 + time), 三个参数拼接的字符串,进行SHA1哈希计算,转化成16进制字符(String,小写) |
time | 当前 UTC 时间戳,从 1970 年 1 月 1 日 0 点 0 分 0 秒开始到现在的秒数 |
请求字段说明:
参数 | 是否必须 | 参数说明 |
---|---|---|
startTime | 否 | 开始时间 |
endTime | 否 | 结束时间,开始时间和结束时间均不传的情况下,会查询近一个月的数据 |
model | 否 | 模式1 默认全部, 模式2 客服组列表, 模式3 客服 |
staffGroupList | 否 | 客服组id |
staffIdList | 否 | 客服id |
请求内容示例:
{
"startTime": 1594308486784,
"endTime": 1594308486784,
"model": 3,
"staffIdList": [
34240,
92461,
74647
]
}
4.接口数据 接口返回数据在请求体内,主要是以JSON格式返回
数据键名 | 数据类型 | 数据说明 |
---|---|---|
id | Long | 客服id |
name | String | 客服名字 |
account | String | 账户名 |
date | Long | 统计日期时间戳,该日期无具体意义,仅表示当前查询的开始时间 |
staffInviteCount | Long | 人工邀评量 |
inviteCount | Long | 邀评量 |
evaCount | Long | 参评量 |
verySatisfiedCount | Long | 非常满意会话数 |
satisfiedCount | Long | 满意会话数 |
normalSatisfiedCount | Long | 一般会话数 |
veryNotSatisfiedCount | Long | 非常不满意会话数 |
notSatisfiedCount | Long | 不满意会话数 |
staffInviteRatio | Double | 人工邀评率 |
inviteRatio | Double | 邀评率 |
validStaffInviteRatio | Double | 有效人工邀评率 |
validInviteRatio | Double | 有效邀评率 |
evaRatio | Double | 参评率 |
validEvaRatio | Double | 有效参评率 |
satisfactionRatio | Double | 相对满意度 |
validSatisfactionRatio | Double | 有效相对满意度 |
# 订单绩效对接
为帮助企业客服管理者更好地考核客服绩效,统计客服的销售及访客订单的转化等情况,七鱼系统OpenAPI提供企业成单数据对接接口,企业可将其成单数据加密同步至七鱼系统,同步成功后,七鱼系统根据成单数据计算出该订单是由那个客服的服务产生的,从而生成企业客服的订单绩效。
# 数据同步流程
数据同步采取批量同步,企业一次最大可上传1000个订单数据,订单数据传输采用JSON格式。 具体步骤如下:
- 企业将订单数据按规定格式组装成json数组对象。
- 对组装过的json数组对象使用AES算法 (opens new window)加密。
- 对加密后的文本做checksum校验,具体见接口鉴权部分。
- 使用https请求开放接口。
# 接口鉴权
接口鉴权参考通用说明-数据校验 (opens new window)
# 订单属性
订单属性 | 描述 | 是否必须 |
---|---|---|
orderId | 企业数据库中标识订单唯一的项,比如订单表主键或者订单号,要求在企业数据库中必须保证全局唯一,在1~255字符之间 | 是 |
uid | 标识该订单是那个客户所下的单,要求必须能唯一标识出该下单客户,在1~128字符之间 | 是 |
orderTime | 该订单的下单时间,精确到毫秒,比如下单时间是2016-11-11 11:11:11,则下单时间是1478833871000,下单时间必须大于0 | 是 |
payTime | 该订单的支付时间,精确到毫秒,同orderTime;目前不支持配置,默认按订单的支付时间来算客服的订单绩效 ,支付时间必须大于0 | 是 |
amount | 该订单中购买或退款的商品件数 | 否 |
price | 该订单购买或退款的总金额 | 否 |
status | 该订单的状态,用于订单支付/撤销/退款场景:正常订单status=2,撤销订单status=3,退款订单=4 默认为正常订单 | 否 |
refundNo | 每次退款的编号全局唯一 | status=4时必填 |
refundTime | 该订单的退款时间 | status=4时必填 |
# 示例
比如某企业订单信息如下:
orderId | uid | orderTime | payTime | amount | price | status |
---|---|---|---|---|---|---|
orderId1 | uid1 | 1478826671000 | 1478833871000 | 1 | 100.00 | 2 |
orderId2 | uid2 | 1478826881888 | 1478833888888 | 2 | 888.88 | 3 |
- 组装成的json数组对象如下:
[
{
"uid":"uid1",
"amount":1,
"orderTime":1478826671000,
"orderId":"orderId1",
"payTime":1478833871000,
"price":100,
"status":2
},
{
"uid":"uid2",
"amount":2,
"orderTime":1478826881888,
"orderId":"orderId2",
"payTime":1478833888888,
"price":213,
"status":3
}
]
- 将组装后的json数组对象进行AES加密,加密代码如下:
/**
* 使用AES算法对content加密
*
* @param content 待加密的内容
* @param encryptKey 加密密钥
* @return 加密后的byte[]
*/
public static String encrypt(String content, String encryptKey) {
try {
KeyGenerator kgen = KeyGenerator.getInstance("AES");
SecureRandom random = SecureRandom.getInstance("SHA1PRNG");
random.setSeed(encryptKey.getBytes());
kgen.init(128, random);
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(kgen.generateKey().getEncoded(), "AES"));
return byteArr2HexStr(cipher.doFinal(content.getBytes("utf-8")));
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/**
* 将byte数组转换为16进制值的字符串
*
* @param b 需要转换的byte数组
* @return 转换后的字符串
*/
private static String byteArr2HexStr(byte[] b) {
int length = b.length;
StringBuffer sb = new StringBuffer(length * 2);
for (int i = 0; i < length; i++) {
int temp = b[i];
while (temp < 0) {
temp = temp + 256;
}
if (temp < 16) {
sb.append("0");
}
sb.append(Integer.toString(temp, 16));
}
return sb.toString();
}
加密密钥使用企业的AppSecret加密,假设某企业AppSecret为123456,则加密示例如下:
加密前:
[{"uid":"uid1","amount":1,"orderTime":1478826671000,"orderId":"orderId1","payTime":1478833871000,"price":100.00},{"uid":"uid2","amount":2,"orderTime":1478826881888,"orderId":"orderId2","payTime":1478833888888,"price":213}]
加密后:
11896bd6f9940b859746a40eace4cbccac23c6208bd7b93fc706afdfc65d707313618b12a1ee4baf18c9b73de825c169f0af355e3f85fc02aad4fc69c6027cc4a750789eb71274d3e49bbad65db483d1cba9e9dd5fb674cd02d1019ad31f6a4912326a639f1f2471708c88dbed0c3b01639ebf0ca6cf3734b26076a06a65615b98ffc188994261f2531d539f5b5c71742672fbc288fd608121866e493a178efe6ee880df386e03b03995b6da43c93429781d011f5459c67eefc88fa6c23e07f2f8337adbefce92f49316b90e9dfa4df4766e9e43488d5875bad81e0804713a34
由于使用https传输及AES算法加密内容,双重保证传输数据的安全性。
# 上传订单信息接口
POST 请求为:
curl -X POST \
'https://qiyukf.com/openapi/order/upload?appKey=3ec34a7ab5305ff49959d5c5023ccabf&time=1534316797&checksum=9b924c7adac9d31a6177fae51cdd86f0e7dee4da' \
-H 'content-type: application/json;charset=utf-8'
上传成功响应:
{
"code":200,
"message":"upload order info success, total = 2"
}
- 响应码为200时,message里total内容为上传成功的订单个数。
# 订单绩效导出接口
POST 请求为:
curl -X POST \
'https://qiyukf.com/openapi/statistic/performance?appKey=3ec34a7ab5305ff49959d5c5023ccabf&time=1534316797&checksum=9b924c7adac9d31a6177fae51cdd86f0e7dee4da' \
-H 'content-type: application/json;charset=utf-8'
- 编写接口
- 接口鉴权参考[通用说明-数据校验]
- 接口类型 POST
- 接口参数 主要用于鉴权
参数 | 参数说明 |
---|---|
appKey | 企业的appKey |
checksum | SHA1(appSecret + md5 + time), 三个参数拼接的字符串,进行SHA1哈希计算,转化成16进制字符(String,小写) |
time | 当前 UTC 时间戳,从 1970 年 1 月 1 日 0 点 0 分 0 秒开始到现在的秒数 |
请求字段说明:
参数 | 是否必须 | 参数说明 |
---|---|---|
startTime | 否 | 开始时间 |
endTime | 否 | 结束时间,开始时间和结束时间均不传的情况下,会查询近一个月的数据 |
staffGroupList | 否 | 客服组id |
staffIdList | 否 | 客服id |
page | 否 | 当前分页查询的页码,从1开始,默认为1 |
pageSize | 否 | 分页查询的数量,取值范围1~1000,默认为100 |
(请求频率限制一分钟一次)
请求内容示例:
{
"startTime": 1594308486784,
"endTime": 1594308486784,
"staffIdList": [
34240,
92461,
74647
],
"staffGroupList":[
61010,
61011
],
"page": 2,
"pageSize":100
}
4.接口数据 接口返回数据在请求体内,主要是以JSON格式返回
数据键名 | 数据类型 | 数据说明 |
---|---|---|
staffId | Long | 客服id |
userName | String | 用户名 |
nameSpell | String | 用户全拼 |
kefuName | String | 客服名字 |
serviceNums | Long | 接待非匿名人数 |
validServiceNums | Long | 有效接待人数 |
totalServiceNums | Long | 接待总人数 |
sellNums | Long | 支付人数 |
sell48Nums | Long | 48小时支付人数 |
translationRatio | Double | 转化率 |
translation48Ratio | Double | 48小时转化率 |
sellMoney | Long | 支付金额 |
sell48Money | Long | 48小时支付金额 |
sellMoneyRatio | Double | 支付金额比例 |
orderNums | Long | 销售单数 |
order48Nums | Long | 48小时销售单数 |
pieceNums | Long | 支付件数 |
piece48Nums | Long | 48小时支付件数 |
kePieceNums | Double | 客件数 |
ke48PieceNums | Double | 48小时客件数 |
keOrderPrice | Double | 客单价 |
ke48OrderPrice | Double | 48小时客单价 |
sum一行代表总和
# 获取会话记录
# 概述
- 此文档描述第三方(以下简称企业)通过七鱼提供的开放接口获取企业会话相关信息的步骤及细节。
- 由于会话是跟企业息息相关的数据,为保证数据的安全,七鱼要求企业在调用每个接口时提供相关信息以保证数据的安全。
- 同一企业在24小时内, 批量下载任务相同任务最大并发请求访问为一次(所有参数都一样即是同一个任务),访问时间没有限制。
- 同一企业同步单条会话数据和消息的任务为每分钟 1000 次,访问时间没有限制。
# 接口鉴权
参考 通用说明-数据校验 (opens new window)
# 接口示例
# 批量导出完整请求地址如下例(POST):
curl -X POST \
'https://qiyukf.com/openapi/export/session?appKey=3ec34a7ab5305ff49959d5c5023ccabf&time=1534316797&checksum=9b924c7adac9d31a6177fae51cdd86f0e7dee4da' \
-H 'content-type: application/json;charset=utf-8'
接口请求 body 示例如下:
{"start":"1504972800000","end":"1505016000000"}
# "单条会话数据获取"以及"单条会话消息获取" 的完整请求地址如下例(POST):
curl -X POST \
'https://qiyukf.com/openapi/export/session/one?appKey=3ec34a7ab5305ff49959d5c5023ccabf&time=1534316797&checksum=9b924c7adac9d31a6177fae51cdd86f0e7dee4da' \
-H 'content-type: application/json;charset=utf-8'
curl -X POST \
'https://qiyukf.com/openapi/export/session/one/message?appKey=3ec34a7ab5305ff49959d5c5023ccabf&time=1534316797&checksum=9b924c7adac9d31a6177fae51cdd86f0e7dee4da' \
-H 'content-type: application/json;charset=utf-8'
接口参数无需起止时间,其body内容示例如下:
{"sessionId" : 123456}
# 接口访问步骤
分为两步:添加任务,校验任务是否完成(如果已完成则提供数据下载链接)。
# 1.添加任务
地址:https://qiyukf.com/openapi/export/session 描述:该接口用于告诉七鱼,企业将开始一个导出数据的任务。 参数: start和end一同决定了要导出的数据的时间范围,其最大时间间隔不能超过2天。
- start: 时间戳毫秒单位
- end: 时间戳毫秒单位
如果一切检查通过,那么该接口会立即返回,其中"message"值是一个有关本次请求的一个专有key用于 1.2 接口请求时的参数值。
{"code":200,"message":"key"}
# 2.校验任务是否完成
地址:https://qiyukf.com/openapi/export/session/check 描述,该接口用于检测任务是否已做完 参数,key,即 1.1 接口返回的 message值
{
"key": "aweerr"
}
如果一切检查合法并且任务执行完毕将返回
{"code":200,"message":"httpUrl"}
该message值即为一个请求下载数据文件的链接,企业可以利用该链接去下载到一个数据文件,这是一个zip格式文件,解压密码是企业appkey的前12个字符。该下载链接有效时间为6小时。解压之后,可得到两个txt文件。 如果不合法则返回示例如下:
{"code": 非200,"message":"相关描述"}
由于 1.1 接口在创建任务后不一定会马上完成,所以最好是在创建任务成功后等待一定时间后再去使用key调用 1.2 接口。而且根据任务量的不同,任务执行时间长短不定;若 1.2 接口返回
{"code":14403,"message":"Wait..."}
需要等待一定时间后再次去请求(等待时间由开发者自己设定),直到成功为止。
# 接口地址
# 根据会话ID获取会话字段
地址:https://qiyukf.com/openapi/export/session/one 描述:该接口用于通过会话ID获取会话详情内容,支持单条获取,目前限定企业访问频次为每秒不能超过5次。 参数:sessionId,长整型,会话的ID。
如果一切检查通过,那么该接口会立即返回,其中"data"值是就是对应的结果, 一个JSON,字段详情见字段说明的Session说明。
{"code":200,"message":"success", "data": {}}
# 根据会话ID获取会话消息
地址:https://qiyukf.com/openapi/export/session/one/message 描述:该接口用于通过会话ID获取会话所有消息,目前限定企业访问频次为每秒不能超过5次。 参数:sessionId,长整型,会话的ID;(可选)mTypes,字符串类型,消息类型编号逗号分割,用于筛选指定类型消息。
如果一切检查通过,那么该接口会立即返回,其中"data"值是就是对应的结果, 一个JSON,字段详情见字段说明的Message说明。
{"code":200,"message":"success", "data": {}}
# 字段说明
- session说明如下:
字段 | 数据库中字段类型和长度 | 含义 | 规则细节 |
---|---|---|---|
id | bigint(20) | 会话ID | 全局唯一 |
startTime | bigint(20) | 会话开始时间 | 单位毫秒 |
endTime | bigint(20) | 会话结束时间 | 单位毫秒 |
sType | tinyint(4) | 会话类型 | 0:正常会话.1(2):离线留言,3:未接入会话,4:群聊,5:群聊离线留言 |
treatedTime | bigint(20) | 留言处理时间(如果该会话是留言) | 单位毫秒 |
category | varchar(128) | 会话末级咨询分类 | 末级咨询分类名 |
categoryDetail | varchar(128) | 会话咨询分类明细 | 一级分类名/二级分类名/三级分类名/四级分类名/五级分类名 |
evaluation | tinyint(4) | 满意度值 | 2:(100满意; 1不满意);3:(100满意; 50一般; 1不满意);5:(100非常满意; 75满意; 50一般; 25不满意; 1非常不满意)否则未评价 |
evaluationType | bigint(20) | 满意度类型 | |
evaluationRemark | varchar(255) | 满意度评价内容 | |
staffInvitedEvaluateTime | bigint(20) | 客服邀评时间 | 单位毫秒 返回-1则为不存在该时间值 |
userJoinEvaluateTime | bigint(20) | 访客参评时间 | 单位毫秒 返回-1则为不存在该时间值 |
relatedType | tinyint(4) | 关联会话类型 | 0:无关联; 1=从机器人转接过来; 2:机器人会话转接人工; 3:历史会话发起; 4:客服间转接; 5:被接管; 6:排队中会话提前进线; 7:留言分配; 8:多机器人切换会话; 9:主企业转出到子企业; 10:从主企业转过来的会话; 11:子企业转出到主企业; 12:从子企业转过来的会话 |
relatedId | bigint(20) | 被关联的会话ID | 若是无关联则此字段未定义 |
interaction | tinyint(4) | 会话交互类型 | 0:客服正常会话,1:机器人会话,2:呼叫中心会话3=推送消息 |
closeReason | tinyint(4) | 会话结束原因 | 参照[接收会话结束通知]中的closeReason |
fromGroup | varchar(255) | 分流客服组名 | 或为空 |
fromGroupId | bigint(20) | 分流客服组ID | 或为空 |
fromStaff | varchar(255) | 会话来自哪个客服 | 或为空 |
inQueueTime | bigint(20) | 开始排队时间 | 若<=0忽略此字段 |
visitRange | bigint(20) | 与上一次来访的时间差 | 默认一年(360天),单位毫秒 |
vipLevel | tinyint(4) | VIP级别 | 0=非VIP用户 |
staffId | bigint(20) | 接待客服ID | <=0 则为机器人 |
staffName | varchar(255) | 接待客服名字 | 或为"机器人" |
userId | varchar(255) | 访客ID | |
foreignId | varchar(255) | 外部ID | 由企业提供 |
fromIp | varchar(64) | 访客来源ip | 或为空 |
fromPage | varchar(128) | 来源页 | 或为空 |
fromTitle | varchar(128) | 来源页标题 | 或为空 |
fromType | varchar(64) | 来源类型 | Ios:苹果设备; Android:安卓设备; Web:网页版(含H5); Wx:微信; wx_ma:微信小程序; Wb:微博; Open:消息接口 |
fromSubType | varchar(64) | 终端明细 | 来源类型的详细信息,与管理端导出会话的终端明细相同 |
customFiled | varchar(6000) | 自定义字段 | 所有自定义字段, 是一个 KV类型的JSON字段,而如果是级联类型自定义字段值见下述说明。 |
description | varchar(2046) | 备注内容 | 备注 |
transferRgType | varchar(128) | 转人工类型 | 机器人会话转成人工会话的触发原因 |
fromHumanTransfer | tinyint(4) | 是否来自客服转接 | 0:非转接会话;1:客服转接过来的会话 |
transferFromStaffName | varchar(128) | 转接来源分流客服名称 | 转接会话有该字段 |
transferFromGroup | varchar(128) | 转接来源分流客服组名称 | 转接会话有该字段 |
transferRemarks | varchar(2046) | 转接来源分流会话备注 | 转接会话有该字段 |
humanTransferSessionId | bigint(20) | 客服转接来源会话ID | 如果该会话不是客服转接过来的,该值为null,否则值为转接来源会话的ID |
worksheetIds | varchar(1000) | 会话关联工单ID | 会话关联工单id, 逗号分隔 |
roundNumber | bigint(20) | 会话回合数 | 会话回合数 |
status | tinyint(4) | 客服解决状态 | 0:未解决,1:已解决,2:解决中 |
userResolvedStatus | tinyint(4) | 评价解决状态 | 0:未选择,1:已解决,2:未解决 |
firstReplyCost | bigint(20) | 客服首次响应时长 | 访客首条消息与客服首次回复消息的时间间隔 |
avgRespDuration | bigint(20) | 客服平均响应时长 | 客服整个会话中的平均响应时长 |
isValid | tinyint(4) | 是否是有效会话 | 0:无效会话,1:有效会话 |
transferType | varchar(128) | 转接类型 | 静默转接/人工转接 |
staffMessageCount | tinyint(4) | 客服消息数 | 客服在整个会话中的消息总量 |
userMessageCount | tinyint(4) | 用户消息数 | 用户在整个会话中的消息总量 |
overflowFrom | varchar(128) | 溢出来源 | 会话溢出的来源客服组 |
alarmTimes | tinyint(4) | 告警次数 | 告警次数 |
staffFirstReplyTime | bigint(20) | 首次回复时间 | 客服首次响应的时间 |
stickDuration | bigint(20) | 置顶时长 | 会话置顶时长 |
clientFirstMessageTime | bigint(20) | 访客首条消息时间 | 访客首条消息时间 |
isEvaluationInvited | tinyint(4) | 是否邀请评价 | 0-没有邀评,1-客服主动邀评,2-系统自动邀评 |
beginer | tinyint(4) | 会话发起方 | 1:访客,2:客服 |
ender | tinyint(4) | 会话终止方 | 1:访客,2:客服,3:系统 |
originPlatform | varchar(128) | 来源渠道 | 来源渠道 |
searchKey | varchar(128) | 关键字 | 关键字 |
landPage | varchar(6000) | 着陆页url | 着陆页url |
satisfactionTags | list<string> | 评价标签 | 访客评价时选择的标签 |
satisfyMsgCount | int(11) | 答案好评数 | |
createTime | varchar(128) | 访客进入时间 | |
queueDuration | varchar(128) | 访客排队时长 | 访客排队时长,格式为<时:分:秒> |
sessionDuration | varchar(128) | 会话时长 | 会话持续时长,格式为<时:分:秒> |
visitTimes | varchar(128) | 重复咨询 | 大于0才展示 |
staffAccount | varchar(128) | 客服账号 | 客服账号 |
categoryId | bigint(20) | 客服组ID | 客服组ID,默认为0 |
overflowRuleName | varchar(128) | 溢出原因 | 溢出原因 |
overflowCondition | varchar(128) | 溢出条件 | 溢出条件 |
startReason | varchar(128) | 会话开始来源 | 会话开始的来源,比如"转自机器人" |
userIpCity | varchar(128) | 用户IP省市 | 用户IP所在省市 |
staffReceptionDuration | varchar(128) | 人工接待时长 | 人工接待时长,格式为<时:分:秒> |
videoRecordUrlList | List<String> | 视频记录地址 | 视频客服的存储地址,可自行拉取下载 |
preQueue | tinyint(4) | 是否是提前进线 | 1:提前进线,0:非提前进线 |
级联类型自定义字段其fieldValue格式如:
{
"path": "1级/1.1级", // 每一级的完整名称
"idpath": [1555974, 1555977], // 每一级对应的ID
"id": 1555977 //级联自定义字段ID
}
- message说明如下:
字段 | 数据库中字段类型和长度 | 描述 | 规则细节 |
---|---|---|---|
id | bigint(20) | 消息id | 全局唯一 |
sessionId | bigint(20) | 会话id | 全局唯一 |
staffId | bigint(20) | 客服id | <=0 则为机器人 |
staffName | varchar(255) | 客服名 | |
userId | bigint(20) | 访客id | |
userName | varchar(255) | 访客名 | |
from | tinyint(2) | 消息流向 | 1=来自访客0=来自客服 |
time | bigint(20) | 消息创建时间 | 单位毫秒 |
mType | tinyint(4) | 消息类型 | 系统消息:0-系统消息;1-文本消息;2-图片消息;3-语音消息;4-文件消息;5-视频消息;6-系统提示消息;100-自定义消息;110-机器人答案;111-机器人答案反馈;112-超时关闭前提醒;113-超时关闭提醒;114-工单流程消息;115-富文本消息;116-敏感词屏蔽消息;117-客服拒绝转接;118-客服提交工单消息;119-客服发送邀请评价;120-访客参评;121-主企业客服转接会话到子企业信息;122-客服邀请评价详情;123-emoji消息;124-客服转接到主企业 |
autoReply | tinyint(4) | 消息回复类型 | 0=手动1=自动 |
msg | varchar(10240) | 消息体 | 或为空 |
status | tinyint(2) | 消息状态 | 1-正常, 2-已撤回 |
isRichMedia | tinyint(4) | 是否富媒体类型 | 消息类型为:2-图片消息;3-语音消息;4-文件消息;5-视频消息;115-富文本消息,值为1,其他为0 |
evaluation | tinyint(4) | 机器人答案评价 | 0-不显示,1-没有评价,2-有用,3-没用 |
msgEvaluationContent | text | 差评内容 | 或为空 |
matchType | tinyint(4) | 匹配类型 | 0:未匹配 1:精确匹配 2:相似匹配,只对应机器人消息,访客和客服消息默认为0 |
matchKnowledgeId | bigint(20) | 匹配知识ID | 匹配知识ID,大于0表示精确匹配命中,其他小于等于0或者为空表示相似匹配或未匹配,只对应机器人消息,访客和客服消息默认为0 |
# 获取会话关联的用户信息
该接口主要用于与获取会话所属用户的信息,特别是该会话所属用户没有关联企业自己的UID时,其信息只是由客服人员手动在七鱼系统记录。企业可以通过本接口将用户信息回流到企业内部系统。由于用户没有关联企业自己的UID,因此调用本接口时,需要传入session id 作为参数。接口鉴权方式可参阅《消息接口文档》 (opens new window)
接口请求示例:
```
POST https://qiyukf.com/openapi/session/user/profile?appKey=1064deea1c3624c9ee26d1de5ce8481f&time=1463217187&checksum=2f13932c4b7c6888b12360a85261a11b8b543f64
Content-Type:application/json;charset=utf-8
```
请求字段说明:
参数 | 是否必须 | 参数说明 |
---|---|---|
sessionId | 是 | 查询该会话的用户的相关信息 |
请求内容示例:
```json
{
"sessionId": 1222
}
```
接口返回会话的用户的相关信息,格式为 JSON,字段说明如下:
数据键名 | 数据类型 | 数据说明 |
---|---|---|
id | Long | 可唯一标识一个用户的ID |
name | String | 名字 |
phone | String | 电话 |
foreign_id | String | 外部id |
address | String | 地址 |
vipLevel | String | VIP等级 |
foreign_id | String | 外部id |
remarks | String | 备注 |
customField | Map<Long, Object> | 自定义属性值id |
# 行为轨迹
发送数据主动推送用户行为轨迹
# 接口使用说明
请求接口:http://qiyukf.com/openapi/track/event/set
POST http://qiyukf.com/openapi/track/event/set?appKey=3ec34a7ab5305ff49959d5c5023ccabf
&time=1534316797&checksum=9b924c7adac9d31a6177fae51cdd86f0e7dee4da
- 接口鉴权 参考通用说明-数据校验 (opens new window)
- 接口类型 POST
- 接口参数 主要用于鉴权
参数 | 参数说明 |
---|---|
appKey | 企业的appKey |
checksum | SHA1(appSecret + md5 + time), 三个参数拼接的字符串,进行SHA1哈希计算,转化成16进制字符(String,小写) |
time | 当前 UTC 时间戳,从 1970 年 1 月 1 日 0 点 0 分 0 秒开始到现在的秒数 |
4.接口数据 接口返回数据在请求体内,主要是以JSON格式返回
数据键名 | 数据类型 | 数据说明 |
---|---|---|
foreignId | String | 第三方系统内用户的唯一表示id,字符串 |
time | Long | 行为时间,与url上的time有区别,url的time用于鉴权,这个time用于记录行为发生的时间 |
title | String | 行为title,当行为缩略显示时,仅显示其title |
desc | String | 行为具体描述,描述行为的情况,请传入Json对象,每个key-value会成对展示在界面上,注意本身在一个Json对象内传输数据,双引号要用转义符转义 |
请求body内容如下:
{
"foreignId": "abc175",
"time": 1534238116999,
"title": "示例",
"desc": "{\"abc\":\"cde\"}"
}
# 微信模板消息
该接口用于将企业发送给用户的资料,以微信模板消息的形式发出。使用该接口前,需要企业的公众号已添加相应的模板,且企业需要按照指定格式提供访问接口,供七鱼获取对应的数据。 通过该接口,七鱼提供了特定业务支持的数据源集。企业设置的模板中支持哪些数据,将对应数据的在模板中的key填入请求中即可完成设置。当用户查询时,七鱼会访问企业提供数据的接口,然后会将对应的数据根据模板配置填入,最后发给用户。
该接口目前仅支持设置物流类的模板信息。
POST请求为:
POST https://qiyukf.com/openapi/settings/wxTemplates?appKey=1064deea1c3624c9ee26d1de5ce8481f&time=1463216914&checksum=e72be4487b6fc03e0f914fc11e4053d771598d93
Content-Type:application/json;charset=utf-8
其中各参数说明可参见消息接口文档
设置物流类模板信息post请求内容字段列举如下:
{
"appId":"wxcxxxxxxxxx",
"logistic": {
"template_id":"s8BlawhJMXO4YWEvvsrBiBrxuBJzYwpk-HchuAa9jbc",
"top":"first",
"bottom":"remark",
"id": "keyword1",
"name":"keyword2",
"last_state": "keyword3",
"update_time": "keyword4",
"sender":"keyword5",
"sender_site":"keyword6",
"sender_phone":"keyword7",
"receiver":"keyword8",
"receiver_site":"keyword9",
"receiver_phone":"keyword10",
"order_id":"keyword11",
"order_time":"keyword12",
"price":"keyword13",
"status":"keyword14",
"good_name":"keyword15"
}
}
公共字段说明:
字段名 | 是否必须 | 说明 |
---|---|---|
appId | 是 | 公众号的appId,可在公众号后台查看。 |
logistic | 否 | 物流类模板信息,物流类必须,其他类无需设置。 |
物流类模板字段说明:
字段名 | 是否必须 | 说明 |
---|---|---|
template_id | 是 | 该模板的ID, 可在公众号后台看到 |
top | 否 | 显示在模板消息第一行的内容的key |
bottom | 否 | 显示在模板消息最后一行的内容的key |
id | 否 | 物流运单ID的key |
name | 否 | 快递公司名称的key |
last_state | 否 | 运单的最新状态 |
update_time | 否 | 最新状态的更新时间 |
sender | 否 | 寄件人的key |
sender_site | 否 | 寄出地址的key |
sender_phone | 否 | 寄件人联系电话的key |
receiver | 否 | 收件人的key |
receiver_site | 否 | 收件地址的key |
receiver_phone | 否 | 收件人电话的key |
order_id | 否 | 与运单关联的商品订单ID的key |
order_time | 否 | 商品下单时间或者寄件时间的key |
price | 否 | 商品价格或者快递单价格的key |
status | 否 | 商品订单状态或者运单状态的key |
good_name | 否 | 商品名称的key |
示例: 某个公众号添加了ID为 s8BlawhJMXO4YWEvvsrBiBrxuBJzYwpk-HchuAa9jbc 的模板,其格式为:
{{first.DATA}}
订单编号:{{keyword1.DATA}}
取件公司:{{keyword2.DATA}}
{{remark.DATA}}
调用设置接口的内容如下:
{
"appId": "wxcxxxxxxx",
"logistic": {
"template_id":"s8BlawhJMXO4YWEvvsrBiBrxuBJzYwpk-HchuAa9jbc",
"top":"first",
"bottom":"remark",
"id": "keyword1",
"name":"keyword2"
}
}
# 获取咨询分类
该接口用于获取企业管理后台配置的咨询分类,以五级树状结构的形式给出。
接口请求示例
POST https://qiyukf.com/openapi/online/session/category/list?appKey=1064deea1c3624c9ee26d1de5ce8481f&time=1463217187&checksum=2f13932c4b7c6888b12360a85261a11b8b543f64
Content-Type:application/json;charset=utf-8
请求字段说明:
参数 | 是否必须 | 参数说明 |
---|---|---|
type | 是 | 目前固定传1,代表获取在线会话的咨询分类 |
请求内容示例:
{
"type": 1
}
接口返回管理后台设置的咨询分类,格式为 JSON,字段说明如下:
数据键名 | 数据类型 | 数据说明 |
---|---|---|
id | Long | 可唯一标识一个分类的ID |
name | String | 咨询分类的名称 |
children | List | 该分类下的子分类 |
# 获取在线会话的服务小记记录
该接口用于获取会话所属的客服可以查看的服务小记模版(根据管理后台->客服工作台->服务小记字段模版中所指定的客服组确定客服可查看的模版)以及已经填写的服务小记记录
接口请求示例
POST https://qiyukf.com/openapi/online/session/customfield/template?appKey=1064deea1c3624c9ee26d1de5ce8481f&time=1463217187&checksum=2f13932c4b7c6888b12360a85261a11b8b543f64
Content-Type:application/json;charset=utf-8
请求字段说明:
参数 | 是否必须 | 参数说明 |
---|---|---|
sessionId | 是 | 获取在线会话的服务小记记录 |
请求内容示例:
{
"sessionId": 1222
}
接口返回会话的服务小记模版和已填写的服务小记相关信息,格式为JSON,字段说明如下
总的返回结果
数据键名 | 数据类型 | 数据说明 |
---|---|---|
templates | List<OpenCustomFieldTemplateVO> | 服务小记模版 |
selectedTemplateId | Long | 已选择的服务小记模版id |
historyFieldValues | List<OpenCustomFieldValueVO> | 已填写的服务小记信息 |
sessionInfo | OpenSessionInfoVO | 会话信息 |
服务小记模版信息(OpenCustomFieldTemplateVO)
数据键名 | 数据类型 | 数据说明 |
---|---|---|
id | Long | 可唯一标识一个服务小记模版的ID |
name | String | 模版名称 |
isDefault | Integer | 是否是默认模版 |
assignFields | List<OpenCustomFieldAssignVO> | 自定义字段列表 |
服务小记模版自定义字段(OpenCustomFieldAssignVO)
数据键名 | 数据类型 | 数据说明 |
---|---|---|
id | Long | 可唯一标识一个服务小记模版自定义字段的ID |
type | Integer | 字段类型(0:文本, 1:下拉菜单,2:多选, 3:时间控件) |
description | String | 描述 |
required | Integer | 是否必填(0: 非必填,1:必填) |
staffName | String | 客服名称 |
valueEditable | Integer | 是否可编辑 |
system | Integer | 0:自定义字段 ; 1:系统默认字段 |
fieldId | Long | 字段id |
已填写的服务小记信息(OpenCustomFieldValueVO)
数据键名 | 数据类型 | 数据说明 |
---|---|---|
fieldId | Long | 字段id |
fieldValue | String | 字段值 |
assignType | Integer | 类型(固定为0:在线会话) |
fieldName | Integer | 字段名 |
其中自定义字段如果是级联类型的,其fieldValue格式如:
{
"path": "1级/1.1级", // 每一级的完整名称
"idpath": [1555974, 1555977], // 每一级对应的ID
"id": 1555977 //级联自定义字段ID
}
会话分类信息(OpenSessionCategoryVO)
数据键名 | 数据类型 | 数据说明 |
---|---|---|
id | Long | 表示唯一分类的id |
name | String | 咨询分类名称 |
parentId | Long | 父咨询分类id |
rank | Integer | 排序 |
updateTime | Long | 更新时间 |
path | String | 会话的五级分类路径 |
pathIds | String | 会话的五级分类id |
会话信息(OpenSessionInfoVO)
数据键名 | 数据类型 | 数据说明 |
---|---|---|
resolvedStatus | Integer | 会话解决状态(0:未解决, 1:已解决, 2:解决中) |
category | OpenSessionCategoryVO | 咨询分类信息 |
remarks | String | 咨询备注 |
# 更新会话服务小记
该接口用于更新服务小记的模版填写信息,注意当已选定一个服务小记模版之后,此后的更新只能更新这个服务小记模版的自定义字段信息,不可再切换服务小记模版 接口请求示例
POST https://qiyukf.com/openapi/online/session/customfield/update?appKey=1064deea1c3624c9ee26d1de5ce8481f&time=1463217187&checksum=2f13932c4b7c6888b12360a85261a11b8b543f64
Content-Type:application/json;charset=utf-8
请求字段说明:
参数 | 字段类型 | 是否必须 | 参数说明 |
---|---|---|---|
sessionId | Long | 是 | 会话id |
status | Integer | 否 | 问题解决状态-客服(值为 (0:未解决, 1:已解决, 2:解决中)) |
category | Long | 否 | 咨询分类id |
description | String | 否 | 会话备注(长度上限500字符) |
customfield | String | 是 | 自定义字段(单行文本:长度上限100字符;多行文本:长度上限500字符;数字:长度上限100字符;单选:长度上限100字符;多选:长度上限100字符;时间:限制为毫秒时间戳) |
templateId | Long | 是 | 模版id |
请求内容示例:
{
"sessionId": 14976699,
"status": 1,
"category": 796963,
"description": "测试分类",
"customfield": "[
{\"id\": 29033,\"value\": \"示例2\"}
,{\"id\": 29034,\"value\": \"示例1\"},
]",
"templateId": 9002
}
接口返回会话的服务小记模版和已填写的服务小记相关信息,格式为JSON,字段说明同获取服务小记模版接口一致
# 商品、订单查询
# 一、 业务流程说明
通过设置订单、商品查询接口,支持访客自主查询信息,并发送至人工客服会话中。
三方服务需在设置-访客端,定义好以下3项内容:
a.三方查询服务地址(下面有接口定义)
b.每页查询数量
c.查询入口ICON
访客点击查询入口时,七鱼携带userId向三方查询服务地址发起请求。 ** 首次请求时不携带标签页ID(tabId),三方服务默认返回首个标签页信息
业务时序图
# 二、访客端样式
# 三、接口定义
七鱼向三方查询数据:
请求头:
参数 | 字段类型 | 是否必须 | 参数说明 |
---|---|---|---|
appId | String | 否 | 企业的appId |
nonce | String | 是 | 随机字符串 |
time | String | 是 | 当前UTC时间戳,秒为单位 |
checkSum | String | 是 | SHA1(appSecret+nonce+time)将三个参数拼接的字符串,进行SHA1哈希计算 |
请求体:
content-type: "application/json", 接口需要支持json形式的body请求
参数 | 字段类型 | 是否必须 | 参数说明 |
---|---|---|---|
pageNo | Integer | 是 | 当前页码(从1开始) |
pageSize | Integer | 是 | 每页展示信息数量(默认5) |
tabId | String | 否 | 商品订单列表中的标签页ID(若不传tabId,默认返回第一tab页数据。*即不传tabId时,代表用户第一个tab查询 |
userId | String | 是 | 用户ID |
三方返回查询数据:
参数 | 字段类型 | 是否必须 | 参数说明 |
---|---|---|---|
code | Integer | 是 | 返回码,如200 |
message | String | 是 | 错误信息 |
data | Object | 是 | 返回商品标签页信息 |
# data结构说明
参数 | 字段类型 | 是否必须 | 参数说明 |
---|---|---|---|
dataList | List | 否 | 标签页商品订单信息列表(入参未传tabId时,dataList默认返回第一个标签页数据)不支持订单&商品混合,只能单类型消息传递 |
tabList | List | 是 | 标签页列表,标签页数量不可超过5个 |
currentTabId | String | 是 | 当前标签页ID |
pageNo | Integer | 是 | 页码(从1开始) |
pageSize | Integer | 是 | 页大小 |
total | Long | 是 | 记录数 |
# dataList结构说明
eventType=1时,订单字段对应显示位置如下:
参数 | 字段类型 | 是否必须 | 参数说明 |
---|---|---|---|
orderId | String | 是 | 订单ID |
orderTime | String | 否 | 时间,例:2021-01-21 01:00 |
orderSku | String | 否 | sku描述 |
orderCount | Integer | 否 | 数量 |
orderStatus | String | 否 | 状态描述,如:已发货、待支付 |
eventType | Integer | 是 | 共两种类型:1-订单,2-商品 |
picture | String | 是 | 缩略图url |
title | String | 是 | 标题 |
desc | String | 否 | 描述 |
payMoney | String | 否 | 价格,例如:¥19.99 |
eventType=2时,商品字段对应显示位置如下:
信息按照如下字段对应位置显示
参数 | 字段类型 | 是否必须 | 参数说明 |
---|---|---|---|
eventType | Integer | 是 | 共两种类型:1-订单,2-商品 |
picture | String | 是 | 缩略图url |
title | String | 是 | 标题 |
desc | String | 否 | 描述 |
price | String | 否 | 价格,例如:¥19.99 |
url | String | 否 | 商品卡片点击跳转链接 |
tabList结构说明
参数 | 字段类型 | 是否必须 | 参数说明 |
---|---|---|---|
tabId | String | 是 | 标签页ID |
tabName | String | 是 | 标签页名称 |
请求示例
curl --location --request POST 'https://{yourAddress}' \
--header 'checksum: f29fb3e9707142f7e74e539b5adaa788628d6b1e' \
--header 'time: 1642415268' \
--header 'appId: nehiuylkdifhhids' \
--header 'nonce: zdfdiufedofxncbn' \
--header 'Content-Type: application/json' \
--data-raw '{
"pageNo": 1,
"pageSize": 5,
"userId": "342566432",
"tabId": "first"
}'
返回示例
订单
{
"code": 200,
"message": "查询成功",
"data": {
"pageNo": 1,
"pageSize": 3,
"operateTitle": "请选择你要咨询的内容",
"total": 10,
"currentTabId": "first",
"dataList": [
{
"orderName": "订单号",
"orderId": "00000000000000000001",
"orderTime": "2021-08-23 19:23",
"skuName": "可口可乐瓶装 330ml",
"orderCount": 5,
"orderStatus": "未发货",
"eventType": 1,
"picture": "https://gimg2.baidu.com/image_search",
"title": "可口可乐 330ml",
"desc": "2022春节大促",
"price": "¥19.99"
},
{
"orderName": "订单号",
"orderId": "00000000000000000002",
"orderTime": "2021-08-23 19:24",
"skuName": "可口可乐瓶装 450ml",
"orderCount": 5,
"orderStatus": "未发货",
"eventType": 1,
"picture": "https://gimg2.baidu.com/image_search2",
"title": "可口可乐 330ml",
"desc": "2022元旦大促",
"price": "¥29.99"
}
],
"tabList": [
{
"tabId": "first",
"tabName": "未发货"
},
{
"tabId": "second",
"tabName": "已发货"
},
{
"tabId": "third",
"tabName": "售后"
},
{
"tabId": "fifth",
"tabName": "待配送"
}
]
}
}
商品
{
"code":200,
"message":"查询成功",
"data":{
"pageNo":1,
"pageSize":3,
"operateTitle":"请选择你要咨询的内容",
"total":10,
"currentTabId":"first",
"dataList":[
{
"url":"http://baidu.com",
"eventType":2,
"picture":"https://gimg2.baidu.coml",
"title":"可口可乐 330ml",
"desc":"2022春节大促",
"price":"19.99"
},
{
"url":"http://baidu.com/2",
"eventType":2,
"picture":"https://gimg2.baidu.coml",
"title":"可口可乐 220ml",
"desc":"2022元旦大促",
"price":"19.99"
}
],
"tabList":[
{
"tabId":"first",
"tabName":"未发货"
},
{
"tabId":"second",
"tabName":"已发货"
},
{
"tabId":"third",
"tabName":"售后"
},
{
"tabId":"fifth",
"tabName":"待配送"
}
]
}
}
# 实时消息推送
# 验证消息的确来自七鱼
当点击“保存”提交以上信息时, 七鱼会发送一条验证消息到填写的URL,发送方法为POST。 企业的接收消息服务器接收到验证请求后,需要作出正确的响应才能通过URL验证
企业在获取请求时需要做Urldecode处理,否则可能会验证不成功
假设接收消息地址设置为:http://api.custom.notify.com ,七鱼将向该地址发送如下验证请求:
请求方式:POST 请求地址:http://api.custom.notify.com/?appkey=APP_KEY&time=13500001234&nonce=123412323&echostr=ENCRYPT_STR&checksum=RTYUQWEXZCVAQFASDFASCYR
参数 | 字段类型 | 是否必须 | 参数说明 |
---|---|---|---|
appkey | String | 是 | 可在扩展与集成-开发者ID-AppKey中查看 |
time | Integer | 是 | 时间戳,单位为秒 |
nonce | String | 是 | 随机数 |
echostr | String | 是 | 加密的字符串。需要解密得到消息内容明文 |
checksum | String | 是 | 加密签名,checksum结合了企业AppSecret、请求中的timestamp、nonce参数、加密的消息体 |
企业后台收到请求后,需要做如下操作:
- 对收到的请求做Urldecode处理
- 解密echostr参数得到消息内容(即msg字段)
- 在1秒内响应POST请求,响应内容为上一步得到的明文消息内容(不能加引号,不能带bom头,不能带换行符)
以上2~3步骤可以直接使用验证URL函数一步到位。 之后接入验证生效,接收消息开启成功。
# 验证URL函数
本函数实现:
- 签名校验
- 解密数据包,得到明文消息内容
public String getUrl(@RequestParam("nonce") String nonce,
@RequestParam("time") String timestamp,
@RequestParam("echostr") String echostr,
@RequestParam("checksum") String checksum,
@RequestParam("appkey") String appkey) throws Exception {
String echostrDecode = URLDecoder.decode(echostr, "UTF-8");
String signature = SHA1Util.getSHA1(appkey, timestamp, nonce, echostrDecode);
if (!signature.equals(checksum)) {
return "error";
}
String appSecret = ""; //可在扩展与集成-开发者ID-AppSecret中查看
return decrypt(appSecret, echostrDecode);
}
public static String decrypt(String customMsgSecret, String text) throws Exception {
byte[] original;
try {
// 使用BASE64对密文进行解码
byte[] encrypted = Base64.getUrlDecoder().decode(text);
// 解密
original = cipherData(customMsgSecret, false, encrypted);
} catch (Exception e) {
return null;
}
String content;
try {
// 去除补位字符
byte[] bytes = PKCS7Encoder.decode(original);
// 分离16位随机字符串,网络字节序和AppId
byte[] networkOrder = Arrays.copyOfRange(bytes, 16, 20);
int xmlLength = recoverNetworkBytesOrder(networkOrder);
content = new String(Arrays.copyOfRange(bytes, 20, 20 + xmlLength), CHARSET);
} catch (Exception e) {
return null;
}
return content;
}
int recoverNetworkBytesOrder(byte[] orderBytes) {
int sourceNumber = 0;
for (int i = 0; i < 4; i++) {
sourceNumber <<= 8;
sourceNumber |= orderBytes[i] & 0xff;
}
return sourceNumber;
}
public static byte[] cipherData(String customMsgSecret, boolean encrypt, byte[] data) throws Exception {
byte[] iv = new byte[16];
System.arraycopy(customMsgSecret.getBytes(), 0, iv, 0, 16);
CipherParameters ivAndKey = new ParametersWithIV(new KeyParameter(customMsgSecret.getBytes()), iv);
BufferedBlockCipher aes = new BufferedBlockCipher(new CBCBlockCipher(
new AESEngine()));
aes.init(encrypt, ivAndKey);
int minSize = aes.getOutputSize(data.length);
byte[] outBuf = new byte[minSize];
int length1 = aes.processBytes(data, 0, data.length, outBuf, 0);
int length2 = aes.doFinal(outBuf, length1);
int actualLength = length1 + length2;
byte[] result = new byte[actualLength];
System.arraycopy(outBuf, 0, result, 0, result.length);
return result;
}
class PKCS7Encoder {
static Charset CHARSET = Charset.forName("utf-8");
static int BLOCK_SIZE = 32;
/**
* 获得对明文进行补位填充的字节.
*
* @param count 需要进行填充补位操作的明文字节个数
* @return 补齐用的字节数组
*/
static byte[] encode(int count) {
// 计算需要填充的位数
int amountToPad = BLOCK_SIZE - (count % BLOCK_SIZE);
if (amountToPad == 0) {
amountToPad = BLOCK_SIZE;
}
// 获得补位所用的字符
char padChr = chr(amountToPad);
String tmp = new String();
for (int index = 0; index < amountToPad; index++) {
tmp += padChr;
}
return tmp.getBytes(CHARSET);
}
/**
* 删除解密后明文的补位字符
*
* @param decrypted 解密后的明文
* @return 删除补位字符后的明文
*/
static byte[] decode(byte[] decrypted) {
int pad = (int) decrypted[decrypted.length - 1];
if (pad < 1 || pad > 32) {
pad = 0;
}
return Arrays.copyOfRange(decrypted, 0, decrypted.length - pad);
}
/**
* 将数字转化成ASCII码对应的字符,用于对明文进行补码
*
* @param a 需要转化的数字
* @return 转化得到的字符
*/
static char chr(int a) {
byte target = (byte) (a & 0xFF);
return (char) target;
}
}
public class SHA1Util {
/**
* 用SHA1算法生成安全签名
* @param token 票据
* @param timestamp 时间戳
* @param nonce 随机字符串
* @param encrypt 密文
* @return 安全签名
*/
public static String getSHA1(String token, String timestamp, String nonce, String encrypt)
{
try {
String[] array = new String[] { token, timestamp, nonce, encrypt };
StringBuffer sb = new StringBuffer();
// 字符串排序
Arrays.sort(array);
for (int i = 0; i < 4; i++) {
sb.append(array[i]);
}
String str = sb.toString();
// SHA1签名生成
MessageDigest md = MessageDigest.getInstance("SHA-1");
md.update(str.getBytes());
byte[] digest = md.digest();
StringBuffer hexstr = new StringBuffer();
String shaHex = "";
for (int i = 0; i < digest.length; i++) {
shaHex = Integer.toHexString(digest[i] & 0xFF);
if (shaHex.length() < 2) {
hexstr.append(0);
}
hexstr.append(shaHex);
}
return hexstr.toString();
} catch (Exception e) {
e.printStackTrace();
}
}
}
# 推送数据数据格式
该服务能够提供三个事件推送:
事件类型 | 说明 |
---|---|
CLIENT_MARK_READ | 会话已读事件 |
STAFF_MESSAGE | 坐席消息 |
CLIENT_MESSAGE | 访客消息 |
- CLIENT_MARK_READ数据格式如下:
{
"createtime": 1625932727657,
"msgidclient": "6383959733#0#36946076bba94a2bb0780bf748606f8c",
"session_id": 6383959733,
"content": "投诉",
"from_user": 1,
"foreign_id": "81275614-ff4c-490e-9517-0934f4fc9325@顺风车乘客",
"autoreply": 0,
"user_id": 20627473396,
"staff_id": 4126122,
"id": 31050959281,
"updatetime": 1625932727657,
"corp_id": 3517575,
"msgtype": "TEXT",
"status": 1
}
- STAFF_MESSAGE数据格式如下:
{
"createtime": 1625932729758,
"msgidclient": "6383962892#7e2bc2663af43b5f295d185a2356b0b7",
"session_id": 6383962892,
"content": "请问您还有其他问题需要帮助的吗?",
"from_user": 0,
"foreign_id": "da27aef3-9888-4fb1-9e82-f3fa4764b65b@顺风车乘客",
"autoreply": 0,
"user_id": 17854991208,
"staff_id": 6016458,
"id": 31050960420,
"updatetime": 1625932729758,
"corp_id": 3517575,
"msgtype": "TEXT",
"status": 1
}
- CLIENT_MESSAGE数据格式如下:
{
"foreign_id": "da27aef3-9888-4fb1-9e82-f3fa4764b65b@顺风车乘客",
"user_id": 17854991208,
"lastest_read_time": 1625932730420,
"staff_id": 6016458,
"session_id": 6383962892,
"corp_id": 3517575
}
参数说明:
字段 | 数据库中字段类型和长度 | 描述 | 规则细节 |
---|---|---|---|
createtime | bigint(20) | 消息创建时间 | 单位毫秒 |
msgidclient | varchar(128) | 消息ID | 客户端消息id |
session_id | bigint(20) | 会话ID | 全局唯一 |
content | varchar(10240) | 消息内容 | |
from_user | tinyint(2) | 消息发送方 | 1=来自访客;0=来自客服 |
foreign_id | varchar(255) | 访客ID | 由企业自定义,并通过前端能力给到七鱼 |
autoreply | tinyint(4) | 是否是自动回复 | 1=自动;0=手动(人工回复) |
user_id | bigint(20) | 访客ID | 七鱼内部访客ID |
staff_id | bigint(20) | 客服ID | 七鱼内部客服ID |
id | bigint(20) | ID | |
updatetime | bigint(20) | 消息更新时间 | 单位毫秒 |
corp_id | bigint(20) | 企业ID | |
msgtype | varchar(32) | 消息类型 | TEXT=文本消息 |
status | tinyint(2) | 消息状态 | 1-正常; 2-已撤回 |
lastest_read_time | bigint(20) | 最后阅读时间 | 单位毫秒或为空(未读) |