Skip to content

feat: send a per-occurrence event_id on IAM engagement [NOTP-1520] - #1696

Closed
cconstantine-onesignal wants to merge 1 commit into
mainfrom
cconstantine/notp-1520-iam-event-id
Closed

feat: send a per-occurrence event_id on IAM engagement [NOTP-1520]#1696
cconstantine-onesignal wants to merge 1 commit into
mainfrom
cconstantine/notp-1520-iam-event-id

Conversation

@cconstantine-onesignal

Copy link
Copy Markdown

Summary

Mint a per-occurrence event_id and send it on IAM engagement requests (click,
impression, pageImpression). Turbine deduplicates these on the SDK-supplied
event_id (see OneSignal/turbine#1768), so at-least-once deliveries collapse to
a single event downstream instead of becoming duplicate Kafka records /
double-counted engagement (NOTP-1520).

What changed

  • OSInAppMessagingRequests: new withEventId: param on the Viewed / PageViewed
    / Clicked requests, added to the body as event_id.
  • OSMessagingController: mint [NSUUID UUID] at each engagement call site.
  • IAMRequestTests updated to pass and assert event_id (the body check is an
    exact match).

Why mint at request-construction

OneSignalClient reattempts a failed request (statusCode >= 500 || == 0, i.e.
5xx or a network error, up to MAX_ATTEMPT_COUNT) by re-executing the same
OneSignalRequest object, whose parameters are set once at construction. So
minting the id when the request is built keeps it stable across those retries,
which is exactly the response-lost duplicate turbine needs to fold. After the
reattempts are exhausted, the controller's onFailure clears its guard, so a
later send is a redisplay = a new occurrence = a new id.

This client retry makes iOS the primary retry-driven duplicate source for IAM
engagement.

Validation

Code-only change (no local build in this environment); relies on CI. Body
assertions added to IAMRequestTests for all three requests.

Task / Ticket

https://linear.app/onesignal/issue/NOTP-1520

Turbine deduplicates IAM engagement (click/impression/pageImpression) on an
SDK-supplied event_id. Mint a fresh UUID per engagement occurrence and send
it as event_id so at-least-once deliveries collapse to one event downstream.

iOS's OneSignalClient reattempts failed requests (5xx / network error) by
re-executing the *same* request object, whose parameters are set once at
construction -- so minting the id when the request is built keeps it stable
across those retries, which is exactly the duplicate turbine needs to fold.
Distinct engagements (including a later redisplay) build a new request and
get a new id.

- OSInAppMessagingRequests: new withEventId: param on the Viewed / PageViewed
  / Clicked requests, added to the body as event_id.
- OSMessagingController: mint [NSUUID UUID] at each engagement call site.
- IAMRequestTests updated to pass and assert event_id.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@cconstantine-onesignal cconstantine-onesignal changed the title Send a per-occurrence event_id on IAM engagement [NOTP-1520] feat: send a per-occurrence event_id on IAM engagement [NOTP-1520] Jul 30, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant