Overview
The RPI Callback Service is used to retrieve results from the following channel providers:
-
SendGrid
-
mPulse
-
Twilio
-
Outbound Delivery
Configuration
The redpoint-interaction-plugins-callbackservicewebapi container's port 8080 or 8443 must be exposed. The following application settings JSON file provides an example of a Callback service configured to use the RabbitMQ and Azure Storage providers.
Ensure that "CallbackServiceQueuePath" is unique across all tenants, applicable to all relevant providers with Callback Services (Twilio, SendGrid, mPulse, and Outbound Delivery).
{
"CallbackServiceConfig": {
"QueueEnabled": true,
"QueueProvider": {
"ChannelLabel": "SendGrid",
"CallbackServiceQueuePath": "RPICallbackService",
"CallbackServiceQueueSettings": {
"Assembly": "RedPoint.Resonance.RabbitMQAccess",
"Type": "RedPoint.Resonance.RabbitMQAccess.RabbitMQFactory",
"Settings": [
{
"Key": "HostName",
"Value": "queueservice",
"Values": []
},
{
"Key": "VirtualHost",
"Value": "/",
"Values": []
},
{
"Key": "UserName",
"Value": "redpointdev",
"Values": []
},
{
"Key": "Password",
"Value": "RP$v51wGtDDvqIYuf/L6vJ1c09Bw==",
"Values": []
}
]
}
},
"ExternalContentProvider": {
"Folder": "https://rpidevstorage3.blob.core.windows.net/rpi",
"SaveEmailEvents": false,
"ExternalContentSettings": {
"Assembly": "RedPoint.Azure.Shared",
"Type": "RedPoint.Azure.Shared.AzureStorage.AzureStorageConnector",
"Settings": [
{
"Key": "StorageAccount",
"Value": "rpidevstorage3",
"Values": null
},
{
"Key": "AccessKey",
"Value": "$v51lxxxxxxxxxO",
"Values": null
},
{
"Key": "EnableCdn",
"Value": false,
"Values": null
},
{
"Key": "BlobServiceEndpoint",
"Value": null,
"Values": null
},
{
"Key": "CdnEndpoint",
"Value": null,
"Values": null
},
{
"Key": "UseAzureIdentityAuthentication",
"Value": true,
"Values": null
}
]
}
},
"EnableHttpsRedirection": false
}
}
The QueueProvider setting can be sourced from the RPI Realtime Queue Providers Configuration interface, by selecting the Copy JSON configuration to clipboard button.
The ExternalContentProvider setting is only utilized for the Events external folder property in the SendGrid channel configuration setting. This can be done selecting the Copy JSON configuration to clipboard button in the RPI External Content Providers configuration interface.
The setting is not used when configuring the Callback Service for use with mPulse. If the ExternalContentProvider setting is not configured, a call to the /status API endpoint will return an overall Error state. However, this error has no bearing on processing callback service events if QueueEnabled is set to true.
API endpoints
The Callback service supports the following API endpoints (where <channel label> is one of SendGrid, mPulse, Twilio, or Outbound%20Delivery):
-
api/test: tests service accessibility. -
api/status?channelLabel=<channel label>: returns specified channel's overall state. -
api/postevents?channelLabel=<channel label>: returns captures specified channel events.
mPulse Auditing
When mPulse events are posted to the Callback service, they can be audited by setting ChannelLabel to “mPulse” in the service's ExternalContentProviders appsettings configuration. When this is the case, events will be written asynchronously into the Events external folder specified at the channel's configuration. Audit files are named in accordance with the following format: 'AUDIT_yyyyMMddHHmmssfff_GUID_Events.json'.
What the Twilio Callback Service does in RPI
When you set the Callback service URL on a Twilio channel, that URL is the address of an RPI-hosted endpoint (the Callback Service Web API) that Twilio will POST to whenever something happens on a message, both outbound delivery status changes and inbound replies.
The endpoint
-
Route:
POST {CallbackServiceURL}/api/PostEvents?channelLabel=Twilio -
Source:
CallbackServiceController.cs:32-68 -
Accepts Twilio's native
application/x-www-form-urlencodedpayloads (and JSON), reads the body, and hands it toCallbackServiceHelper.Write(...) -
Always responds
200 OKto Twilio so Twilio doesn't retry indefinitely
What gets captured
The endpoint handles two categories of Twilio events into the same model (TwilioSmsEvent.cs):
-
Outbound delivery status:
MessageStatusfield maps to RPI fulfillment states declared inChannelTwilio.cs:600-608:-
Queued,Sent,Delivered,Undelivered,Failed,InvalidNumber -
Plus
ErrorCode/ErrorMessagefor diagnostic detail
-
-
Inbound MO (mobile-originated) replies: events with
EventType=IncomingMessageEventcarryBody,From,To, etc.
How the data lands
Twilio → POST /api/PostEvents → CallbackServiceHelper.Write
→ WriteToQueue (RabbitMQ/Kafka)
→ CallbackServiceProcessor (consumer)
→ RPI_TwilioEvents (raw) + OfferHistory_TwilioTracking (per-message)
→ fulfillment-state counts updated on the originating offer
→ if MO reply matches a STOP-class keyword: TwilioSMS_Suppression row written
The queueing step (CallbackServiceProcessor) decouples receipt from processing so Twilio gets fast 200 OKs even under load.
Inbound keyword handling (STOP / OPT-OUT / surveys)
ChannelTwilio.AddChannelSpecificStates declares the recognized reply keywords: STOP, STOPALL, UNSUBSCRIBE, CANCEL, END, QUIT, OPTOUT, REVOKE, START, YES, UNSTOP, HELP, INFO, plus a generic Survey Response bucket.
-
Suppression keywords write the recipient's number into
TwilioSMS_Suppressionso subsequent sends skip them. -
Free-text replies are captured against the Survey Response state only when Capture Survey Responses is enabled on the channel (
ChannelTwilio.cs:196-210). With that off, keyword templates fail validation (lines 908-910).
Callback vs. scheduled bulk export
The two ingestion paths coexist: SynchronizeData (ChannelTwilio.cs:844-868) is unconditional; there is no if (CallBackURL is set) branch. So:
|
Path |
Latency |
Source |
Role |
|---|---|---|---|
|
Callback |
Real-time (seconds) |
Twilio → RPI webhook |
Primary disposition stream once configured |
|
Bulk Export / Insights polling |
Scheduled (default 10 min) |
RPI → Twilio Insights API |
Backfill + reconciliation; covers any callbacks Twilio retried unsuccessfully or missed |
This is intentional: the bulk export protects against webhook delivery failures.
Additional resources
-
mPulse:
-
Outbound Delivery:
-
SendGrid:
-
Twilio: