Communication

"app_type": ["communication"]

Overview

Creating a communication app lets you integrate 3rd party messaging channels (e.g. Messenger, WhatsApp, etc.) into our conversation page.

This can be a good solution for businesses with a business page on social networks and want to be able to send and receive messages through these networks within our product and manage the entire interaction with their clients from one place.

To support such use cases, inTandem has the infrastructure that allows messages to be sent to our conversion page and get notified when new messages are sent from this page.

🚧

Handling communication with 3rd party messaging channels

Pushing messages to the 3rd party communication channel and listening to new events from these channels is the developer's/business responsibility.


How does it work?

Injecting messages to our product from external messaging channels is done using the "inTandem Communication Service" (ICS).
ICS exposes the necessary APIs that allow external messaging apps to push messages into inTandem and get notified when a message is sent out from inTandem to the messaging app.

End-to-end integration overview

πŸ“˜

Middleware Service

A service that can (a) listen to new messages sent from 3rd party messaging apps and (b) push messages back to these apps. The middleware service can be an existing service provider or an in-house solution. Either way, it should be able to perform the tasks listed above.

πŸ“˜

Main App

The main application is responsible for syncing messages between inTandem and the 3rd party messaging apps. This app will interact with both the middleware service and ICS.

πŸ“˜

inTandem Communication Service - ICS

inTandem service that enables external services to get notified on new messages sent from inTandem and also to inject new messages to our client conversation page.

Incoming messages

Outgoing messages

Final result

Once new channels are created, staff members will be able to choose the channel through which they want to send messages to the client, and in the same way, the conversation page thread will reflect the channel in which a message was sent.


Developers guide

Prerequisites

  • Creating an app of type "communication"
  • Make sure you can generate an OAuth access token for the businesses that need to be connected to the channel
  • Building the Main App that will be responsible for:
    (a) implementing the communication app interface
    (b) communicating with ICS APIs

For this guide, let's assume we are building a channel for WhatsApp messages.

Step 1: Creating the communication app

curl --location 'https://api.vcita.biz/platform/v1/apps' \
--header 'Authorization: Bearer {DIRECTORY_TOKEN}' \
--header 'Content-Type: application/json' \
--data '{
    "name": "{APP_NAME}",
    "app_type": ["communication"],
    "trusted": true,
    "url_params": ["business_uid", "staff_role", "staff_uid"],
    "redirect_uri": "{REDIRECT_URI}",
    "api_uri": "{API_URI}",
		"scopes": ["openid", "business/clients", "business/communication"],
		"app_layer": "apps"
}'

πŸ“˜

app_uri

The app_uri is the dedicated route on your main app that inTandem will send updates and webhooks to. Thus when building the main app on your end, it will have to include a dedicated route for ICS events.

Later on, we will go through the different child routes that it has to implement (See below "Appendix 1: Communication-app interface").

In this guide we will refer to the app_uri as the "app-registered-uri".

🚧

Storing app info

After creating your app in inTandem, make sure to store the "client_id", "client_secret", "app_code_name", "and app_id" values returned in the Create App API response. These will be needed for later authentication tasks.

Step 2: Generating OAuth tokens

Ensure you can generate OAuth tokens for the businesses you want to connect the messaging channel to, and store these tokens in a database for future use.
Make sure you're able to generate, store, and retrieve these tokens dynamically.
These tokens will be used for creating and managing sessions on behalf of these businesses.
For further info regarding OAuth tokens, please refer to this article.

Step 3. Building the Main App

On your end, you need to build an app that will know to (a) listen to webhook events from inTandem, and (b) update inTandem upon new messages or status updates on the 3rd party communication channel.
This app is eventually a middleware that will handle the communication between the 3rd party messaging channel and inTandem's communication service.

Listening to webhook events from inTandem

The main app must implement the routes listed in this guide under the "Communication-app interface" appendix.
As explained above, inTandem will send webhooks to these routes in order to update your app when new messages/sessions/channels are created, or have their status updated.

Updating inTandem

To update inTandem when a new message is created on the 3rd party messaging app, or when a session changed its status, etc. We developed a set of APIs that allow you to communicate with our communication service and perform all necessary actions.

Communication API reference

Please refer to this swagger file for detailed API specs.
We will also go through these API endpoints in this guide.


ICS - inTandem Communication Service

