====== REST API Integration ======
After you activate the REST API channel and configure the server information, agents' replies to the customers will be forwarded to the server's URL address. The REST API channel is used for messaging between Hyphenate and the third-party server.
The REST API channel is a value-added service. To activate it, please provide the tenant ID and contact Hyphenate.
===== Create REST Account =====
You can create multiple REST API channel accounts, each of which can serve as a channel for sending and receiving messages between Hyphenate and your server.
To create a REST API channel account:
- Go to "Admin Mode > Channels > REST API".
- Click **Add REST API Account**, fill in the account name, callback address, and click **Save**.
The system automatically generates the Client ID, Client Secret, and messaging API for you. Client ID and Client Secret are used for identity authentication when you send messages to Hyphenate. The messaging API, whose method is POST, is for you to send messages to Hyphenate.
{{:cs-en:admin:start-rest-api.png?nolink|REST API channel}}
===== Authentication =====
When your server calls the messaging API to send messages to Hyphenate Customer Engagement Cloud, the messages must be authenticated by Hyphenate. Hyphenate uses the Hash-based Message Authentication Code (HMAC) to authenticate the messages.
==== Request Header ====
Add the following request header to the messaging API:
X-Auth-Expires: 1234567
Content-Type: application/json; utf-8
Authorization: hmac {Client ID}:{signature}
X-Auth-Expires indicates the signature expiration time. It must be timestamped in milliseconds. For example, the current date and time is 'Tue Mar 14 19:20:54 2017' with the timestamp 1489490454142. If you want the signature to expire in 1 minute, set X-Auth-Expires to 1489490514142. If the timestamp is a negative value, it indicates that the signature does not expire.
In the Authorization field, {signature} is generated using Client Secret through the hmac-SHA256 algorithm.
==== Signature Generation Formula ====
Signature is generated using the following formula:
base64(hmac-sha256(Client_SECRET, HTTP-Verb + "\n"
+ RESOURCE_PATH + "\n"
+ X-Auth-Expires + "\n"
+ md5(CONTENT)
))
==== Signature Calculation Example ====
Use the following request as an example:
* 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}
=== Step 1: Calculate md5(CONTENT) ===
CONTENT is the request body (in JSON format, no spaces or newlines).
The result of the above example is 705bfbd388d2bf852813fc90e655b5ed, so the string to be encrypted is:
POST\n/api/tenants/5950/rest/channels/20/messages\n1489490514142\n705bfbd388d2bf852813fc90e655b5ed
=== Step 2: Calculate signature based on Client Secret and the string to be encrypted ===
Use hmac-sha256 encryption, and then use base64 encoding for the returned original binary data.
The result of the above example is yLgHjb8GckRpZ2uW8kb0qipODRkaFCIBNQsnZ2vhGMo=
Java code example:
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);
Other examples: [[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]]
=== Step 3: Add Authorization Request Header ===
The complete request is as follows:
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}
===== Deliver Customers' Messages to Hyphenate =====
You can send text, pictures, voice and video messages to Hyphenate Customer Engagement Cloud. Also, you can add ext extension fields to the messages to have extended functions.
==== Message Formats ====
**Note:**
The following message bodies are in the JSON format. Before calculating the signature and posting the messages, remove all the spaces, newlines, and comments.
=== Text Message ===
Request body of a text message:
{
"bodies": [
{
"msg": "testmsg2", // message content
"type": "txt" // message type, which can be text (txt), picture (img), voice (audio), video (video)
}
],
"ext": {
"queue_id": "", // optional. Team ID, used to specify a team
"queue_name": "", // optional. Team name, used to specify a team
"agent_username": "", // optional, agent's login email address, used to specify an agent
"visitor": { // customer profile
"user_nickname": "userNickname", // customer nickname
"true_name": "userTrueName", // customer's full name
"qq": "999999999", // customer's QQ ID
"email": "test@test.test", // customer's email address
"phone": "18888888888", // customer's phone number
"company_name": "companyName", // customer's company name
"description": "description", // description of the customer
"tags":["vip1", "vip2"] // optional. Identify VIP customers so that they can jump to the front of the queue
}
},
// optional. Message ID, uniquely identifies a message. Hyphenate uses msg_id to remove duplicate messages
"msg_id": "14332423141234234",
// channel type. The value is rest.
"origin_type": "rest",
// Customer ID, displayed on the Profile tab. If the customer is a WeChat follower, "origin ID + openid" is recommended.
"from": "test_weichat_visitor05",
// the time the message was sent
"timestamp": 1468832767680
}
=== Picture Message ===
Request body of a picture message:
{
"bodies": [
{
"type": "img",
"url": "http://172.17.2.154:9090/images/entry/logo.png",
"filename": "logo.png",
"size": {
"width": 480,
"height": 720
}
}
],
"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
}
=== Voice Message ===
Request body of a voice message:
{
"bodies": [
{
"type": "audio",
"url": "http://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
}
=== Video Message ===
Request body of a video message:
{
"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
}
==== Extended Functions ====
You can add ext extension fields to the messages to have extended functions, such as displaying customer profile, specifying the team, specifying the agent, and VIP customers.
=== Display Customer Profile ===
You can specify customer information in the ''visitor'' field, so that Hyphenate displays the customer information on the Profile tab.
"ext": {
"visitor": { // customer profile
"user_nickname": "userNickname", // customer nickname
"true_name": "userTrueName", // customer's full name
"qq": "999999999", // customer's QQ ID
"email": "test@test.test", // customer's email address
"phone": "18888888888", // customer's phone number
"company_name": "companyName", // customer's company name
"description": "description", // description of the customer
}
},
=== Specify Team ===
You can specify team ID or team name in the ''ext'' field, so that Hyphenate routes the conversations to the specified team. The name of the team must be exactly the same as the name of the team set on the Hyphenate Customer Engagement Cloud.
Specifying the team in the ''ext'' field corresponds to entry binding in routing rules. To set routing rules, go to “Admin Mode > Settings > System Settings > Routing”.
"ext": {
"queue_id": "", // optional. Team ID, used to specify a team
"queue_name": "", // optional. Team name, used to specify a team
},
=== Specify Agent ===
You can specify an agent's login email address in the ''ext'' field, so that Hyphenate assigns the conversations to the specified agent. When the agent is online, the new conversation goes directly to the ongoing conversation list of the agent.
Note: When the agent is offline, the conversation may not be served in a timely manner.
"ext": {
"agent_username": "", // optional, agent's login email address, used to specify an agent
},
=== VIP Customers ===
By setting the ''tags'' field, you can identify VIP customers. When all agents are busy, VIP customers can jump to the front of the queue so that they are served first once an agent is available.
VIP customers are places before non-VIP customers in the queue. If there are multiple VIP customers in the queue, the VIP customer who starts the conversation earliest will be served earliest.
"ext": {
"visitor": { // customer profile
"tags":["vip1", "vip2"] // optional. Identify VIP customers so that they can jump to the front of the queue
}
},
===== Receive Agents' Messages =====
Hyphenate sends agents' messages (text, pictures, voice, and files) to the callback address of your server. When you receive the agents' messages, you need to parse the messages and forward the messages to the corresponding customers (customer IDs specified by the ''to'' field).
==== Message Formats ====
The formats of agents' messages are the same as those of customers' messages.
Example of a picture message:
{
"bodies": [
{
"type": "img" // message type, which can be text (txt), picture (img), voice (audio), file (file)
"url": "http://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" // customer ID, same as in the to field
},
"agent": {
"avatar": null, // agent avatar
"user_nickname": "agent nickname" // agent nickname
},
"queue_id": null,
"queue_name": "",
"agent_username": ""
},
"to": "test_weichat_visitor06", // customer ID that the message is destined. Forward the message to the customer based on this customer ID
"channel_type": "rest", // channel account type. The value is rest.
"tenant_id": 11784, // tenant ID
"origin_type": "rest", // channel type. The value is rest.
"channel_id": 1 // ID of the REST account, same as ID in the messaging API URL
}