feat(inbox): type trackingIds and add clickTrackingId for SDK parity - #64
Open
mikemilla wants to merge 1 commit into
Open
feat(inbox): type trackingIds and add clickTrackingId for SDK parity#64mikemilla wants to merge 1 commit into
mikemilla wants to merge 1 commit into
Conversation
Not a bug fix — worth saying plainly, because it looked like one.
Unlike courier-flutter, this SDK was never broken. `InboxMessage` already declared
`trackingIds`, and `fromJson` already passes `parsed.trackingIds` into the
constructor, so the field the native SDKs send has always reached JS. The
high-level `Courier.shared.clickMessage({ messageId })` also resolves the tracking
id natively, so click tracking worked regardless.
What was missing was reachability. `trackingIds` was typed `{ [key: string]: any }`,
so a caller using the lower-level `client.inbox.click({ messageId, trackingId })`
had to guess key names off an untyped map with no autocomplete and no compiler
check. And `clickTrackingId` — a convenience that exists on courier-ios,
courier-android and now courier-flutter — had no equivalent here, making this the
only SDK where you had to reach through the map by hand.
- `InboxMessageTrackingIds` covering all seven ids the server publishes (archive,
channel, click, deliver, open, read, unread), exported as a type
- `trackingIds` field and constructor parameter typed to it
- `clickTrackingId` getter, matching the other SDKs
Reads from the root of the message, which is where both the GraphQL read and the
`iwpv=v2` socket publish it. Nothing here depends on the protocol version or on a
native SDK release, so this is independent of the pending pin bump.
Tests: 5 new cases (all seven ids parsed, clickTrackingId present/absent/partial,
and that a nested `data.trackingIds` copy — the v1/legacy shape — is not read).
130/130 passing, `tsc --noEmit` clean, eslint clean.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Ticket: C-19804
Not a bug fix — worth saying plainly
Unlike courier-flutter (which genuinely had no
trackingIdsfield), this SDK was never broken:InboxMessagealready declaredtrackingIdsfromJsonalready passesparsed.trackingIdsinto the constructor, so the field the native SDKs send has always reached JSCourier.shared.clickMessage({ messageId })resolves the tracking id natively, so click tracking worked regardlessI initially reported the opposite on C-19804 — that was wrong, from globbing
*.tsand missing.tsx. Retracted there.What was actually missing: reachability
trackingIdstype{ [key: string]: any }— guess the key names, no autocomplete, no compiler checkInboxMessageTrackingIds, all seven idsclickTrackingIdThat matters for the lower-level
client.inbox.click({ messageId, trackingId }), which does need the id — and this was the only SDK where you had to reach through an untyped map to get it.Change
InboxMessageTrackingIdscovering all seven ids the server publishes: archive, channel, click, deliver, open, read, unread — exported as a typetrackingIdsfield and constructor parameter typed to itclickTrackingIdgetter for parityRead from the root of the message, where both the GraphQL read and the
iwpv=v2socket publish it. Independent of the protocol version and of the pending native pin bump.Tests
130/130 passing,
tsc --noEmitclean, eslint clean. 5 new cases:clickTrackingIdpresent, absent, and present-but-partialdata.trackingIdscopy (the v1/legacy shape) is not readOne of these caught a wrong assumption of mine while writing it:
fromJsonpassesundefinedinto a parameter defaulting tonull, so an absenttrackingIdslands asnull, notundefined. The test now pins that actual behaviour.🤖 Generated with Claude Code