Webhook API
Telerivet's Webhook API allows your server to receive asynchronous event notifications from Telerivet, such as when an incoming message is received,
when an outgoing message is sent or has an error, or when a message or contact is updated via the Telerivet web app.
When an event occurs, Telerivet will make a HTTP POST request to your Webhook URL (a script on your own web server), sending data about the event in the POST request body.
|
|
Request Format
Webhooks are just HTTP POST requests that Telerivet makes to your web server. Data is formatted as normal URL-encoded POST parameters (application/x-www-form-urlencoded ).
The POST parameters for each event are described in the sections below.
In particular, note that Webhook request data is not JSON encoded.
|
Example
POST /incoming_message.php HTTP/1.1
Host: yourserver.example.com
Content-Type: application/x-www-form-urlencoded
...
event=incoming_message&from_number=%2B16505550123&content=Hello+world...
|
Response Format
Your Webhook URL should return a response with HTTP status code 200. Any other HTTP response code will be treated as a failure.
It is not necessary for your Webhook response to return any content.
If your Webhook takes 10 seconds or longer to return a response, Telerivet will also treat it as a failure.
If you are performing any operations during a webhook that may take longer than a couple seconds, consider performing the operation asynchronously
instead of within the webhook itself.
Telerivet will retry failed webhooks periodically for up to a day, until receiving a response with HTTP code 200.
|
|
Receiving Incoming Messages
To configure your Webhook URL to receive incoming messages, add a new service in your Telerivet project and click "Webhook API", or click the button below:
Create Webhook Service
When Telerivet receives an incoming message on one of your phones, it will make a HTTP POST request to the URL you define in your Webhook service.
|
Example
<?php
$webhook_secret = 'YOUR_WEBHOOK_SECRET_HERE';
if ($_POST['secret'] !== $webhook_secret)
{
header('HTTP/1.1 403 Forbidden');
echo "Invalid webhook secret";
}
else
{
if ($_POST['event'] == 'incoming_message')
{
$content = $_POST['content'];
$from_number = $_POST['from_number'];
$phone_id = $_POST['phone_id'];
// do something with the message, e.g. send an autoreply
header("Content-Type: application/json");
echo json_encode([
'messages' => [
['content' => "Thanks for your message!"]
]
]);
}
} from django.views.decorators.csrf import csrf_exempt
from django.http import HttpResponse
import json
@csrf_exempt
def webhook(request):
webhook_secret = 'YOUR_WEBHOOK_SECRET_HERE'
if request.POST.get('secret') != webhook_secret:
return HttpResponse("Invalid webhook secret", 'text/plain', 403)
if request.POST.get('event') == 'incoming_message':
content = request.POST.get('content')
from_number = request.POST.get('from_number')
phone_id = request.POST.get('phone_id')
# do something with the message, e.g. send an autoreply
return HttpResponse(json.dumps({
'messages': [
{'content': "Thanks for your message!"}
]
}), 'application/json')
/*
* Sample code depends on the Java JSON library:
* http://mvnrepository.com/artifact/org.json/json/20090211
*/
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
public class WebhookStatusServlet extends HttpServlet
{
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
PrintWriter out = response.getWriter();
String webhookSecret = "YOUR_WEBHOOK_SECRET_HERE";
if (!webhookSecret.equals(request.getParameter("secret")))
{
response.setStatus(403);
out.write("Invalid webhook secret");
}
else if ("incoming_message".equals(request.getParameter("event")))
{
String content = request.getParameter("content");
String fromNumber = request.getParameter("from_number");
String phoneId = request.getParameter("phone_id");
// do something with the message, e.g. send an autoreply
response.setContentType("application/json");
try
{
JSONArray messages = new JSONArray();
JSONObject reply = new JSONObject();
reply.put("content", "Thanks for your message!");
messages.put(reply);
JSONObject json = new JSONObject();
json.put("messages", messages);
json.write(out);
}
catch (JSONException ex)
{
throw new ServletException(ex);
}
}
}
} using System;
using System.Collections.Generic;
using System.Web;
using System.Web.Mvc;
namespace MyMVCApplication.Controllers
{
public class HomeController : Controller
{
public ActionResult Index()
{
String statusSecret = "YOUR_STATUS_SECRET_HERE";
if (Request["secret"] != statusSecret)
{
Response.StatusCode = 403;
return Content("Invalid status secret");
}
if (Request["event"] == "incoming_message")
{
String content = Request["content"];
String fromNumber = Request["from_number"];
String phoneId = Request["phone_id"];
// do something with the message, e.g. send an autoreply
Dictionary<string,object> reply = new Dictionary<string,object>();
reply["content"] = "Thanks for your message!";
Dictionary<string,object> result = new Dictionary<string,object>();
result["messages"] = new Object[]{reply};
return Json(result);
}
else
{
Response.StatusCode = 400;
return Content("Unknown event");
}
}
}
}
var express = require('express');
var bodyParser = require('body-parser');
var app = express();
var WEBHOOK_SECRET = "YOUR_WEBHOOK_SECRET_HERE";
app.post('/telerivet/webhook',
bodyParser.urlencoded({ extended: true }),
function(req, res) {
var secret = req.body.secret;
if (secret !== WEBHOOK_SECRET) {
res.status(403).end();
return;
}
if (req.body.event == 'incoming_message') {
var content = req.body.content;
var from_number = req.body.from_number;
var phone_id = req.body.phone_id;
// do something with the message, e.g. send an autoreply
res.json({
messages: [
{ content: "Thanks for your message!" }
]
});
}
res.status(200).end();
}
);
app.listen(8000);
|
Request Parameters
When an incoming message is received, Telerivet will make a POST request to your Webhook URL with the following POST parameters:
event
|
string
The type of event that triggered this webhook, always set to incoming_message .
|
id
|
string, maximum length 34 characters
Telerivet's unique ID for the message (string, maximum length 34 characters).
|
message_type
|
string
Either sms , mms , ussd , or call . Other message types may be added in the future.
|
content
|
string
The text of the SMS message, or the content of the text/plain part of an MMS message.
|
from_number
|
string
The phone number (or alphanumeric sender ID) that the message was sent from.
For USSD responses, this is the USSD/MMI code that was requested.
This is always the raw sender ID provided by the mobile network or SMS gateway API,
so it may have a different format depending on the mobile network or SMS gateway API.
|
from_number_e164
|
string
The phone number that the message was sent from, normalized to E.164 format
relative to the country property of the phone that received the message.
Often this is identical to the from_number parameter.
This parameter is not set for messages received from alphanumeric sender IDs, shortcodes, or other phone numbers that cannot be normalized to E.164 format.
|
to_number
|
string
The phone number that received the message (your own phone number).
|
time_created
|
The time Telerivet received the message.
|
time_sent
|
The time the message was sent, if available.
(This time is given by the mobile network, and may not always be reliable.)
|
contact_id
|
string, maximum length 34 characters
The unique ID of the contact that sent the message
|
phone_id
|
string, maximum length 34 characters
The ID of the phone that received the message.
|
service_id
|
string, maximum length 34 characters
The ID of the Telerivet service that is invoking this Webhook
|
message_service_id
|
string, maximum length 34 characters
The ID of the Telerivet service that handled this incoming message (may be different from the service that is triggering the webhook if multiple services are enabled)
|
project_id
|
string, maximum length 34 characters
The ID of the Telerivet project associated with this message
|
secret
|
string
A secret parameter associated with your Webhook, so you can verify that the request came from Telerivet.
You can set this secret parameter when you create the Webhook service.
|
media[0][url]
media[0][type]
media[0][filename]
media[0][size]
...
|
Information about each of the media files attached to the incoming message, if present. Depending on the type of route, the type , filename , and size properties may or may not be available.
The POST parameters are named so that some languages (including PHP) will automatically parse the parameters into an array of objects.
|
contact[name]
contact[time_created]
contact[message_count]
contact[vars][foo]
...
|
Information about the contact that sent the message, as stored in your Telerivet contacts database.
The POST parameters are named so that some languages (including PHP) will automatically parse the parameters into an object.
The Webhook API sends the same contact properties as are available in the REST API. See all
|
state[id]
state[time_created]
state[vars][foo]
...
|
Information about the current state of the contact for this service.
The state[id] parameter lets you keep track of the contact's current state within a multi-step conversation flow.
Your webhook can also update the contact's current state to move them to the next step in the conversation flow.
Learn more
The Webhook API sends the same properties as are available in the REST API. See all
|
phone[name]
phone[phone_type]
phone[country]
phone[vars][foo]
...
|
Information about the phone/gateway that received the message.
The POST parameters are named so that some languages (including PHP) will automatically parse the parameters into an object.
The Webhook API sends the same contact properties as are available in the REST API. See all
|
In addition to the parameters documented above, Telerivet also passes all other REST API message properties as POST parameters.
Since numeric fields like time_created are converted to strings when encoded as Webhook POST parameters, your script may need to convert them back to integers.
We recommend keeping track of the id field on your server. This will let you detect if a Webhook was sent multiple
times for the same message (if your URL didn't return a 200 response within the 10 second limit).
|
Sending Autoreplies
Optionally, your webhook URL can send one or more SMS messages (or USSD requests) in response to an incoming message by returning a JSON
object containing a messages property with an array of messages to send.
When returning JSON, your webhook response should include the HTTP header Content-Type: application/json .
Each entry in the messages array should be a JSON object, which may contain the following properties:
content
|
string
The content of the SMS message to send. (Ignored if the message_type is ussd )
|
to_number
|
string, optional
The optional phone number to send the message to. If omitted, Telerivet will send a reply to the same phone number that sent the incoming message.
|
message_type
|
string, optional
Either sms or ussd . The default is sms .
|
status_url
|
string, optional
An optional Webhook URL that Telerivet will notify via a HTTP POST when the message status changes, such as when the message is sent or fails to send.
See Message Status Notifications for more details.
|
status_secret
|
string, optional
An optional string that Telerivet will pass as the secret POST parameter to your status_url , so you can verify that the request came from Telerivet.
|
route_id
|
string, optional
The optional ID of the phone or route you want to send the message from. If omitted, Telerivet will use the same phone that received the incoming message.
|
As an alternative to using the Webhook API for sending auto-replies, it's also possible to use the REST API to send auto-replies.
The REST API provides additional functionality for sending messages that is not available in the Webhook API.
If you send auto-replies using the REST API, we recommend doing so asynchronously, instead of in the Webhook response itself, to ensure that your Webhook returns a response within the 10 second limit.
|
Example
HTTP/1.1 200 OK
Content-Type: application/json
...
{
"messages":[
{
"content":"Reply message text"
},
{
"content":"Another message text",
"to_number":"+16505550123",
"route_id":"YOUR_PHONE_ID"
},
{
"to_number":"*104*12312312*456#",
"message_type":"ussd",
}
]
}
|
Integrating with Rules Engine
In addition to using a Webhook service, it's also possible to add a Webhook action
within other Telerivet services, such as Custom Actions or a Poll.
To add a Webhook action within Custom Actions, click "Add action...", then "Notify webhook URL".
Your Webhook can also directly update any variable within the Rules Engine, including contact.name (the current contact's name),
state.id (the contact's current state within this service), and temporary variables like $foo .
To set variables within the Rules Engine, return a property named variables in your JSON response, with an object containing the variable names and values to update, for example:
{
"variables": {
"contact.name": "John Smith",
"$foo": 42
}
}
For a list of all available variables, see the Rules Engine documentation.
It's possible to have multiple services active at the same time, such as a Webhook service and Custom Actions, or multiple Webhook services.
In this case, make sure the Webhook service(s) are at the top of the list on the Services page, before any non-Webhook services.
By default, Telerivet will only "fall-through" to the next active service if a Webhook service does not send any messages.
If you want Telerivet to fall-through to the next service even if you send a message, set the variable return_value to false ,
(for example, {"variables": {"return_value": false}} ).
|
Example
Custom Actions:
notify webhook URL http://example.com/path/to/webhook_script show log message: foo = [[$foo]]
Your Webhook Script:
<?php
$webhook_secret = 'YOUR_WEBHOOK_SECRET_HERE';
if ($_POST['secret'] !== $webhook_secret)
{
header('HTTP/1.1 403 Forbidden');
echo "Invalid webhook secret";
}
else
{
if ($_POST['event'] == 'incoming_message')
{
header("Content-Type: application/json");
echo json_encode([
'variables' => [
'contact.name' => "John Smith",
'$foo' => 42,
]
]);
}
} from django.views.decorators.csrf import csrf_exempt
from django.http import HttpResponse
import json
@csrf_exempt
def webhook(request):
webhook_secret = 'YOUR_WEBHOOK_SECRET_HERE'
if request.POST.get('secret') != webhook_secret:
return HttpResponse("Invalid webhook secret", 'text/plain', 403)
if request.POST.get('event') == 'incoming_message':
return HttpResponse(json.dumps({
'variables': {
'contact.name': "John Smith",
'$foo': 42
}
}), 'application/json')
/*
* Sample code depends on the Java JSON library:
* http://mvnrepository.com/artifact/org.json/json/20090211
*/
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
public class WebhookStatusServlet extends HttpServlet
{
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
PrintWriter out = response.getWriter();
String webhookSecret = "YOUR_WEBHOOK_SECRET_HERE";
if (!webhookSecret.equals(request.getParameter("secret")))
{
response.setStatus(403);
out.write("Invalid webhook secret");
}
else if ("incoming_message".equals(request.getParameter("event")))
{
response.setContentType("application/json");
try
{
JSONObject variables = new JSONObject();
reply.put("$foo", 42);
reply.put("contact.name", "John Smith");
JSONObject json = new JSONObject();
json.put("variables", variables);
json.write(out);
}
catch (JSONException ex)
{
throw new ServletException(ex);
}
}
}
} using System;
using System.Collections.Generic;
using System.Web;
using System.Web.Mvc;
namespace MyMVCApplication.Controllers
{
public class HomeController : Controller
{
public ActionResult Index()
{
String statusSecret = "YOUR_STATUS_SECRET_HERE";
if (Request["secret"] != statusSecret)
{
Response.StatusCode = 403;
return Content("Invalid status secret");
}
if (Request["event"] == "incoming_message")
{
Dictionary<string,object> variables = new Dictionary<string,object>();
variables["$foo"] = 42;
variables["contact.name"] = "John Smith";
Dictionary<string,object> result = new Dictionary<string,object>();
result["variables"] = variables;
return Json(result);
}
else
{
Response.StatusCode = 400;
return Content("Unknown event");
}
}
}
}
var express = require('express');
var bodyParser = require('body-parser');
var app = express();
var WEBHOOK_SECRET = "YOUR_WEBHOOK_SECRET_HERE";
app.post('/telerivet/webhook',
bodyParser.urlencoded({ extended: true }),
function(req, res) {
var secret = req.body.secret;
if (secret !== WEBHOOK_SECRET) {
res.status(403).end();
return;
}
if (req.body.event == 'incoming_message') {
res.json({
variables: {
'contact.name': "John Smith",
'$foo': 42
}
});
}
res.status(200).end();
}
);
app.listen(8000);
|
Configuring Webhook via REST API
If you are developing an integration that requires setting up incoming message webhooks for multiple Telerivet projects or user accounts, your integration can use the REST API to create the Webhook service instead of requiring the users to copy and paste your webhook URL into the Telerivet web app.
For details, see the documentation for the REST API method project.createService.
|
|
Message Status Notifications
If you enable the Webhook for "Message status notifications" in your Project Settings,
Telerivet will notify your URL via a Webhook whenever the status of an outgoing message changes (e.g. when it is sent or fails to send).
Telerivet will also notify your URL when an outgoing message is first queued, except when sending an individual message via the REST API.
If your message contains any short links, Telerivet will also notify your URL the first time the contact clicks a short link in the message,
providing the time_clicked parameter.
If you send a message via the REST API or Webhook API and specify a status_url , Telerivet will notify that URL for that message, instead of the URL specified in your Project Settings.
When the status of an outgoing message changes, Telerivet will make a HTTP POST request to your URL
with the following POST parameters:
event
|
string
This will be set to send_status .
|
id
|
string, maximum length 34 characters
Telerivet's unique ID for the message (same as returned by the REST API).
|
status
|
One of the following codes representing the current message status:
sent | the message has been successfully sent to the mobile network |
queued | the message has not been sent yet |
failed | the message has failed to send |
failed_queued | the message has failed to send, but Telerivet will try to send it again later |
delivered | the message has been delivered to the recipient phone (if delivery reports are enabled) |
not_delivered | the message could not be delivered (if delivery reports are enabled) |
cancelled | the message was cancelled by the user |
|
error_message
|
string
A description of why the message was not sent successfully (if available).
|
message_type
|
string
Either sms , mms , ussd , or call . Other message types may be added in the future.
|
from_number
|
string
The phone number that the message was sent from (a string, not an integer).
For USSD responses, this is the USSD/MMI code that was requested.
|
to_number
|
string
The phone number that the message was sent to
|
contact_id
|
string, maximum length 34 characters
The ID of the contact that the message was sent to
|
phone_id
|
string, maximum length 34 characters
The ID of the phone that the message was sent from
|
content
|
string
The text of the SMS message
|
time_created
|
The time the message was first queued for sending
|
time_sent
|
The time the message was sent, as a Unix timestamp (UTC), if available. This parameter will be absent if the message has not been sent yet.
|
time_clicked
|
The first time a short link in the message was clicked, if available. This parameter will be absent if the message does not have any short links or if no short links have been clicked.
|
project_id
|
string, maximum length 34 characters
The ID of the Telerivet project associated with this message
|
secret
|
string
An optional secret string that you previously specified, so that you can verify that the request came from Telerivet.
|
contact[name]
contact[time_created]
contact[message_count]
contact[vars][foo]
...
|
Information about the contact who sent or received the message, as stored in your Telerivet contacts database.
The POST parameters are named so that some languages (including PHP) will automatically parse the parameters into an object.
The Webhook API sends the same contact properties as are available in the REST API. See all
|
In addition to the parameters documented above, Telerivet also passes all other REST API message properties as POST parameters.
Your Webhook URL should return a response with HTTP status code 200. Any other HTTP response code will be treated as a failure.
|
Example
<?php
$webhook_secret = 'YOUR_WEBHOOK_SECRET_HERE';
if ($_POST['secret'] !== $webhook_secret)
{
header('HTTP/1.1 403 Forbidden');
echo "Invalid webhook secret";
}
else
{
if ($_POST['event'] == 'send_status')
{
$id = $_POST['id'];
$status = $_POST['status'];
$error_message = $_POST['error_message'];
// do something with the message status, e.g. update your database
}
} from django.views.decorators.csrf import csrf_exempt
from django.http import HttpResponse
import json
@csrf_exempt
def webhook(request):
webhook_secret = 'YOUR_WEBHOOK_SECRET_HERE'
if request.POST.get('secret') != webhook_secret:
return HttpResponse("Invalid webhook secret", 'text/plain', 403)
if request.POST.get('event') == 'send_status':
id = request.POST.get('id')
status = request.POST.get('status')
error_message = request.POST.get('error_message')
# do something with the message status, e.g. update your database
/*
* Sample code depends on the Java JSON library:
* http://mvnrepository.com/artifact/org.json/json/20090211
*/
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
public class WebhookStatusServlet extends HttpServlet
{
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
PrintWriter out = response.getWriter();
String webhookSecret = "YOUR_WEBHOOK_SECRET_HERE";
if (!webhookSecret.equals(request.getParameter("secret")))
{
response.setStatus(403);
out.write("Invalid webhook secret");
}
else if ("send_status".equals(request.getParameter("event")))
{
String id = request.getParameter("id");
String status = request.getParameter("status");
String errorMessage = request.getParameter("error_message");
// do something with the message, e.g. update your database
}
}
} using System;
using System.Collections.Generic;
using System.Web;
using System.Web.Mvc;
namespace MyMVCApplication.Controllers
{
public class HomeController : Controller
{
public ActionResult Index()
{
String statusSecret = "YOUR_STATUS_SECRET_HERE";
if (Request["secret"] != statusSecret)
{
Response.StatusCode = 403;
return Content("Invalid status secret");
}
if (Request["event"] == "send_status")
{
String id = Request["id"];
String status = Request["status"];
String errorMessage = Request["error_message"];
// do something with the message status, e.g. update your database
return Content("");
}
else
{
Response.StatusCode = 400;
return Content("Unknown event");
}
}
}
}
var express = require('express');
var bodyParser = require('body-parser');
var app = express();
var WEBHOOK_SECRET = "YOUR_WEBHOOK_SECRET_HERE";
app.post('/telerivet/webhook',
bodyParser.urlencoded({ extended: true }),
function(req, res) {
var secret = req.body.secret;
if (secret !== WEBHOOK_SECRET) {
res.status(403).end();
return;
}
if (req.body.event == 'send_status') {
var id = req.body.id;
var status = req.body.status;
var error_message = req.body.error_message;
// do something with the message status, e.g. update your database
}
res.status(200).end();
}
);
app.listen(8000);
|
Simulating Status Codes
When sending messages via a Test Number,
you can use the following special phone numbers for the to_number parameter in the REST API to send particular status codes to your Webhook:
+15005550011
|
Simulates the status failed with error message: "Example error message."
|
+15005550012
|
Simulates the status sent , followed by delivered .
|
+15005550013
|
Simulates the status sent , followed by not_delivered with error message: "Example delivery failure message."
|
+15005550014
|
Simulates the status failed_queued with error message: "Example temporary failure message.", followed by the status sent .
|
all other numbers
|
Simulates the status sent .
|
|
|
Broadcast Notifications
If you enable the Webhook for "Broadcast sent" in your Project Settings,
Telerivet will notify your URL via a Webhook whenever a broadcast is sent via Telerivet.
The webhook is triggered shortly after the broadcast is first created. Some messages may have been sent before the webhook is triggered.
When a broadcast is sent, Telerivet will make a HTTP POST request to your URL
with the following POST parameters:
event
|
string
This will be set to send_broadcast .
|
id
|
string, maximum length 34 characters
Telerivet's unique ID for the broadcast.
|
recipients_str
|
string
A string with a human readable description of the first few recipients (possibly truncated)
|
recipients[0][type]
recipients[0][....]
...
|
Details about each of the recipients for the broadcast.
The POST parameters are named so that some languages (including PHP) will automatically parse the parameters into an object.
The Webhook API sends the same properties for the recipients as are available in the REST API. See all
|
estimated_count
|
integer
The approximate number of messages expected to be sent in this broadcast when complete. The actual number of messages may differ from the estimated_count, for example if there are any blocked contacts or if the group membership changes while the broadcast is being sent.
|
content
|
string
The text of the SMS message sent.
|
route_id
|
string, maximum length 34 characters
The ID of the route or phone that the broadcast is sent from.
|
project_id
|
string, maximum length 34 characters
The ID of the Telerivet project associated with this broadcast
|
user_name
|
string
The name of the Telerivet user that sent this broadcast
|
user_email
|
string
The email address of the Telerivet user that sent this broadcast
|
secret
|
string
An optional secret string that you previously specified, so that you can verify that the request came from Telerivet.
|
In addition to the parameters documented above, Telerivet also passes all other REST API broadcast properties as POST parameters.
Your Webhook URL should return a response with HTTP status code 200. Any other HTTP response code will be treated as a failure.
|
Example
<?php
$webhook_secret = 'YOUR_WEBHOOK_SECRET_HERE';
if ($_POST['secret'] !== $webhook_secret)
{
header('HTTP/1.1 403 Forbidden');
echo "Invalid webhook secret";
}
else
{
if ($_POST['event'] == 'send_broadcast')
{
$id = $_POST['id'];
$estimated_count = (int)$_POST['estimated_count'];
$recipients_str = $_POST['recipients_str'];
$content = $_POST['content'];
// do something with the broadcast, e.g. update your database
}
} from django.views.decorators.csrf import csrf_exempt
from django.http import HttpResponse
import json
@csrf_exempt
def webhook(request):
webhook_secret = 'YOUR_WEBHOOK_SECRET_HERE'
if request.POST.get('secret') != webhook_secret:
return HttpResponse("Invalid webhook secret", 'text/plain', 403)
if request.POST.get('event') == 'send_broadcast':
id = request.POST.get('id')
estimated_count = int(request.POST.get('estimated_count'))
recipients_str = request.POST.get('recipients_str')
content = request.POST.get('content')
# do something with the broadcast, e.g. update your database
/*
* Sample code depends on the Java JSON library:
* http://mvnrepository.com/artifact/org.json/json/20090211
*/
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
public class WebhookStatusServlet extends HttpServlet
{
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
PrintWriter out = response.getWriter();
String webhookSecret = "YOUR_WEBHOOK_SECRET_HERE";
if (!webhookSecret.equals(request.getParameter("secret")))
{
response.setStatus(403);
out.write("Invalid webhook secret");
}
else if ("send_broadcast".equals(request.getParameter("event")))
{
}
}
} using System;
using System.Collections.Generic;
using System.Web;
using System.Web.Mvc;
namespace MyMVCApplication.Controllers
{
public class HomeController : Controller
{
public ActionResult Index()
{
String statusSecret = "YOUR_STATUS_SECRET_HERE";
if (Request["secret"] != statusSecret)
{
Response.StatusCode = 403;
return Content("Invalid status secret");
}
if (Request["event"] == "send_broadcast")
{
}
else
{
Response.StatusCode = 400;
return Content("Unknown event");
}
}
}
}
var express = require('express');
var bodyParser = require('body-parser');
var app = express();
var WEBHOOK_SECRET = "YOUR_WEBHOOK_SECRET_HERE";
app.post('/telerivet/webhook',
bodyParser.urlencoded({ extended: true }),
function(req, res) {
var secret = req.body.secret;
if (secret !== WEBHOOK_SECRET) {
res.status(403).end();
return;
}
if (req.body.event == 'send_broadcast') {
}
res.status(200).end();
}
);
app.listen(8000);
|
Synchronizing Contacts
If you enable the Webhook for "Contact added or updated" in your Project Settings, Telerivet will notify your URL each time a contact is added, updated, or deleted, making it easy to keep an external application automatically synchronized with Telerivet's contacts database.
Telerivet will make a HTTP POST request to your URL with the following POST parameters:
event
|
string
This will be set to contact_update .
|
update_type
|
string
A code representing the type of update. May be add , auto_add , update , update_field , add_group , remove_group ,
block_send , unblock_send , or delete
|
id
|
string, maximum length 34 characters
Telerivet's unique ID for the contact
|
phone_number
|
string
Phone number of the contact
|
name
|
string
Name of the contact
|
send_blocked
|
boolean
1 if Telerivet is blocked from sending messages to this contact
|
vars[foo]
vars[bar]
...
|
Custom variables for the contact
|
group_ids[0]
group_ids[1]
...
|
Array of string IDs of Group
List of IDs of groups applied to this contact
|
secret
|
string
An optional secret string that you specified in your Project Settings, so that you can verify that the request came from Telerivet.
|
In addition to the parameters documented above, Telerivet also passes all other REST API contact properties as POST parameters.
Note that this webhook is not triggered for contacts added or updated via Telerivet's REST API or Cloud Script API.
It is also not triggered when a new message is sent or received for a contact, except when a new contact is created.
|
|
Synchronizing Message Metadata
If you enable the Webhook for "Message metadata updated" in your Project Settings, Telerivet will notify your URL when a user updates the metadata for a message (e.g. labels and stars) via the Telerivet web interface. For voice calls, this webhook is also triggered each time a variable is saved (storing key press or a recording URL), and at the end of the call.
Telerivet will make a HTTP POST request to your URL
with the following POST parameters:
event
|
string
This will be set to message_metadata .
|
update_type
|
string
May be star , unstar , add_label , remove_label , set_variable , or call_complete .
|
id
|
string, maximum length 34 characters
Telerivet's unique ID for the message (same as returned by the REST API).
|
starred
|
boolean
1 if the message is starred, 0 otherwise
|
label_ids[0]
label_ids[1]
...
|
Array of string IDs of Label
List of IDs of labels applied to this message
|
vars[foo]
vars[bar]
...
|
Custom variables for this message/call. For IVR calls, the user's key press(es) or audio recording URL are stored in message variables with the same name as the input handler.
|
in_progress
|
boolean
1 if the call is currently in progress, 0 otherwise (voice calls only)
|
secret
|
string
An optional secret string that you specified in your Project Settings, so that you can verify that the request came from Telerivet.
|
contact[name]
contact[time_created]
contact[message_count]
contact[vars][foo]
...
|
Information about the contact who sent or received the message, as stored in your Telerivet contacts database.
The POST parameters are named so that some languages (including PHP) will automatically parse the parameters into an object.
The Webhook API sends the same contact properties as are available in the REST API. See all
|
In addition to the parameters documented above, Telerivet also passes all other REST API message properties as POST parameters.
Note that this webhook is not triggered for messages updated via Telerivet's REST API or Cloud Script API.
|
|
Debugging Webhooks
If your webhook script doesn't work as expected, then you'll need to debug it.
When a webhook fails because it returned a status code other than 200 or took longer than 10 seconds, Telerivet sends an email notification to the address(es) listed in your
Project Settings, and also adds an entry in your service logs. (You can
also view the service logs from the Services page, by clicking "More" then "View logs").
In some cases, the information in the notification email or on the service logs page may be enough for you to figure out why the webhook is failing and how to fix it.
Common errors and solutions include:
- HTTP 403: This is returned by our sample code when the secret in your code does not match the 'secret' parameter sent by Telerivet (see your Services page). Update the secrets so they match.
- HTTP 301 or HTTP 302: Your webhook is redirecting to another URL. Change your webhook URL to the target of the redirect.
- "timed out": Your webhook took more than 10 seconds to return a response. Move long-running tasks out of your webhook script and perform them asynchronously (e.g. invoking REST API methods).
If it is not clear from Telerivet's logs how to resolve the error, the next step would be to add debugging code at various points in your Webhook script to write information to your server's error logs.
For example in PHP you can use error_log("..."); to write text to your server's error log. The location of the log file depends on your web server. On Linux servers this is usually somewhere in /var/log , for example /var/log/nginx/error.log or /var/log/apache2/error.log .
|
|
Testing Webhooks in Development
In order for Telerivet to send a Webhook to your application, your web server generally needs to be available on the public internet.
However, many software developers build and test their applications on their own private computers before deploying the application to a public production environment.
In order to test the Telerivet Webhook API for receiving incoming messages and status notifications in your development environment, you can temporarily expose a port on
your development computer to the public internet, using a process known as tunneling.
There are two basic ways to set up a tunnel to your private computer – using a third-party service, or using one of your own SSH servers.
Third-Party Tunneling Services
There are a few popular third-party services that make it easy to set up a tunnel that exposes a port on your development computer.
Visit their sites to learn more:
Tunneling through your own SSH server
Note: This approach only works if you run your own Linux-based server or VPS (virtual private server). It is typically not available with shared hosting providers.
A reverse SSH tunnel allows Telerivet to send HTTP POST requests to your development computer via an SSH server:
Telerivet's servers <----> SSH Server <----> Your computer
If you have a Linux-based web server, it is probably already running SSH server software called sshd.
By default, sshd is configured to disable reverse SSH tunneling. To enable this functionality, edit the /etc/ssh/sshd_config file on your SSH server and add the following line:
GatewayPorts yes
Be sure to remove any other line starting with GatewayPorts .
Then, connect to your SSH server using the -R flag to set up an SSH tunnel:
ssh <username>@<hostname> -R <publicport>:localhost:<localport>
Replace the parameters shown in brackets as follows:
<username> : Your username on your ssh server. Example: root
<hostname> : The hostname or IP address of your ssh server. Example: myapp.example.com
<publicport> : The port number to publicly expose on your SSH server. Telerivet's Webhook API only allows the following port numbers: 80, 443, 8000, 8080, or 8443. Additionally, the port number must not already be in use by other applications on your SSH server. Often, ports 80 and 443 are already used by your public web server, so they can't be used for reverse SSH tunneling. Recommended: 8000 or 8080
<localport> : The port number on your local development computer where your application is running. There are no restrictions to the port numbers you can use.
Example: 3000
|
|