-
Notifications
You must be signed in to change notification settings - Fork 10.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[NEW] Livechat messages rest APIs #10054
[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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should check this.bodyParams.messages
as an array and if not empty
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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
Rooms Endpoint: "http://host/api/v1/livechat/visitor/:visitorToken/room"
- 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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi @hmagarotto I prefer the second option with multiple endpoints with more clear results
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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: Visitor: http://localhost:3000/api/v1/livechat/visitor/zCzPcfA73AaQ44RJs {
"_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": "guest@email.com"
}
],
"name": "Guest Name",
"success": true
} Rooms: http://localhost:3000/api/v1/livechat/visitor/zCzPcfA73AaQ44RJs/room {
"rooms": [
{
"t": "l",
"cl": false,
"usernames": [
"agent.one"
],
"servedBy": {
"_id": "qzPNhHRKRnKXFqASi",
"username": "agent.one"
},
"_id": "PZ7Nbm573kbziXgcn"
}
],
"success": true
} Departments: http://localhost:3000/api/v1/livechat/department {
"departments": [
{
"_id": "yfZZkAYZEsa8E8dQf",
"enabled": true,
"name": "SAC",
"description": "",
"numAgents": 1,
"showOnRegistration": true,
"_updatedAt": "2018-03-27T00:58:30.647Z"
}
],
"success": true
} Department Item: http://localhost:3000/api/v1/livechat/department/yfZZkAYZEsa8E8dQf {
"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
} Agents: http://localhost:3000/api/v1/livechat/users/agent {
"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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You are using RocketChat.authz.hasPermission
, so you have to set { authRequired: true }
to the route parameter.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @renatobecker , I fixed this.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@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": "guest@mail.com",
"phone": {
"number": "+5511999999999"
}
},
"messages": [
{
"msg": "Hi!!"
}
]
}'
Webhook payloads: https://rocket.chat/docs/administrator-guides/livechat/
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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": "guest@mail.com",
"phone": {
"number": "+5511999999999"
}
},
"messages": [
{
"msg": "Hi!!"
}
]
}'
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you want to try, here is the whole script:
https://gist.github.com/hmagarotto/6251f86e1f00035cc249c8ef05238a90
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.