Skip to content

feat(inbox): expose trackingIds on InboxMessage - #49

Closed
mikemilla wants to merge 1 commit into
mainfrom
mike/c-19804-flutter-inbox-message-tracking-ids
Closed

feat(inbox): expose trackingIds on InboxMessage#49
mikemilla wants to merge 1 commit into
mainfrom
mike/c-19804-flutter-inbox-message-tracking-ids

Conversation

@mikemilla

Copy link
Copy Markdown
Collaborator

Ticket: C-19804

Flutter apps could not track inbox clicks at all

InboxMessage had no trackingIds field, so fromJson dropped the key. Meanwhile CourierClient.inbox.click requires a trackingId:

Future click({required String messageId, required String trackingId}) async

…with no way to obtain one from the message. So click tracking was effectively unreachable from Dart.

The data was already arriving

Both platform handlers serialize a message with the native SDK's toJson(), and both native InboxMessage types encode trackingIds. The key has always been present in the payload crossing the platform channel — this model just never read it.

That's why this part was never blocked, unlike the rest of C-19804: no protocol version, no native SDK release, nothing to wait on.

Change

  • InboxMessageTrackingIds covering all seven ids the server publishes: archive, channel, click, deliver, open, read, unread
  • read in fromJson, written in toJson
  • clickTrackingId convenience accessor for the id click() needs
  • parsing is defensive — the field arrives untyped over a platform channel, so a non-object value yields null rather than throwing

Read 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.

Tests

First test directory in this package. flutter test 7/7, flutter analyze clean:

  • all seven ids parsed; clickTrackingId accessor
  • absent, partial, and non-object trackingIds inputs
  • toJson round-trip survives a second parse
  • other fields unaffected

🤖 Generated with Claude Code

Flutter apps could not track inbox clicks at all. `InboxMessage` had no
`trackingIds` field, so `fromJson` dropped the key on the floor, while
`CourierClient.inbox.click` requires the caller to pass a `trackingId` — with no
way to obtain one from the message.

The data was already arriving. Both platform handlers serialize a message with the
native SDK's `toJson()`, and both native `InboxMessage` types encode `trackingIds`,
so the key has always been present in the payload crossing the platform channel.
This model simply never read it.

Adds `InboxMessageTrackingIds` covering all seven ids the server publishes
(archive, channel, click, deliver, open, read, unread), reads it in `fromJson`,
writes it in `toJson`, and adds a `clickTrackingId` convenience accessor for the id
`click()` needs.

Independent of the `iwpv=v2` work: the field is read from the root of the message,
which is where both the GraphQL read and the v2 socket publish it, but nothing here
depends on the protocol version or on a native SDK release. This is the one part of
the courier-flutter migration that was never blocked.

Parsing is defensive — `trackingIds` arrives untyped over a platform channel, so a
non-object value yields null rather than throwing.

Tests: 7 new unit tests (all seven ids parsed, clickTrackingId accessor, absent,
partial, non-object input, toJson round-trip, other fields unaffected). First test
directory in this package. `flutter test` 7/7, `flutter analyze` clean.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@linear

linear Bot commented Aug 5, 2026

Copy link
Copy Markdown

C-19804

@mikemilla

Copy link
Copy Markdown
Collaborator Author

Parking this PR during a PR-cleanup pass. The branch is kept (not deleted) and the work is tracked in C-19804 (cycle 367). Reopening restores everything — branch, commits, and this thread.

@mikemilla mikemilla closed this Aug 26, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

1 participant