Hubspot CRM Integration

What’s about

In this page we’ll see the integration of the HubSpot CRM Ticket functionalities for XCALLY Motion V3 in form of an AppZone Plugin.
The project is integrated with the main HubSpot ticketing system, including contact and ownership assignation, and provides the automatic display of the ticket to the assigned agent.

So the system is based on a plugin service running under Motion V3, which provides a specific API endpoint to be called using the URL Forward action from Motion Triggers.

Consider that the data used for the ticket and contact handling is related to the trigger variables provided by xcally call/interaction events.

 

Plugin configuration

You can download the plugin from this link: Hubspot plugin

Then you can install it from the AppZone → Plugins section in the Admin interface.

image-20240829-154736.png

So you have to upload the zip file in this section and then click on 3 dots menu, by choosing the option Install plugin.
Then the plugin configuration can be accessed from the Plugins → HubSpot Integration section.

image-20240829-154831.png

There are different sections depending on the component you are configuring:

HubSpot

  • OAUTH Token: The private app OAUTH Token, used to connect to your HubSpot account and perform API requests, required to handle ticket and contact creation/association. It can be obtained/created going into your HubSpot account settings, then Integrations → Private App

  • HubSpot URL: The base URL of your HubSpot instance

  • HubSpot Account ID: Your HubSpot account id

Ticket

  • Ticket Subject: The default subject for the HubSpot ticket that will be created. It can be overridden by the trigger parameters

  • Ticket Content: The default content for the HubSpot ticket that will be created. It’s possible to use the variables passed in the trigger configuration to fill it with the call info, using the trigger variables syntax {{variable_name}}.
    E.g. The call from {{phone}} is being handled by the agent {{agent}}

Calls

  • Show Recording URL: Whether to include or not the recording URL of the call recording

Plugin

  • Plugin Port: The port used by the HubSpot plugin. It’s important since it’s used also in the trigger configuration to point to the correct API endpoint

Motion

  • API key: The admin/user motion API key, used by the plugin to retrieve the agent info and associate the ticket to the related HubSpot account.

IMPORTANT: The association between Motion and HubSpot agent is done through the email address, so your Motion agent needs to have the same email address as the HubSpot agent for the plugin to be able to associate the tickets and display them to the agent interface.


Redis

  • Host: The host for the Redis/socket connection. Don’t change it unless you changed your motion Redis configuration manually

  • Redis Port: The Port for the Redis/socket connection. Don’t change it unless you changed your motion Redis configuration manually

Trigger details and configuration

The contact search/creation, the ticket/call creation and the ownership/contact assignation can be executed with an API request, using the URL Forward action from the Motion V3 Tools → Triggers section.
The APIs can be called on any event, and on any channel, meaning that the integration is already available for all the channels (using the ticket entity) that are available on the Motion V3 environment, including openchannel.
Of course, the variable available for the ticket creation varies depending on the channel of integration.

URL Forward configuration

On Triggers section, you can configure the desired conditions, while on actions you can configure:

Ticket creation API

Trigger configurations should be reported exactly as in Wiki

 

  • Type: The ticket creation API needs to be called using a POST request

  • URL: After knowing on which port your plugin is running, the API endpoint will be: http://localhost:[plugin_port]/api/createTicket

  • Timeout: The timeout for the API request, you can leave it at 10 seconds

  • Headers: The headers of the request specify what type of request you are sending. In this case it’s a json object, so you need to insert

{"content-type": "application/json"}

{"content-type": "application/json"}

  • Body: The body of the request. As usual, it can also be populated by the event variables coming from Motion, using the triggers variables syntax {{variable_name}}. The HubSpot Plugin createTicket API supports different parameters in the body:

{
"membername": "{{membername}}",
"contact": {
"phone": "{{calleridnum}}",
"firstname": "Customer"
},
"templateVariables": {
"phone": "{{calleridnum}}",
"agent": "{{membername}}"
},"ticket": {
"source_type": "PHONE"
}}

{
"membername": "{{membername}}",
"contact": {
"phone": "{{calleridnum}}",
"firstname": "Customer"
},
"templateVariables": {
"phone": "{{calleridnum}}",
"agent": "{{membername}}"
},"ticket": {
"source_type": "PHONE"
}}

 

  • membername: the name of the agent, used to search for the Motion agent, get the related email and search for a match among HubSpot agents. If not passed/found the system will not associate the ticket to the agent and it will not automatically display the ticket.

  • contact: the parameters used to search/create the HubSpot contact. The system will first search for a HubSpot contact including all the parameters passed in the contact property, and if not found it will be created. Refer to HubSpot documentation for all the available contact fields.

  • templateVariables: These are the variables that the plugin will try to replace inside the default content of the ticket you defined in the plugin configuration. E.g.

    • Plugin default content: The call from {{phone}} is being handled by the agent {{agent}}

    • "templateVariables":{"agent": "john.doe","phone": "123456789"}

    • Result: The call from 123456789 is being handled by the agent john.doe

  • ticket: Additional ticket parameters that are not included in the default plugin configuration, like source_type, or ticket properties that have been already configured in the default plugin parameters but need to be overridden, like subject or content (E.g. If you want to have a different subject or content depending on the trigger). Refer to HubSpot documentation for all the available ticket fields.

  • showContact: on entity creation, if true displays the contact page, if false it displays the ticket page

  • noDisplay: if set to true it doesn't display the popup

Call creation API

Trigger configurations should be reported exactly as in Wiki

 

 

 

  • Type: The call creation API needs to be called using a POST request

  • URL: After knowing on which port your plugin is running, the API endpoint will be: http://localhost:[plugin_port]/api/createCall

  • Timeout: The timeout for the API request, you can leave it at 10 seconds

  • Headers: The headers of the request specify what type of request you are sending. In this case it’s a json object, so you need to insert:

