Notification Skip Send Event
When a notification request is processed, the system checks user preferences to determine which channels to send on. If a channel is enabled in the notification config but disabled in the user's preferences, a SkipSend tracking event is published instead of sending the notification on that channel.
Why
The SkipSend event provides visibility into notifications that were intentionally not sent due to user preferences. This enables analytics and reporting on how often users opt out of specific channels, helping inform product decisions around notification strategy.
When It Is Published
A SkipSend event is published in two scenarios:
1. No Parent Notification Created
When a user has all enabled channels disabled in their preferences, no parent notification record is created. In this case, a SkipSend event is published for each enabled channel the user has opted out of.
- Location:
createParentNotificationsinlib/workers/request/handler.go notification_id: Empty string (no parent notification exists)- Example: A notification config has email, in-app, and push enabled, but the user has all three disabled. Three
SkipSendevents are published (one per channel).
2. Parent Notification Created, Channel Skipped
When a user has some enabled channels active but has disabled others, a parent notification is created. Individual SkipSend events are then published for each disabled channel during the channel-specific fan-out steps:
- Email:
createEmailNotificationsinlib/workers/request/handler.go - In-App:
createInAppNotificationsinlib/workers/request/handler.go - Push:
createPushNotificationsinlib/workers/request/handler.go
In these cases, the notification_id field is populated with the parent notification's ID.
SkipSend Event Fields
| Field | Description |
|---|---|
uuid | Deterministic UUID derived from idempotency_key, user_id, and channel |
created_at | Timestamp in microseconds (UTC) |
notification_name | Name from the notification config |
notification_version | Version from the notification config |
notification_id | Parent notification ID, or empty if no parent was created |
request_id | Request ID from context |
idempotency_key | Idempotency key from context |
channel | One of: email, in_app, push |
reason | user_preference_disabled |
user_id | The user whose preference caused the skip |
source | notifications_request_worker |
Protobuf Definition
The event uses the SkipSend message from the tracking-internal protobuf package:
joinhandshake.buf.dev/gen/go/joinhandshake/tracking-internal/protocolbuffers/go/tracking_internal/notifications/v1
Idempotency
The uuid for each SkipSend event is generated deterministically using a SHA-256 hash of {idempotency_key}:{user_id}:{channel}, truncated to 16 bytes for UUID generation. This ensures that retried requests produce the same event UUIDs.