Table of Contents
Custom Channel Quick Start
Updated by JQ Lee
This integration allows your team to chat with your customers over any messaging Channel via a custom implementation.
Connecting a Custom Channel
Step 1: Go to Settings > Channels
Step 2: Click Add Channel > Custom Channel > Connect
Step 3: Enter the destination Webhook URL where outgoing messages will be sent.
Step 4: Select the ID type for the Channel > click Next
ID types are used for user identification and are used to communicate with your custom integration server.
There are two types of IDs available:
- Phone Number: Use this if the messaging service provider recognizes Contacts based on their Phone Number.
- Sample format:
+60177872890
- Sample format:
- Custom ID: Use this if the messaging service provider recognizes Contacts based on a custom-generated ID.
- The maximum character length is 50.
A-Z
,a-z
,0-9
,_
,=
,+
,/
and@
are allowed.
Step 5: The following dialog will provide the Channel ID, API Token, and Webhook URL e.g.
- Channel ID:
gfd8g7fd89dgfd
- API Token:
aaaxczsadzxcasdacxzcasdaaaxczsadzxcasdacxzcasd
- Webhook URL:
https://app.respond.io/custom/channel/webhook/
Using a Phone Number ID type allows you to initiate a conversation and send the first message to a Contact.
Pass Messages to respond.io
Webhook URL is used to post the Messages, Messaging Echoes and Messaging Receipts to the respond.io platform.
The provided code will trigger the webhook on respond.io, creating a Contact if necessary and saving the message under that Contact.
Sample for Messages
curl -X POST \
https://app.respond.io/custom/channel/webhook/ \
-H 'authorization: Bearer aaaxczsadzxcasdacxzcasdaaaxczsadzxcasdacxzcasd' \
-H 'cache-control: no-cache' \
-H 'content-type: application/json' \
-d '{
"channelId": "gfd8g7fd89dgfd",
"contactId": "+60177872890",
"events": [
{
"type": "message",
"mId": "xcvzzxcxczxczxc",
"timestamp": 2132131321000,
"message": {
"type": "text",
"text": "Hello World"
}
}
],
"contact": {
"firstName": "John",
"lastName": "Doe",
"profilePic": "<https://static.independent.co.uk/s3fs-public/thumbnails/image/2015/07/08/14/pic.jpg>",
"countryCode": "MY",
"email": "john@respond.io",
"phone": "+60177872890",
"language": "en"
}
}'
Sample for Messaging Echoes
curl -X POST \
https://app.respond.io/custom/channel/webhook/ \
-H 'authorization: Bearer aaaxczsadzxcasdacxzcasdaaaxczsadzxcasdacxzcasd' \
-H 'cache-control: no-cache' \
-H 'content-type: application/json' \
-d '{
"channelId": "gfd8g7fd89dgfd",
"contactId": "+60177872890",
"events": [
{
"type": "message_echo",
"mId": "xcvzzxcxczxczxc",
"timestamp": 2132131321000,
"message": {
"type": "text",
"text": "Hello World"
}
}
],
"contact": {
"firstName": "John",
"lastName": "Doe",
"profilePic": "<https://static.independent.co.uk/s3fs-public/thumbnails/image/2015/07/08/14/pic.jpg>",
"countryCode": "MY",
"email": "john@respond.io",
"phone": "+60177872890",
"language": "en"
}
}'
Sample for Messaging Receipts
curl -X POST \
https://app.respond.io/custom/channel/webhook/ \
-H 'authorization: Bearer aaaxczsadzxcasdacxzcasdaaaxczsadzxcasdacxzcasd' \
-H 'cache-control: no-cache' \
-H 'content-type: application/json' \
-d '{
"channelId": "gfd8g7fd89dgfd",
"contactId": "+60177872890",
"events": [
{
"type": "message_status",
"mId": "xcvzzxcxczxczxc",
"timestamp": 2132131321000,
"status": {
"value": "sent|delivered|read|failed",
"message": "Error: Sending failed due to invalid token"
}
]
}'
Field | Description | Validation |
channelId | Unique Channel ID | Required. Unique field. Is generated by respond.io. |
contactId | Unique Contact ID | Required. Unique respond.io contact id. Max 50 characters. |
events.type | Event Type | Required. Available type: message, message_echo, and message_status. |
events.mld | Message ID | Required. Unique message ID. Max 50 characters. |
events.timestamp | UNIX Epoch Time (milliseconds) | Required. Time of the event that triggered the callback. |
events.message.type | Message Type | Required. Available message types: text, attachment, location and quick_reply. Refer Message Type section for other message type samples. |
events.message.text | Message Text | Required. Max length 7,000 characters. |
events.status.value | Text | Required if event.type is message_status. Available status values: sent, delivered, read, and failed. |
events.status.message | Text | Required if events.status.value is failed. |
contact.firstName | First Name | Optional. Max 50 characters. |
contact.lastName | Last Name | Optional. Max 50 characters. |
contact.profilePic | Profile Pic URL | Optional. Avatar size should be no more than 100 kb. Recommended 720x720. |
contact.locale | Locale Code | Optional. Refer here for the list of values. |
contact.countryCode | Country Code | Optional. 2 letters country code - ISO ALPHA-2 Code. |
contact.timezone | Time Zone | Optional. (min: -24) (max: 24). |
contact.email | Email Address | Optional. Max 50 characters. |
contact.phone | Phone Number | Optional. Max 18 characters. |
contact.language | Language | Optional. ISO 639-1. |
Response - Success (HTTP status → 200)
"OK"
Handle Outgoing Messages from respond.io
respond.io will call the endpoint <API Base URL>/message
/message
route of your web server.Here is the cURL example of respond.io calling the endpoint:
curl -X POST \
<API Base URL>/message \
-H 'authorization: Bearer aaaxczsadzxcasdacxzcasdaaaxczsadzxcasdacxzcasd' \
-H 'cache-control: no-cache' \
-H 'content-type: application/json' \
-d '{
"channelId": "gfd8g7fd89dgfd",
"contactId": "+60177872890",
"message": {
"type": "text",
"text": "Hello World"
}
}'
Response - Success (HTTP status → 200)
{
"mId": "1640141607842"
}
Authentication needs to happen at the endpoint before sending the message to the Messaging Service Provider.
Here's an example of using an express middleware for this purpose:
const {validationResult} = require('express-validator');
const validateToken = (req, res, next) => {
const apiToken = <<API Token>>
const bearerToken = req.headers.authorization;
if (!bearerToken)
return res.send(401)
const token = bearerToken.substring(7, bearerToken.length);
if (apiToken !== token) {
return res.send(401)
}
next();
};
module.exports = {
validateToken
};
Messages Type
Sample for Text
{
"type": "text",
"text": "Welcome to respond.io",
}
Field | Description | Validation |
type | Message Type | Required. text |
text | Message Text | Required. Max length 7,000 characters. |
Sample for Media File
{
"type": "attachment",
"attachment": {
"type": "image|video|audio|file",
"url": "https://abc/japan.png",
"mimeType": "image/png",
"fileName":"company logo.png",
"description": "latest company logo"
}
}
Field | Description | Validation |
type | Message Type | Required. attachment. |
attachment.type | Attachment Type | Required. Available attachment types: image, video, audio and file. |
attachment.url | URL | Required. Max 2,000 characters. Make sure it’s a public link so users or contacts are able to see the content. |
attachment.mimeType | Mime Type of the Attachment | Optional |
attachment.fileName | File Name | Optional. The File name should include an extension. Max 256 characters (including file extension). Sending a file without an extension or with the wrong extension might cause the contact or user to be unable to open the file. |
attachment.description | File Description | Optional. Max 256 characters. Only applicable for attachment.type = image. |
Ensure that the attachment URL isn't forcibly downloaded by the browser. The HTTP response's Content-Disposition
header should have the default value, which is inline
.
Sample for Location
{
"type": "location",
"latitude": 0.123456,
"longitude": -0.1234,
"address": "Sky Suites, Jalan P. Ramlee, Kuala Lumpur, 50250 Kuala Lumpur, Wilayah Persekutuan Kuala Lumpur"
}
Field | Description | Validation |
type | Message Type | Required. location. |
latitude | Coordinates | Required. Latitude (±90°) within valid ranges. |
longtitude | Coordinates | Required. Longitude (±180°) within valid ranges. |
address | Location Address | Optional. Max 256 characters. |
Sample for Quick Reply
{
"type": "quick_reply",
"title": "Select your preferred language",
"replies": [
"Malay",
"English"
]
}
Field | Description | Validation |
type | Message Type | Required. quick_reply. |
title | Quick Reply Title | Required. Max 256 characters. |
replies | Reply Text | Required. Max 10 replies with max. 256 characters for each reply. |
Error Codes
Error (HTTP Status → 4xx)
{
"error": {
"message": "Error message"
}
}
Channel Configuration
Step 1: Click Settings > Channels
Step 2: Locate the Custom Channel > click Manage
Step 3: In the Custom Channel Configuration page you will see the following configurations:
- Channel Icon - Upload an image that serves as the icon for your Custom Channel.
- Channel Name - The Channel Name can be changed and is used internally to identify the Channel.
- Webhook URL for Outgoing message — The webhook URL for outgoing messages to this Channel.
- Webhook URL for Incoming message — The webhook URL for incoming messages to this Channel.
- ID Type — These are used for user identification and are used to communicate with your custom integration server.
- Channel ID — Unique Channel ID to identify your Custom Channel.
- API Token — A unique identifier used to authenticate a user to access an API.
Step 4: Click Save Changes to update the Custom Channel configuration.
FAQ and Troubleshooting
Can I connect chats from other platforms using a Custom Channel?
Yes, you can. Here are three steps to follow:
- In respond.io, input the destination webhook URL from the other platform into the Webhook URL for Incoming message field.
- In the other platform, set up a webhook URL pointing to respond.io, allowing Contacts to send messages back to you.
- You'll require a Custom Integration Server to interpret APIs from both respond.io and the other platform, enabling message exchange between them.
Make sure to confirm with the other platform that the first two steps are feasible.
FAQ for Custom Channel Webhooks
Why does the webhook return a 200 status even if the message fails to be delivered to respond.io?
When connecting a Custom Channel, messages sent to respond.io through webhooks will always return a 200 status code immediately, regardless of whether the message was successfully passed to respond.io. This is due to the nature of webhooks, which are designed to return an immediate response without verifying the success of the message delivery.