{"content-type": "application/json"}

{"content-type": "application/json"}

  • Body: The body of the request. As usual, it can also be populated by the event variables coming from Motion, using the triggers variables syntax {{variable_name}}.
    The HubSpot Plugin createCall API supports different parameters in the body:

{
"membername": "{{membername}}",
"contact": {
"phone": "{{calleridnum}}"
},
"call": {
"uniqueid": "{{uniqueid}}",
"status": "{{lastevent}}",
"direction": "{{type}}",
"duration": "{{duration}}",
"from": "{{calleridnum}}",
"to": "{{exten}}",
"title": "New call with uniqueid ({{uniqueid}})"
},
"showContact": true
}

{
"membername": "{{membername}}",
"contact": {
"phone": "{{calleridnum}}"
},
"call": {
"uniqueid": "{{uniqueid}}",
"status": "{{lastevent}}",
"direction": "{{type}}",
"duration": "{{duration}}",
"from": "{{calleridnum}}",
"to": "{{exten}}",
"title": "New call with uniqueid ({{uniqueid}})"
},
"showContact": true
}

  • membername: The name of the agent, used to search for the Motion agent, get the related email and search for a match among HubSpot agents. If not passed/found the system will not associate the ticket to the agent and it will not automatically display the ticket.

  • contact: The parameters used to search/create the HubSpot contact. The system will first search for a HubSpot contact including all the parameters passed in the contact property, and if not found it will be created. Refer to HubSpot documentation for all the available contact fields.

  • call: contains specific plugin properties converted to HubSpot properties, plus all the others you can find in HubSpot docs

    • "uniqueid": the only required field, otherwise the plugin cannot search the call later to update it

    • "status": call status

      • for the status property you can pass the lastevent var and it will be converted to HubSpot call status like this:

        • abandoned: CANCELED

        • timeout: NO_ANSWER

        • complete: COMPLETED

        • rejected: CANCELED

        • called: RINGING

        • connect: IN_PROGRESS

        • nosuchnumber: FAILED

        • busy: BUSY

        • noanswer: NO_ANSWER

        • congestion: FAILED

        • agentreject: CANCELED

        • amd: COMPLETED

      • Or you can pass the HubSpot status directly, one of these

        • BUSY

        • CALLING_CRM_USER

        • CANCELED

        • COMPLETED

        • CONNECTING

        • FAILED

        • IN_PROGRESS

        • NO_ANSWER

        • QUEUED

        • RINGING

    • direction: call type (inbound/outbound), you can pass the type variable

    • duration: the call duration (better to pass it at the call hangup using the updateCall api)

    • from: call source, you can use the calleridnum variable

    • to: call destination, you can use the exten variable

    • title: call title

    • body: call body

      • the body of the call, if not passed as a parameter (string) in the call property, is created automatically from the properties: status, direction, duration. The format of the body in that case will be: [answered/unanswered] [inbound/outbound] call. Call duration: [duration ‘hh:mm:ss’]

    • all the other hs_call_ variables are available to be used

  • showContact: on entity creation, if true displays the contact page, if false it displays the ticket page

  • noDisplay: if set to true it doesn't display the popup

 

Call update API

 

  • Type: The call update API needs to be called using a POST request

  • URL: After knowing on which port your plugin is running, the API endpoint will be: http://localhost:[plugin_port]/api/updateCall

  • Timeout: The timeout for the API request, you can leave it at 10 seconds

  • Headers: The headers of the request specify what type of request you are sending. In this case it’s a json object, so you need to insert

{"content-type": "application/json"}

{"content-type": "application/json"}

  • Body: The body of the request. As usual, it can also be populated by the event variables coming from Motion, using the triggers variables syntax {{variable_name}}. The HubSpot Plugin updateCall API supports different parameters in the body:

{
"call": {
"uniqueid": "{{uniqueid}}",
"status": "{{lastevent}}",
"direction": "{{type}}",
"duration": "{{talktime}}"
}
}

{
"call": {
"uniqueid": "{{uniqueid}}",
"status": "{{lastevent}}",
"direction": "{{type}}",
"duration": "{{talktime}}"
}
}

  • call: contains specific plugin properties converted to HubSpot properties, plus all the others you can find in HubSpot docs

  • "uniqueid": the only required field, otherwise the plugin cannot search the call to update it

  • "status": call status

    • for the status property you can pass the lastevent var and it will be converted to HubSpot call status like this:

      • abandoned: CANCELED

      • timeout: NO_ANSWER

      • complete: COMPLETED

      • rejected: CANCELED

      • called: RINGING

      • connect: IN_PROGRESS

      • nosuchnumber: FAILED

      • busy: BUSY

      • noanswer: NO_ANSWER

      • congestion: FAILED

      • agentreject: CANCELED

      • amd: COMPLETED

    • Or you can pass the HubSpot status directly, one of these

      • BUSY

      • CALLING_CRM_USER

      • CANCELED

      • COMPLETED

      • CONNECTING

      • FAILED

      • IN_PROGRESS

      • NO_ANSWER

      • QUEUED

      • RINGING

  • "direction": call type (inbound/outbound), you can pass the type variable

  • "duration": the call duration. If used on the hangup event you can use the talktime variable

  • "from": call source, you can use the calleridnum variable

  • "to": call destination, you can use the exten variable

  • "title": call title

  • "body": call body

    • the body of the call, if not passed as a parameter (string) in the call property, is created automatically from the properties: status, direction, duration. The format of the body in that case will be: [answered/unanswered] [inbound/outbound] call. Call duration: [duration ‘hh:mm:ss’]

  • all the other hs_call_ variables are available to be used