When sending a message, some platforms offer a deeper level of delivery confirmation that serves to confirm that a message was received by the intended user. Sunshine Conversations exposes a set of delivery event webhook triggers that can be used to track message delivery at each step of the way.
During the process of delivering a message to a user, three important events can happen:
Webhook Trigger | Description |
---|---|
conversation:message:delivery:channel | The message has been delivered to the channel (e.g. WhatsApp), but it may not have yet been received by the user. |
conversation:message:delivery:user | The message has been delivered to the user. This event is only supported by certain channels |
conversation:message:delivery:failure | The message could not be delivered (either to the channel or to the user). Each failure will also include an error code . |
These three triggers can be integrated in a conversation user interface to provide in-depth delivery information or they can be used for troubleshooting purposes. The conversation:message:delivery:user
trigger is useful to detect failures where the delivery flow of a channel is more complex. For example, SMS providers might accept a message (and trigger a conversation:message:delivery:channel
event) but then fail to deliver the message to the user because a carrier rejected the message later on (which triggers a subsequent conversation:message:delivery:failure
event).
Our API Reference explains how to configure and manage webhooks for your app using our API. Alternatively, you can use the dashboard to subscribe to the webhooks.
The conversation:message:delivery:channel
webhook trigger reports the successful handoff of a message from Sunshine Conversations to the destination channel. When this event is fired, it means that Sunshine Conversations has sent the message to the appropriate channel API, and received a response indicating that the message was accepted. Depending on the capabilities of the destination channel, this event does not guarantee that the message has reached the user, rather it means that the channel has accepted the message and will attempt delivery. See Channel Support below.
A isFinalEvent
field is included in this webhook payload. When its value is false
it means that Sunshine Conversations is awaiting a further user delivery confirmation from the channel, which will in turn produce a follow-up conversation:message:delivery:user
or conversation:message:delivery:failure
event indicating whether the channel was able to deliver the message to the user or not. Note that isFinalEvent: false
does not strictly guarantee that such a follow-up event will be triggered; your code should gracefully handle the case where no follow-up delivery webhook is sent.
{
"app": {
"id": "5fb29b20fee5422428712475"
},
"webhook": {
"id": "5ff5e98b0d0c6d8925594923",
"version": "v2"
},
"events": [
{
"id": "5ff7595eafcaab0a685ff889",
"createdAt": "2021-01-07T18:56:30.666Z",
"type": "conversation:message:delivery:channel",
"payload": {
"conversation": {
"id": "2d4fd3d00715d1e64611e248",
"type": "personal"
},
"user": {
"id": "71268330a47f5c4b541fce46"
},
"destination": {
"type": "twilio",
"integrationId": "5ff75853b1c3000a6ad4f7f5"
},
"externalMessages": [
{
"id": "SM98cf27c00ada4502aeba7ee784ab6c93"
}
],
"message": {
"id": "5ff7595eb1c3000a6ad4f7fb"
},
"isFinalEvent": false
}
}
]
}
For channels that do not support delivery confirmation, isFinalEvent
will be true
indicating that this is the last delivery event that Sunshine Conversations will send for a given message.id
and destination.type
.
{
"app": {
"id": "5fb29b20fee5422428712475"
},
"webhook": {
"id": "5ff5e98b0d0c6d8925594923",
"version": "v2"
},
"events": [
{
"id": "5ff5ea19586a5289264fe738",
"createdAt": "2021-01-06T16:49:29.986Z",
"type": "conversation:message:delivery:channel",
"payload": {
"conversation": {
"id": "6f52af604c607e7ce01e6c52",
"type": "personal"
},
"user": {
"id": "004ef0350baa219fcdcf121a"
},
"destination": {
"type": "ios",
"integrationId": "5fb6a33ff3c83e50f3daedce"
},
"message": {
"id": "5ff5ea190d0c6d8925594926"
},
"isFinalEvent": true
}
}
]
}
conversation:message:delivery:user
webhooks indicate that a message successfully reached the user. The webhook always has an associated conversation:message:delivery:channel
event with the same message.id
and destination.type
. No further webhook trigger will be sent as a follow-up to this webhook. This terminal message delivery state is represented by isFinalEvent: true
.
{
"app": {
"id": "5fb29b20fee5422428712475"
},
"webhook": {
"id": "5ff5e98b0d0c6d8925594923",
"version": "v2"
},
"events": [
{
"id": "5ff7595fafcaab0a685ff88b",
"createdAt": "2021-01-07T18:56:31.810Z",
"type": "conversation:message:delivery:user",
"payload": {
"conversation": {
"id": "2d4fd3d00715d1e64611e248",
"type": "personal"
},
"user": {
"id": "71268330a47f5c4b541fce46"
},
"destination": {
"type": "twilio",
"integrationId": "5ff75853b1c3000a6ad4f7f5"
},
"externalMessages": [
{
"id": "SM98cf27c00ada4502aeba7ee784ab6c93"
}
],
"message": {
"id": "5ff7595eb1c3000a6ad4f7fb"
},
"isFinalEvent": true
}
}
]
}
conversation:message:delivery:failure
can occur if a message cannot be sent to a channel or if a message cannot reach a user. In both cases, the webhook body will include an error
key giving the details of the failure. No further webhook trigger will be sent as a follow-up to this webhook. This terminal message delivery state is represented by isFinalEvent: true
.
{
"app": {
"id": "5ebee0975ac5304b664a12fa"
},
"webhook": {
"id": "5f4eaef81e3dcc117c7ba48a",
"version": "v2"
},
"events": [
{
"id": "5f74a0d52b5315fc007e798a",
"createdAt": "2020-09-30T15:14:29.834Z",
"type": "conversation:message:delivery:failure",
"payload": {
"conversation": {
"id": "f52b01137aa6c250bc7251fa",
"type": "personal"
},
"user": {
"id": "26508c10541a4b0ff472e5e2",
"externalId": "912382197"
},
"destination": {
"type": "twilio",
"integrationId": "5ecc061987d4d413774a8131"
},
"message": {
"id": "5f74be6256be263abf0ffd5f"
},
"isFinalEvent": true,
"error": {
"code": "uncategorized_error",
"message": "Unsupported message type `form`"
}
}
}
]
}
Channel delivery confirmation is supported on all channels, including SDKs.
User delivery confirmation is only supported on a subset of channels:
Channel Messages IDs are included in the webhook payload for the following channels:
To expose the delivery state of a Sunshine Conversations message in your software, you must subscribe to all delivery webhooks. Delivery state has to be tracked per channel, which is included in the webhook payload as the destination
property.
To track the delivery state of a message, you can handle the delivery events in the following way:
Receiving a conversation:message:delivery:channel
webhook confirms that a message was delivered to a channel. Use the destination
and the message.id
properties to take note that the message was delivered to the specified channel. Depending on the channel, receiving conversation:message:delivery:channel
might not confirm that the message has truly reached the user. If the isFinalEvent
flag is true
, it indicates that the message can be considered delivered. However, if isFinalEvent
is false
, then the message cannot be considered fully delivered yet. A further event is expected (either a conversation:message:delivery:failure
or conversation:message:delivery:user
trigger may occur).
Receiving a conversation:message:delivery:user
webhook indicates that the message is now delivered to the user on the channel represented by the destination
.
Receiving a conversation:message:delivery:failure
webhook means that the message didn’t reach the user. To know the reason for the failure, use the error
property included in the webhook payload.
Another way to use delivery events is to keep track of messages that don’t reach the user. If a lot of conversation:message:delivery:failure
webhooks are triggered, it can indicate that there is a configuration problem on the third-party channel.
The best way to debug these issues is to add alerts or logs when this event occurs. The properties useful to debug delivery failures are:
error
property because it includes both a generic Sunshine Conversations error code
property, along with an underlyingError
which has the channel-specific information necessary to debug the failure.destination
property to know for which channel the message failed to deliver.externalMessages
property to know which messages in the third-party channel failed to deliver. This is useful if you need to get more information about a delivery failure directly from the third-party channel.When a message is sent to an app user with multiple channels linked, many delivery events can be sent for the same Sunshine Conversations message. The delivery events reflect the automatic channel delivery rules.
More specifically, delivery events for the same Sunshine Conversations message can be sent multiple times if
You can the use destination
property of delivery events to know to which channel a message is delivered.
When sending images to an iOS device, Twilio SMS has not been reliably confirming delivery to the end user. Sunshine Conversations will always trigger the conversation:message:delivery:channel
webhook but the corresponding conversation:message:delivery:user
cannot be relied upon.