ICS is built upon 4 main building blocks:

  • Communication app
  • Channel
  • Sessions
  • Messages

Communication app

The communication app is the main entity that manages the interaction between the external messaging service and ICS.
When creating a new communication app and assigning it to a business, you'll instantly see it reflected in the conversation page as an additional messaging channel.

Channels

A channel represents the implementation of a communication app at the business level.
When assigning a communication app to a business, the app needs to create a new channel for the business and wait for the confirmation webhook before it can open messaging sessions with clients.

When creating a channel, you'll need to specify the following:

  • "business_uid": uid of the business the channel is created for.
  • "type": messaging channel type. It can be either "transactional" or "promotional".
    You'll usually use the "transactional" option, which relates to messages sent to and from the clients' conversation page.
  • "display_name": the name of the channel to be displayed in the conversion page's channels dropdown
curl --location --request POST 'https://api.vcita.biz/business/communication/channels' \
--header 'Authorization: Bearer APP_TOKEN' \
--header 'Content-Type: application/json' \
--data-raw '{
	"business_uid": "string",
	"type": "transactional",
	"display_name": "CHANNEL_DISPLAY_NAME"
}'

The response from the POST request will indicate the newly created channel's status is "pending", and will also include the channel uid. Please make sure to store the channel uid and its other properties on your DB for future reference.

Create channel response

{
  "data": {
    "channel": {
      "status": "pending",
      "uid": "string"
    }
  },
  "success": true
}

Once the channel is verified and validated by us, we will trigger a webhook to your application (/channels/:channel_uid) indicating the channel's status is "active".

Update channel

Later, you can change the channel's display name or status.

The status should be changed whenever switching between channels and when a channel needs to be re-activated after it is pending.

The channel statuses are listed below under the ENUMs appendix.

curl --location --request PUT 'https://api.vcita.biz/business/communication/channels/:channel_uid' \
--header 'Authorization: Bearer APP_TOKEN' \
--header 'Content-Type: application/json' \
--data-raw '{
	"status": "active",
	"display_name": "string"
}'

πŸ“˜

Communication app identification

You'll notice that the create channel request does not include the communication app id or name in it.
Our way of identifying the communication app that the channel is created for is by the API token used in the request. Therefore, you have to generate a dedicated token for the communication app using its client id and secret, as explained here.

Sessions

A session represents a conversation thread with a client via a given channel. Thus if a staff member wants to send a message to a client via WhatsApp, the communication app created for WhatsApp needs to create a channel with that business, and then create a session using that channel for the client.

When creating a session, you'll need to specify the following:

  • "business_uid": uid of the business the session is created for.
  • "channel_uid": the channel that the session was created for (remember that you can connect multiple channels to one business).
  • "contact_uid": uid of the client that the session is created for.
  • "external_uid": client's identifier on the main app.

πŸ“˜

Multiple matters under one client

If there is more than one user/matter under the same client, ICS will create the session under the matter that had the last conversation with the business.

curl --location --request POST 'https://api.vcita.biz/business/communication/sessions' \
--header 'Authorization: Bearer APP_TOKEN' \
--header 'Content-Type: application/json' \
--data-raw '{
  "business_uid": "BUSINESS_UID",
  "channel_uid": "CHANNEL_UID",
  "contact_uid": "CLIENT_UID",
  "external_uid": "EXTERNAL_ID"
}'

The response from the POST request will indicate the newly created session's status is "pending", and also includes the session uid.

{
	"data": {
		"session": {
			"uid": "SESSION_UID",
			"status": "pending"
		}
	},
	"success": true
}

Once the session is validated on inTandem, we will trigger a webhook to your application URI indicating the session status is "inactive".

After the session is created, you'll need to send an update request to update the session's status to Active:

curl --location --request PUT 'https://api.vcita.biz/business/communication/sessions/:SESSION_UID' \
--header 'Authorization: Bearer APP_TOKEN' \
--header 'Content-Type: application/json' \
--data-raw '{
  "status": "active"
}'

Response:

{
	"data": {
		"session": {
			"uid": "SESSION_UID",
			"status": "active"
		}
	},
	"success": true
}

The final approval of the session status will be sent to the application URI. If there were an issue with activating the session, the webhook event will indicate that the status is "inactive". See below the "Communication-app interface" appendix.

🚧

Sessions

