Skip to content
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

Merged
merged 9 commits into from
Mar 27, 2018

Conversation

hmagarotto
Copy link
Contributor

@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.

return RocketChat.API.v1.unauthorized();
}

const info = Meteor.call('livechat:getInitialData', this.urlParams.visitorToken);
Copy link
Member

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

Copy link
Contributor Author

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;
Copy link
Member

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

Copy link
Contributor Author

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');
Copy link
Member

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.

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?

Copy link
Contributor Author

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?

Copy link
Member

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

Copy link
Contributor Author

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

@hmagarotto
Copy link
Contributor Author

hmagarotto commented Mar 27, 2018

@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
}

@renatobecker-zz renatobecker-zz self-requested a review March 27, 2018 18:00
@@ -0,0 +1,64 @@
import LivechatVisitors from '../../../server/models/LivechatVisitors';

RocketChat.API.v1.addRoute('livechat/messages', {

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.

Copy link
Contributor Author

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

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.

Copy link
Contributor Author

@hmagarotto hmagarotto Mar 27, 2018

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/

Copy link

@renatobecker-zz renatobecker-zz Mar 27, 2018

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.

Copy link
Contributor Author

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!!"
    }
  ]
}'

screenshot-new-guest

Copy link
Contributor Author

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

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) {
Copy link

@renatobecker-zz renatobecker-zz Mar 27, 2018

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.

@rodrigok rodrigok dismissed their stale review March 27, 2018 19:40

Changes made

@rodrigok rodrigok added this to the 0.63.0 milestone Mar 27, 2018
@rodrigok rodrigok added this to Desireable in 0.63.0 via automation Mar 27, 2018
@rodrigok rodrigok merged commit 04a6f3f into RocketChat:develop Mar 27, 2018
0.63.0 automation moved this from Desireable to Done Mar 27, 2018
@hmagarotto hmagarotto deleted the livechat-messages-api branch March 29, 2018 00:01
@rodrigok rodrigok mentioned this pull request Apr 4, 2018
@ilyamsts
Copy link

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.

@renatobecker-zz
Copy link

Hi @ilyamsts.
Can you open a new issue describing your case, please?

Thanks.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
No open projects
0.63.0
  
Done
Development

Successfully merging this pull request may close these issues.

None yet

5 participants