这是本文档旧的修订版!


REST API渠道集成

开通REST API渠道并配置服务器信息后,客服向客户回复的消息,将被环信转发到服务器的回调地址中。该功能可用于环信客服云与第三方服务器之间的消息传递。

REST API渠道为旗舰版功能。

创建REST关联

REST API渠道支持创建多个REST关联,每个REST关联均可作为环信与您的服务器之间收发消息的通道。

创建REST关联:

  1. 进入“管理员模式 > 渠道管理 > REST API”页面;
  2. 点击“添加REST关联”按钮,填写关联名称、回调地址,并保存。

系统自动为您生成Client ID、Client Secret、发送消息API。Client ID和Client Secret用于向环信发送消息时的身份认证;“发送消息API”为您向环信发送消息时使用的REST API接口,方法为POST。

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);

其他代码示例: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:YbAEBJ0O9wchQf0QgYTAev3D6CYqL+6mBM+VsNrO7bE=
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.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一致
}