====== REST API渠道集成 ======
开通REST API渠道并配置服务器信息后,客服向客户回复的消息,将被环信转发到服务器的回调地址中。该功能可用于环信客服云与第三方服务器之间的消息传递。
注:REST API渠道为旗舰版功能。
===== 创建REST关联 =====
REST API渠道支持创建多个REST关联,每个REST关联均可作为环信与您的服务器之间收发消息的通道。
创建REST关联:
- 进入“管理员模式 > 渠道管理 > REST API”页面;
- 点击“添加REST关联”按钮,填写关联名称、回调地址,并保存。
系统自动为您生成Client ID、Client Secret、发送消息API。Client ID和Client Secret用于向环信发送消息时的身份认证;“发送消息API”为您向环信发送消息时使用的REST API接口,方法为POST。
{{:cs:300visitoraccess:admin-channel-restapi.png?nolink|REST API渠道}}
===== 身份认证 =====
当您的服务器使用REST关联中的“发送消息API”向环信客服云发送消息时,需要通过环信的身份认证。环信使用HMAC(Hashed Message Authentication Code,散列消息身份认证码)进行身份认证。
==== 请求头 ====
在发送消息的API中添加如下请求头:
X-Auth-Expires: 1234567
Content-Type: application/json; utf-8
Authorization: hmac {Client ID}:{signature}
X-Auth-Expires 为签名过期时间,必须使用时间戳,单位毫秒;比如当前时间为 'Tue Mar 14 19:20:54 2017',时间戳为 1489490454142,如果想让签名在1分钟后过期,则 X-Auth-Expires: 1489490514142。如果时间戳为非正值,则表示不过期。
Authorization 中 signature 使用 Client Secret 通过 hmac-SHA256 算法生成。
==== Signature生成规则 ====
Signature生成规则如下:
base64(hmac-sha256(Client_SECRET, HTTP-Verb + "\n"
+ RESOURCE_PATH + "\n"
+ X-Auth-Expires + "\n"
+ md5(CONTENT)
))
==== Signature计算示例 ====
例如下面这个请求:
* Client ID: 283e8488-06d6-43d4-b8a8-d8f0a300f4ce
* Client Secret: 02a0693ba5a57560df1f26a991204cb0
POST /api/tenants/5950/rest/channels/20/messages HTTP/1.1
Content-Type: application/json; utf-8
X-Auth-Expires: 1489490514142
{"bodies":[{"msg":"testmsg2","type":"txt"}],"ext":{"queue_id":"","queue_name":"","agent_username":"","visitor":{"user_nickname":"userNickname","true_name":"userTrueName","qq":"999999999","email":"test@test.test","phone":"18888888888","company_name":"companyName","description":"description"}},"msg_id":"14332423141234234","origin_type":"rest","from":"test_weichat_visitor05","timestamp":1468832767680}
=== 第 1 步:计算md5(CONTENT) ===
CONTENT为Request body的内容(JSON格式,没有空格和换行)。
上述示例的计算结果为: 705bfbd388d2bf852813fc90e655b5ed;所以待加密字符串为:
POST\n/api/tenants/5950/rest/channels/20/messages\n1489490514142\n705bfbd388d2bf852813fc90e655b5ed
=== 第 2 步:根据Client Secret与待加密字符串计算signature ===
使用hmac-sha256加密,然后对其返回的原始二进制数据进行base64编码。
上述示例的计算结果为: yLgHjb8GckRpZ2uW8kb0qipODRkaFCIBNQsnZ2vhGMo=
Java 代码示例:
String secret = "02a0693ba5a57560df1f26a991204cb0";
String message = "POST\n/api/tenants/5950/rest/channels/20/messages\n1489490514142\n705bfbd388d2bf852813fc90e655b5ed";
final SecretKeySpec keySpec = new SecretKeySpec(secret.getBytes(), "HmacSHA256");
final Mac mac = Mac.getInstance("HmacSHA256");
mac.init(keySpec);
final byte[] result = mac.doFinal(message.getBytes());
Base64.getEncoder().encodeToString(result);
其他代码示例:[[https://www.jokecamp.com/blog/examples-of-creating-base64-hashes-using-hmac-sha256-in-different-languages/|Examples of creating base64 hashes using HMAC SHA256 in different languages]]
=== 第 3 步:添加 Authorization 请求头 ===
完整请求如下:
POST /api/tenants/5950/rest/channels/20/messages HTTP/1.1
Content-Type: application/json; utf-8
Authorization: hmac 283e8488-06d6-43d4-b8a8-d8f0a300f4ce:yLgHjb8GckRpZ2uW8kb0qipODRkaFCIBNQsnZ2vhGMo=
X-Auth-Expires: 1489490514142
{"bodies":[{"msg":"testmsg2","type":"txt"}],"ext":{"queue_id":"","queue_name":"","agent_username":"","visitor":{"user_nickname":"userNickname","true_name":"userTrueName","qq":"999999999","email":"test@test.test","phone":"18888888888","company_name":"companyName","description":"description"}},"msg_id":"14332423141234234","origin_type":"rest","from":"test_weichat_visitor05","timestamp":1468832767680}
===== 投递客户消息到环信 =====
支持投递文本、图片、语音、视频消息到环信客服云。并且,可以在消息中增加ext扩展字段,以实现更多个性化功能。
==== 消息示例 ====
**注意:**
以下消息格式仅为JSON示例,计算signature和投递消息时请删除所有空格、换行、注释。
=== 文本消息 ===
发送文本消息的Request body格式:
{
"bodies": [
{
"msg": "testmsg2", // 消息内容
"type": "txt" // 消息类型,支持文本(txt)、图片(img)、语音(audio)、视频(video)消息
}
],
"ext": {
"queue_id": "", // 可选,技能组ID,用于指定技能组
"queue_name": "", // 可选,技能组名称,用于指定技能组
"agent_username": "", // 可选,客服登录邮箱,用于指定客服
"visitor": { // 客户信息
"user_nickname": "userNickname", // 客户昵称
"true_name": "userTrueName", // 客户的真实姓名
"qq": "999999999", // 客户的QQ号码
"email": "test@test.test", // 客户的电子邮件地址
"phone": "18888888888", // 客户的电话号码
"company_name": "companyName", // 客户的公司名称
"description": "description", // 客户的描述
"tags":["vip1", "vip2"] // 可选,用于VIP客户在待接入中插队
}
},
// 可选,消息ID,环信根据msg_id对消息进行去重,每条消息需要有唯一的msg_id
"msg_id": "14332423141234234",
// 渠道类型,固定值为rest
"origin_type": "rest",
// 客户ID,显示在“资料”页签,如果客户为微信公众号的粉丝,建议填写“原始ID+openid”
"from": "test_weichat_visitor05",
// 消息发送的时间
"timestamp": 1468832767680
}
=== 图片消息 ===
发送图片消息的Request body格式:
{
"bodies": [
{
"type": "img", // 消息类型,图片消息
"url": "https://172.17.2.154:9090/images/entry/logo.png", // 图片的下载地址
"filename": "logo.png", // 图片名称
"size": {
"width": 480, // 可选,图片宽度,单位:px
"height": 720 // 可选,图片高度,单位:px
}
}
],
"ext": {
"queue_id": "",
"queue_name": "",
"agent_username": "",
"visitor": {
"user_nickname": "userNickname",
"true_name": "userTrueName",
"qq": "999999999",
"email": "test@test.test",
"phone": "18888888888",
"company_name": "companyName",
"description": "description"
}
},
"msg_id": "14332423141234234",
"origin_type": "rest",
"from": "test_weichat_visitor05",
"timestamp": 1468832767680
}
=== 语音消息 ===
发送语音消息的Request body格式:
{
"bodies": [
{
"type": "audio", // 消息类型,语音消息
"url": "https://172.17.2.154:9090/media/msg.mp3", // 语音文件的下载地址
"filename": "msg.mp3", // 语音文件名称
"length": 1 // 可选,语音消息的时长,单位:秒
}
],
"ext": {
"queue_id": "",
"queue_name": "",
"agent_username": "",
"visitor": {
"user_nickname": "userNickname",
"true_name": "userTrueName",
"qq": "999999999",
"email": "test@test.test",
"phone": "18888888888",
"company_name": "companyName",
"description": "description"
}
},
"msg_id": "14332423141234234",
"origin_type": "rest",
"from": "test_weichat_visitor05",
"timestamp": 1468832767680
}
=== 视频消息 ===
发送视频消息的Request body格式:
{
"bodies": [
{
"type": "video", // 消息类型,视频消息
"url": "https: //a1.easemob.com/easemob-demo/chatdemoui/chatfiles/671dfe30-7f69-11e4-ba67-8fef0d502f46", // 视频文件的下载地址
"filename": "1418105136313.mp4", // 视频文件名称
"length": 10 // 可选,视频消息的时长,单位:秒
}
],
"ext": {
"queue_id": "",
"queue_name": "",
"agent_username": "",
"visitor": {
"user_nickname": "userNickname",
"true_name": "userTrueName",
"qq": "999999999",
"email": "test@test.test",
"phone": "18888888888",
"company_name": "companyName",
"description": "description"
}
},
"msg_id": "14332423141234234",
"origin_type": "rest",
"from": "test_weichat_visitor05",
"timestamp": 1468832767680
}
==== 扩展功能 ====
在客户消息中增加ext扩展字段,可以实现更多个性化功能,包括:显示客户信息、指定技能组、指定客服、VIP客户插队、发送订单消息、发送轨迹消息,等等。
=== 显示客户信息 ===
通过在''visitor''字段中指定客户信息,可以将这些客户信息显示在客服云中会话页面的“资料”页签。
"ext": {
"visitor": { // 客户信息
"user_nickname": "userNickname", // 客户昵称
"true_name": "userTrueName", // 客户的真实姓名
"qq": "999999999", // 客户的QQ号码
"email": "test@test.test", // 客户的电子邮件地址
"phone": "18888888888", // 客户的电话号码
"company_name": "companyName", // 客户的公司名称
"description": "description", // 客户的描述
}
},
=== 指定技能组 ===
通过在''ext''字段中指定技能组ID或技能组名称,可以指定会话分配的技能组。推荐使用技能组名称指定技能组,技能组名称需与客服云“管理员模式 > 成员管理 > 技能组”页面设置的技能组名称一致,中英文均可。
在扩展字段中指定技能组的方式,对应于客服云“管理员模式 > 设置 > 会话分配规则”页面的“入口指定”。
"ext": {
"queue_id": "", // 可选,技能组ID,用于指定技能组
"queue_name": "", // 可选,技能组名称,用于指定技能组
},
=== 指定客服 ===
通过在''ext''字段中指定客服登录邮箱,可以指定会话分配的客服。如果指定了客服,会话将直接分配给对应的客服,进入客服的“进行中”会话列表。
注:客服离线时,可能无法及时接待会话。
"ext": {
"agent_username": "", // 可选,客服登录邮箱,用于指定客服
},
=== VIP客户插队 ===
通过设置''tags''字段,可以实现VIP客户插队的功能。当客服全忙时,VIP客户可插队到“待接入”队列的队首,有空闲客服出现时,优先接入。
客户发起会话时,凡是”tags”字段非空的客户都会直接排在待接入队列的最前面。当有多个客户包含非空的”tags”字段时,这些客户单独按会话发起时间排队。
"ext": {
"visitor": { // 客户信息
"tags":["vip1", "vip2"] // 可选,用于VIP客户在待接入中插队
}
},
=== 发送订单消息 ===
通过在''ext''字段中指定订单标题、金额、描述、图片、路径等信息,可以把订单消息发给访客。
"ext": {
"msgtype": {
"order": {
"title":"我的订单", //订单标题
"order_title":"订单号:1513256", //订单编号
"price":"¥: 555.00", //订单金额
"desc":"潮流背包", //订单描述
"img_url":"http://o8ugkv090.bkt.clouddn.com/hd_two.png", //商品图片
"item_url":"https://yourdomain.com/item/a.html" //商品路径
}
}
},
=== 发送轨迹消息 ===
通过在''ext''字段中指定标题、价格、描述、图片、路径等信息,可以把轨迹消息发给访客。
"ext": {
"msgtype": {
"track": {
"title":"我正在看:", //商品标题
"price":"¥: 235.00", //商品价格
"desc":"潮流女鞋", //商品描述
"img_url":"http://o8ugkv090.bkt.clouddn.com/hd_three.png", //商品图片
"item_url":"https://yourdomain.com/item/a.html" //商品路径
}
}
},
===== 接收客服回复的消息 =====
环信将客服回复的消息(文本、图片、语音、文件消息)投递到REST关联的服务器回调地址。收到客服消息后,需要对消息进行解析,并转发给对应的客户(to字段指定的客户ID)。
==== 消息示例 ====
客服消息的消息体bodies内容与投递消息到环信的格式一致。
图片消息示例:
{
"bodies": [
{
"type": "img", // 消息类型,支持文本(txt)、图片(img)、语音(audio)、文件(file)消息
"url": "https://kefu.sh.easemob.com/v1/Tenant/11784/MediaFiles/8350c049-c36d-4b63-8d02-e535ec9de2865L2T6aqM5YWz6IGU77yIZ2F0ZXdhee-8iS5wbmc=",
"filename": "testImg.png",
"size": {
"width": 602,
"height": 439
}
}
],
"ext": {
"msg_id": "cff22371-6eed-42ee-81ad-5923993fd8e8",
"visitor": {
"user_nickname": "userNickname",
"true_name": "userTrueName",
"qq": "999999999",
"email": "test@test.test",
"phone": "18888888888",
"company_name": "companyName",
"description": "description",
"weixin": null,
"tags": null,
"callback_user": "test_weichat_visitor06" // 客户ID,与to字段的值一致
},
"agent": {
"avatar": null, // 客服头像
"user_nickname": "客服昵称" // 客服昵称
},
"queue_id": null,
"queue_name": "",
"agent_username": ""
},
"to": "test_weichat_visitor06", // 接收消息的客户ID,根据该ID判断将消息投递给哪位客户
"channel_type": "rest", // 关联类型,固定值为rest
"tenant_id": 11784, // 租户ID
"origin_type": "rest", // 渠道类型,固定值为rest
"channel_id": 1 // REST关联的ID,与发送消息API URL中的ID一致
}