Delivery Events

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.

Overview

During the process of delivering a message to a user, three important events can happen:

Webhook TriggerDescription
conversation:message:delivery:channelThe message has been delivered to the channel (e.g. WhatsApp), but it may not have yet been received by the user.
conversation:message:delivery:userThe message has been delivered to the user. This event is only supported by certain channels
conversation:message:delivery:failureThe 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).

Message delivery flow
Message delivery events flow

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.

Channel Delivery Confirmation

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
            }
        }
    ]
}

User Delivery Confirmation

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
            }
        }
    ]
}

Delivery Failure

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 Support

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:

Use Cases

Tracking Delivery State in Your Software

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.

Early Detection of Delivery Issues

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:

  • The 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.
  • The destination property to know for which channel the message failed to deliver.
  • The 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.

Delivery Events for Multi-Channel Users

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

  • the app user is linked to multiple types of SDK channel
  • the app user’s primary channel is a third-party channel and the app user is linked to a SDK channel
  • the app user’s non-primary channel supports receiving messages without a notification

You can the use destination property of delivery events to know to which channel a message is delivered.

Known Issues

Twilio

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.