Sessions are singular per client and channel. Thus when switching between channels there is no need to create new sessions each time, and a channel can use its existing session by activating it. As a rule of thumb - there should only be one session per client for a given channel.

Messages

The message is the actual text message sent during an active session.

When creating a message, you'll need to specify the following:

  • "message": the actual message (text) sent by the client.
  • "channel_uid": the channel from which the message was sent.
  • "message_uid": uid of the message. It will be used for later webhook events indicating whether the message was sent successfully or not.
  • "external_uid": client's identifier on the main app.
  • "created_at": the date-time of when the message was sent.
  • "direction": optional. valid values: busines_to_client \ client_to_business
curl --location --request POST 'https://api.vcita.biz/business/communication/messages' \
--header 'Authorization: Bearer APP_TOKEN' \
--header 'Content-Type: application/json' \
--data-raw '{
  "channel_uid": "string",
  "external_uid": "string",
  "message": "string",
  "message_uid": "string"
}'

The response from the POST request will indicate the newly created message status is "pending", and also includes the message uid.

{
  "data": {
    "message": {
      "status": "pending",
      "uid": "string"
    }
  },
  "success": true
}

Once the message is validated on inTandem, we will trigger a webhook indicating the status is "active".


Appendix 1: Communication-app interface

The main app needs to implement child routes under the redirect URI route.

Channels

Channels

Receive channel update

Method: PUT
Route: /channels/{channel_uid}
Response codes:
-204 - Message received successfully
-4xx/5xx - Error receiving message
Payload:

{
  "status”: ChannelStatus
}

Sessions

Receive session update

Method: PUT
Route: /sessions/{session_uid}
Response codes:
-204 - Message received successfully
-4xx/5xx - Error receiving message
Payload:

{
  β€œstatus”: SessionStatus
}

Messages

Receive new message

Method: POST
Route: /messages
Response codes:
-204 - Message received successfully
-4xx/5xx - Error receiving message
Payload:

{
  "external_uid": string, // App's contact identifier
  "message": string,
  "message_uid": string, //  uuid of message (unique per channel). App will send message updates based on this message identifier
  "channel_uid": string,
  β€œstatus”: MessageStatus // Current status of message
}

Receive message update

Method: PUT
Route: /messages/{message_uid}
Response codes:
-204 - Message received successfully
-4xx/5xx - Error receiving message
Payload:

{
  "status”: string,
  "channel_uid": MessageStatus
}

Appendix 2: ENUMs

ChannelStatus

  • pending - Channel has been registered but not yet active
  • active - The channel is active, and messages can be sent to/from
  • inactive - Channel is temporarily inactive
  • blocked - Channel is blocked for an unexpected reason
  • deleted - The channel is explicitly deleted by the user/business

ChannelType

ChannelType

  • transactional - Channel dedicated to regular messaging
  • promotional - Channel dedicated to promotional offers

SessionStatus

  • pending - Session has been created and is waiting for confirmation
  • active - Session of a channel is open and ready to send and receive messages
  • inactive - The channel's session is established but can't send and receive messages.

MessageStatus

  • pending - A new message was received by the service but not yet displayed to the user/business
  • received - Message was successfully displayed to the user/business
  • read - Message was read by user/business
  • error - Message delivery encountered some error that needs to be handled

Appendix 3: Typing Indication

Listening to typing events within inTandem, and notifying us when a user is typing in the 3rd party messaging app, can be easily achieved by implementing the following:

Listening to typing events from inTandem

Create the following endpoint on your end: {app_registered_uri}/{session_uid}/typing

Example: https://app-registered-uri.com/c6f6217f-bf44-4ed0-84d1-0ef82149bf54/typing

The payload inTandem sends upon typing state change is:

{
  typing: boolean
}

Based on the session_uid URL param, you should be able to determine the channel and client id that their state needs to be updated on the 3rd party app.

Update inTandem on typing state changes from 3rd party channels

curl --location --request POST 'https://api.vcita.biz/business/communication/v1/sessions/typing' \
--header 'Authorization: Bearer {TOKEN}' \
--header 'Content-Type: application/json' \
--data-raw '{
    "session_uid": string,
    "typing": boolean
}'

Appendix 4: Workflows

Channel-business hierarchy

Download PDF

Working with multiple communication apps

Download PDF

Incoming messages

Download PDF

Outgoing messages

Download PDF