Real-world Activity examples
What this document covers:
- What activity is: Learn about the various types of activities that Pendula emits, including messaging, experience lifecycle activity, and inbound message matching.
- How activities are structured: Each activity is provided in a structured JSON format, which includes contextual data like the flow, experience, and additional custom information.
- How to use these activities: These activities can be consumed by third-party systems for monitoring, reporting, or alerting purposes. By understanding the structure of each activity, you can create meaningful insights or automate actions based on them.
If you’re looking for an introduction to Activity Sync, please visit this article.
Workflow context
For every activity, there is what’s called workflowContext (object). The workflowContext object contains all the relevant contextual information for that activity:
- The associated experience (experienceContext: experienceID)
- The associated flow (flowContext: flowId, flowName, flowVersion)
- The associated node within the flow (nodeContext: currently unsupported)
While all activities include workflowContext, some are not fully populated yet (Inbound message unmatched, inbound message trigger). We are working to implement workflowContext consistently for all activities.
"workflowContext": {
"experienceContext": {
"experienceId": "501b95b3-06d3-4398-9ad4-b2563e158308"
},
"flowContext": {
"flowId": "b07a5e44-04e3-4698-a799-04c558b77147",
"flowName": "My first flow",
"flowVersion": 2
},
"nodeContext": null
}
nodeContext is currently unsupported.
Experience activity
experience-start
The very first activity for an experience is an experience-start activity:
{
"experienceId": "60b34d82-7781-474b-ad10-4bca1a774e14",
"timestamp": "2024-08-27T13:25:04.913Z",
"workflowContext": {...},
"customContext": {},
"kind": "experience-start"
}
experience-finish (outcome: success)
Here is a successful, ‘Complete’ experience-finish activity:
{
"experienceId": "60b34d82-7781-474b-ad10-4bca1a774e14",
"timestamp": "2024-08-28T13:40:13.482Z",
"outcome": {
"success": {
"value": {}
}
},
"workflowContext": {...},
"customContext": {},
"kind": "experience-finish"
}
experience-finish (outcome: failure)
Here is a failed, ‘Failed’ experience-finish activity. Before this activity, there may be other activities signalling what caused the experience to fail and finish (for instance, validation-failed
for a message or bounce
)
{
"experienceId": "60b34d82-7781-474b-ad10-4bca1a774e14",
"timestamp": "2024-08-28T14:12:52.134Z",
"outcome": {
"failure": {
"errorMessage": "Unhandled outcome for messaging/sendSenderIdSmsWithOutcome: failure/validation-error. Context: {\\"rawArgs\\":{\\"message\\":{\\"kind\\":\\"handlebars\\",\\"handlebars\\":\\"Activity Sync - Unmatched Trigger node - SENT outcome\\"},\\"senderId\\":{\\"kind\\":\\"handlebars\\",\\"handlebars\\":\\"PENDULA_TEST\\"},\\"recipientNumber\\":{\\"kind\\":\\"handlebars\\",\\"handlebars\\":\\"{{ unmatchedMessageTrigger_1.fromNumber }}\\"},\\"successTimeoutMins\\":{\\"kind\\":\\"number\\",\\"number\\":1}},\\"outputs\\":{\\"outcome\\":\\"failure\\",\\"outcomeReason\\":\\"validation-error\\",\\"timestamp\\":1724854371406},\\"args\\":{\\"message\\":\\"Activity Sync - Unmatched Trigger node - SENT outcome\\",\\"senderId\\":\\"PENDULA_TEST\\",\\"recipientNumber\\":\\"+61401260405\\",\\"successTimeoutMins\\":1},\\"type\\":\\"messaging/sendSenderIdSmsWithOutcome\\",\\"nodeId\\":\\"node-g2zkv\\"}",
"errorCode": "experiences/fail"
}
},
"workflowContext": {...},
"customContext": {},
"kind": "experience-finish"
}
experience-failed
And finally, here is an ‘Error’ experience-failed activity. If multiple of these activities are detected within a flow; the flow itself will be stopped and also set to status ‘Error’.
{
"experienceId": "ee4ee007-2bb2-41de-8da3-038cfe33564d",
"timestamp": "2024-09-04T00:05:23.443Z",
"workflowContext": {...},
"customContext": {},
"errorDetails": [
{
"errorMessage": "Not found: inboundWebhookTrigger_1 (full path: inboundWebhookTrigger_1.message). Available fields were: AvailableFields[inboundSMSTrigger_1.fromNumber:<+.10.5>,inboundSMSTrigger_1.matchedIntent:<m.8.d>,inboundSMSTrigger_1.matchedPart:<M.8.d>,inboundSMSTrigger_1.matchedType:<E.19.)>,inboundSMSTrigger_1.messageBody:<M.8.d>,inboundSMSTrigger_1.timestamp:<number>]",
"errorCode": null
}
],
"kind": "experience-failed"
}
Messaging events
A message being ‘queued’ is the first activity in the process of sending a message. The message queued activity contains all of the relevant information for the lifecycle of a message (recipient, message body, attachments etc) and generates a message ID.
Any subsequent activities (sent to gateway, delivered, opened, any failures etc) can all be correlated back to the initial queued activity using the message ID.
queued (SMS)
Here is a message queued activity for an SMS:
{
"messageId": "1d8e4e9c-69d8-4cd1-83fe-c13ef6870cfd",
"payload": {
"sender": "0000000000",
"recipient": "+61412345678",
"body": "Thanks for signing up, John.",
"segmentCount": 1,
"kind": "sms"
},
"timestamp": "2024-08-28T13:38:46.210055990Z",
"workflowContext": {...},
"customContext": {},
"kind": "queued"
}
queued (email)
Here is a message queued activity for an email:
{
"messageId": "3064433f-d939-4df9-b49b-a2fa2573bce2",
"payload": {
"sender": "me@appleseed.com",
"recipient": "john.smith@bananas.com",
"subject": "Thanks for registering with us.",
"body": "<hmtl>\\n <body>\\n Hello world!\\n </body>\\n</hmtl>",
"plainTextBody": "\\n \\n Hello world!\\n \\n",
"replyTo": "me@appleseed.com",
"attachments": [
{
"filename": "welcomepack.pdf"
},
{
"filename": "file2.png"
}
],
"kind": "email"
},
"timestamp": "2024-08-29T01:18:25.532229654Z",
"workflowContext": {...},
"customContext": {},
"kind": "queued"
}
sent-to-gateway
Here is a message sent to gateway activity for SMS and email:
{
"messageId": "1d8e4e9c-69d8-4cd1-83fe-c13ef6870cfd",
"timestamp": "2024-08-28T13:38:46.434638837Z",
"workflowContext": {...},
"customContext": {},
"kind": "sent-to-gateway"
}
delivered
Here is a message delivered activity for SMS and email:
{
"messageId": "1d8e4e9c-69d8-4cd1-83fe-c13ef6870cfd",
"timestamp": "2024-08-28T13:38:52.362Z",
"workflowContext": {...},
"customContext": {},
"kind": "delivered"
}
opened
Here is a message opened activity for SMS and email:
{
"messageId": "3064433f-d939-4df9-b49b-a2fa2573bce2",
"timestamp": "2024-08-29T01:19:41.746Z",
"workflowContext": {...},
"customContext": {},
"kind": "opened"
}
bounced
Here is a message bounced activity for SMS and email:
{
"messageId": "ad45e9e3-e0ae-48f9-bdc0-e7c328a10b0b",
"errors": [
{
"errorMessage": "Bad request",
"errorCode": "explanation"
}
],
"timestamp": "2024-08-28T14:01:52.132Z",
"workflowContext": {...},
"customContext": {},
"kind": "bounced"
}
validation-failed
Here is an activity for when a message fails to send due to validation failing:
{
"messageId": "fb1ec07a-42ae-4b90-ae02-5b6cc8f6a2e3",
"errors": [
{
"errorMessage": "NonEmptyList(Recipient must be a valid phone number, got: Beepboop. )",
"errorCode": null
}
],
"timestamp": "2024-09-03T04:29:45.419079448Z",
"workflowContext": {...},
"customContext": {},
"kind": "validation-failed"
}
rejected-by-gateway
{
could not replicate
}
Inbound messages & replies
inbound-matched-intent (trigger)
Here is a message inbound matched trigger activity (this happens after an experience-start activity):
Note that workflowContext is not fully populated: flowName and flowVersion
{
"messageId": "d3703474-8c92-4ee8-acf0-5353407bbc71",
"parentMessageId": "1d8e4e9c-69d8-4cd1-83fe-c13ef6870cfd",
"matchedIntentKey": "optin",
"matchedType": "Rule Match (Trigger)",
"matchedPart": "opt-in",
"body": "I'd like to opt-in",
"fromNumber": "+61412345678",
"timestamp": "2024-09-03T03:48:49.187411Z",
"workflowContext": {
"experienceContext": {
"experienceId": "6c36658f-6017-449e-9f91-3f23e3e9876a"
},
"flowContext": {
"flowId": "7d39b190-71fd-4295-9a48-1285f083de95",
"flowName": "?",
"flowVersion": 0
},
"nodeContext": null
},
"flowId": "7d39b190-71fd-4295-9a48-1285f083de95",
"customContext": {},
"kind": "inbound-matched-intent"
}
inbound-matched-intent (reply)
Here is a reply:
{
"messageId": "5ae77323-c8c5-4858-ac35-27798e98d6e9",
"parentMessageId": "e5cebadf-f1bc-4c2b-b892-f7ddd1bb3e59",
"matchedIntentKey": "upgrade",
"matchedType": "Rule Match (Conversation)",
"matchedPart": "upgrade",
"body": "I'd like to upgrade",
"fromNumber": "+61412345678",
"timestamp": "2024-09-03T04:27:52.953530Z",
"workflowContext": {...},
"flowId": "7d39b190-71fd-4295-9a48-1285f083de95",
"customContext": {},
"kind": "inbound-matched-intent"
}
inbound-unmatched
Here is a message inbound unmatched activity (this happens after an experience-start event):
Note that workflowContext is not fully populated: flowID, flowName and flowVersion
{
"messageId": "e46a9bce-f03e-4232-b68c-f27fce70a99f",
"payload": {
"sender": "+61487654321",
"recipient": "+61412345678",
"body": "I need some help",
"kind": "sms"
},
"timestamp": "2024-08-29T01:18:24.792807Z",
"workflowContext": {
"experienceContext": {
"experienceId": "60b34d82-7781-474b-ad10-4bca1a774e14"
},
"flowContext": {
"flowId": "?",
"flowName": "?",
"flowVersion": 0
},
"nodeContext": null
},
"customContext": {},
"kind": "inbound-unmatched"
}