Track marketing notification opens - #6067
Conversation
b4eafc8 to
5d8b895
Compare
f149ce7 to
b8a1392
Compare
b8a1392 to
ff38b7b
Compare
ff38b7b to
83177c4
Compare
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.
There are 2 total unresolved issues (including 1 from previous review).
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 83177c4. Configure here.
83177c4 to
1cdb570
Compare
a30df05 to
c14a73a
Compare
| | 'Fio_Handle_Bundled_Tx' | ||
| | 'Load_Install_Reason_Match' | ||
| | 'Load_Install_Reason_Fail' | ||
| | 'Marketing_Notification_Opened' |
There was a problem hiding this comment.
Genericize to Push_Notification_Opened
There was a problem hiding this comment.
Done in 9553f1f — renamed to Push_Notification_Opened. Agreed on the reasoning: the event describes a push being opened, so price-change or any future push type can report through the same one instead of accruing an event per category. campaignId stays an optional param since only marketing pushes carry one.
c14a73a to
e4a6665
Compare
There was a problem hiding this comment.
Claude Code Review
Claude Code Review is paused for this repository. To reconnect it, an admin of this repository's GitHub organization (or the account owner, for personal repositories) who can also manage your Claude organization's Code Review settings needs to re-link GitHub in Code Review settings. This is a one-time step.
Tip: disable this comment in your organization's Code Review settings.
The push server attaches a campaignId (and an optional deep link URL) to every marketing notification. Parse that payload when the user opens the app from one: report the campaign to analytics, and navigate to the URL. A campaign link goes wherever its URL points, the same as a link tapped in a browser or a message. Both reach the app through `parseDeepLink` and the same handler, so a campaign can send users anywhere the app already goes - including both the new and legacy fiat ramp spellings - without a list here to keep in step with the rest of the app. A URL the parser does not recognize tracks the open without navigating. Sends are gated behind a marketer API key that is not shipped in the apps, so a campaign URL is not reachable by an outsider.
e4a6665 to
9553f1f
Compare

CHANGELOG
Does this branch warrant an entry to the CHANGELOG?
Dependencies
none
Requirements
If you have made any visual changes to the GUI. Make sure you have:
No visual changes — this is push-payload parsing plus navigation/analytics, no new UI.
Description
Recognizes a marketing push notification and, when the user opens the app from it, reports the campaign open to analytics and navigates to an optional deep link.
parsePushMessagenow recognizes a{ type: 'marketing', campaignId, url? }FCMdatapayload and returns a newMarketingLinkdeep-link type. An unrecognized or malformedurldegrades to track-only.Marketing_Notification_OpenedPostHog event carrying thecampaignId, then navigates to the optional deep link through the existing handler.PushMessageParserunit test.Verified with the unit test and end-to-end on a real Android device against a local push server: the open was tracked in PostHog and the deep link navigated.
The sending side lives in edge-push-server (companion PR EdgeApp/edge-push-server#78). This PR is the receiving side and is safe to merge on its own — it only acts on notifications that carry the marketing payload.
Note
Medium Risk
Push URLs can drive navigation for all campaign recipients; the allow-list mitigates operator error or compromised send keys, but expanding destinations or parser gaps could still route users to sensitive flows.
Overview
Marketing push notifications (
type: marketingwithcampaignIdand optionalurl) are now recognized when the user opens the app from the notification.parsePushMessagereturns a newMarketingLinkdeep-link type. Optional URLs are parsed through the existing deep-link parser; only allow-listed campaign destinations (home, wallets, earn, markets, swap, buy/sell quotes, promotions, fund-account modal) trigger navigation—sensitive or unlisted targets (recovery, edge-login, arbitrary scenes, provider returns) are track-only. Wrappeddeep.edge.appURLs are judged by their inner destination; malformed URLs still record the open.On handle,
DeepLinkingActionslogsMarketing_Notification_Openedto analytics withcampaignId, then navigates via the shared link handler when a permitted link was parsed.PushMessageParser.test.tscovers destinations, refusals, attribution wrappers, and existing price-change payloads.Reviewed by Cursor Bugbot for commit 1cdb570. Bugbot is set up for automated code reviews on this repo. Configure here.