[NEW] Livechat messages rest APIs#10054
Conversation
| return RocketChat.API.v1.unauthorized(); | ||
| } | ||
|
|
||
| const info = Meteor.call('livechat:getInitialData', this.urlParams.visitorToken); |
There was a problem hiding this comment.
Which data you want to get here? This method is returning a lot of data not related to visitor's status
There was a problem hiding this comment.
@rodrigok we change this to pick only the fields below from initialData result:
- visitor
- room
- departments
- online
- agentData
| if (!this.bodyParams.visitor.token) { | ||
| return RocketChat.API.v1.failure('Body param "visitor.token" is required'); | ||
| } | ||
| const visitorToken = this.bodyParams.visitor.token; |
There was a problem hiding this comment.
Should check this.bodyParams.messages as an array and if not empty
There was a problem hiding this comment.
@rodrigok , we added some validations to messages param according to suggestions
| } | ||
|
|
||
| const initialData = Meteor.call('livechat:getInitialData', this.urlParams.visitorToken); | ||
| const info = _.pick(initialData, 'visitor', 'room', 'departments', 'online', 'agentData'); |
There was a problem hiding this comment.
Why do you need these fields? When I see the route's name I imagine it would return only the visitor's status.
There was a problem hiding this comment.
Hi @rodrigok, so, in the beginning, the requirement was to know if there is some agent available (online) and then take some actions, but during the implementation, we realized that other information would be important too, such as "room", "departments" (to direct the visitor to the right chat), and "agentData" (to inform the visitor the name of agent). In the end, we left the route endpoint only named as status. Do you think is better create another endpoint to this extra information or just renaming the endpoint from status to something wider meaning is enough?
There was a problem hiding this comment.
Hi @rodrigok,
I think of two ways to improve this
Proposal 1
is it better if we break that into two endpoints?
Visitor Endpoint: "http://host/api/v1/livechat/visitor/:visitorToken"
- visitor data
- visitor room
- agent serving visitor
Livechat Status: "http://host/api/v1/livechat/status"
- agents online
- available departments
Proposal 2
or maybe break into four endpoints:
Visitor Endpoint: "http://host/api/v1/livechat/visitor/:visitorToken"
- visitor data
- opened rooms for the visitor or all rooms for visitor
- with this endpoint we can check who is serving the visitor
Departments Endpoint: "http://host/api/v1/livechat/department"
- list all departments
- with this endpoint we can determine and show only available departments to the visitor (we can filter for enabled departments and with agents)
Agents Endpoint: "http://host/api/v1/livechat/agent"
- list all agents
- with this endpoint we can check for online agents (we can count online agents) and get agent details to show whos serving the visitor
Department endpoint already exists, but authentication is not based on the webhook token, its based on user login. We will need to deal with this.
What do you think? Is it better?
There was a problem hiding this comment.
Hi @hmagarotto I prefer the second option with multiple endpoints with more clear results
There was a problem hiding this comment.
Thank you @rodrigok , we'll start to make changes
|
@rodrigok I made the requested changes as proposed. The "department" and "agent" endpoint already existed. I added the name and status into agent user data. All endpoints are authenticated using REST login. Responses examples: {
"_id": "Woa3YMoaNuCziv9hW",
"username": "guest-8",
"department": "yfZZkAYZEsa8E8dQf",
"userAgent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.146 Safari/537.36",
"ip": "127.0.0.1",
"host": "localhost:3000",
"_updatedAt": "2018-03-27T00:56:50.261Z",
"token": "zCzPcfA73AaQ44RJs",
"visitorEmails": [
{
"address": "[email protected]"
}
],
"name": "Guest Name",
"success": true
}{
"rooms": [
{
"t": "l",
"cl": false,
"usernames": [
"agent.one"
],
"servedBy": {
"_id": "qzPNhHRKRnKXFqASi",
"username": "agent.one"
},
"_id": "PZ7Nbm573kbziXgcn"
}
],
"success": true
}{
"departments": [
{
"_id": "yfZZkAYZEsa8E8dQf",
"enabled": true,
"name": "SAC",
"description": "",
"numAgents": 1,
"showOnRegistration": true,
"_updatedAt": "2018-03-27T00:58:30.647Z"
}
],
"success": true
}{
"department": {
"_id": "yfZZkAYZEsa8E8dQf",
"enabled": true,
"name": "SAC",
"description": "",
"numAgents": 1,
"showOnRegistration": true,
"_updatedAt": "2018-03-27T00:58:30.647Z"
},
"agents": [
{
"_id": "RFgzKhhZWqCRdmBEw",
"agentId": "qzPNhHRKRnKXFqASi",
"departmentId": "yfZZkAYZEsa8E8dQf",
"username": "agent.one",
"count": 0,
"order": 0,
"_updatedAt": "2018-03-27T00:58:30.658Z"
}
],
"success": true
}{
"users": [
{
"_id": "yBx92hRyN5kdqiB4w",
"username": "henrique",
"name": "Henrique",
"status": "away",
"statusLivechat": "available"
},
{
"_id": "qzPNhHRKRnKXFqASi",
"username": "agent.one",
"name": "AgentOne",
"status": "offline",
"statusLivechat": "available"
}
],
"success": true
} |
| @@ -0,0 +1,64 @@ | |||
| import LivechatVisitors from '../../../server/models/LivechatVisitors'; | |||
|
|
|||
| RocketChat.API.v1.addRoute('livechat/messages', { | |||
There was a problem hiding this comment.
You are using RocketChat.authz.hasPermission, so you have to set { authRequired: true } to the route parameter.
| if (!this.bodyParams.visitor) { | ||
| return RocketChat.API.v1.failure('Body param "visitor" is required'); | ||
| } | ||
| if (!this.bodyParams.visitor.token) { |
There was a problem hiding this comment.
this.bodyParams.visitor.token doesn't work. You should use camelCased in the field names, such as this.bodyParams.visitorToken.
There was a problem hiding this comment.
@renatobecker the payload used in message post was based in the payload send to webhook.
This is the expected POST for this endpoint:
curl -v -H "Content-type: application/json" -H "${H_USERID}" -H "${H_AUTHTOKEN}" "http://localhost:3000/api/v1/livechat/messages" -d'{
"visitor": {
"token":"04aa15e2-31ed-11e8-ac97-93976ab3c67b",
"name": "Guest Name",
"email": "[email protected]",
"phone": {
"number": "+5511999999999"
}
},
"messages": [
{
"msg": "Hi!!"
}
]
}'
Webhook payloads: https://rocket.chat/docs/administrator-guides/livechat/
There was a problem hiding this comment.
Have you tried your code? We are talking about the name of a query parameter and the format you are using is not valid.
There was a problem hiding this comment.
Yes, we tried it. We are using a body parameter (JSON object) not a query parameter. And this format is to access field token inside visitor inside request body (application/json). This is why "visitor.token"
The "curl" below is working and will create a new guest as shown in the screenshot.
curl -s -H "Content-type: application/json" -H "${H_USERID}" -H "${H_AUTHTOKEN}" "http://localhost:3000/api/v1/livechat/messages" -d'{
"visitor": {
"token":"04aa15e2-31ed-11e8-ac97-93976ab3c67b",
"name": "Guest Name",
"email": "[email protected]",
"phone": {
"number": "+5511999999999"
}
},
"messages": [
{
"msg": "Hi!!"
}
]
}'
There was a problem hiding this comment.
If you want to try, here is the whole script:
https://gist.github.com/hmagarotto/6251f86e1f00035cc249c8ef05238a90
There was a problem hiding this comment.
OK, sorry. I was testing this in another way.
| if (!this.bodyParams.visitor) { | ||
| return RocketChat.API.v1.failure('Body param "visitor" is required'); | ||
| } | ||
| if (!this.bodyParams.visitor.token) { |
There was a problem hiding this comment.
Have you tried your code? We are talking about the name of a query parameter and the format you are using is not valid.
|
By http://localhost:3000/api/v1/livechat/messages method I get an error "Cannot read property 'id' of undefined" after dozens successful requests. Only refreshing the token helps, but not for long. New guest chat is visibly, and 1-st guest message is visibly too in hint agent window. But when agent takes that chat, guest message doesn't display at chat. |
|
Hi @ilyamsts. Thanks. |

@RocketChat/core
This PR added one API route to allow some external integrator send a message to a livechat room as a visitor and make guest registration if necessary. Additionally, one endpoint to check agent availability was added.
The payload to send a message was derived from the payload send to webhook.