Add trackConversion for sending conversion events#124
Merged
Conversation
Exposes a new public method on ParselyTracker for firing conversion events (newsletter signups, subscriptions, purchases, link clicks, lead capture, and arbitrary custom conversions) using the existing event queue, flush, and mobileproxy pipeline. - New ConversionType enum mirrors the categories accepted by the Parse.ly conversions backend (NEWSLETTER_SIGNUP, LEAD_CAPTURE, LINK_CLICK, SUBSCRIPTION, PURCHASE, CUSTOM). Each case carries the wire-format string the backend expects in `_conversion_type`. - trackConversion(url, conversionType, conversionLabel, ...) merges `_conversion_type` and `_conversion_label` into the event's extra_data alongside caller-supplied keys. Reserved keys cannot be overridden by caller extraData (caller values are applied first, reserved keys last). - The event is dispatched through the existing EventsBuilder / enqueueEvent / FlushQueue / mobileproxy pipeline. No changes to EventsBuilder, the buffer, the flush manager, or the API connection. - Tests: EventsBuilderTest gains "when building conversion event, then build the correct one" covering the conversion event shape (action, idsite, url, merged extra_data, absence of pvid/vsid). ParselyTrackerTest gains a smoke test that the public entry point doesn't throw when called after init. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Adds two buttons on the main screen — "Track Pageview (sandbox)" and
"Track Conversion (sandbox)" — that fire against the
`sandbox.joshhanson.io` apikey on a shared test URL. The pageview lets
a session accrue history before the conversion fires so the conversions
topology has something to attribute to.
NOTE: the example app initializes the SDK with `dryRun=true`, which
suppresses real network sends. To exercise these buttons end-to-end
against mobileproxy, temporarily flip the fourth argument of
`ParselyTracker.init(...)` to `false`.
Used during the manual end-to-end verification of trackConversion on
the Android emulator: with logcat filtered to `Parsely:V`, confirm the
emitted "POST Data {...}" JSON includes `action: "conversion"` and the
`_conversion_type` / `_conversion_label` keys, then watch
dash.parsely.com for the conversion in the conversions report.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The binary-compatibility-validator plugin tracks the SDK's public API surface in parsely.api. Adding ConversionType + trackConversion to the public interface requires regenerating the snapshot via ./gradlew apiDump. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #124 +/- ##
==========================================
+ Coverage 71.32% 73.46% +2.14%
==========================================
Files 22 23 +1
Lines 415 441 +26
Branches 50 52 +2
==========================================
+ Hits 296 324 +28
+ Misses 105 99 -6
- Partials 14 18 +4 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
wzieba
reviewed
May 16, 2026
Collaborator
wzieba
left a comment
There was a problem hiding this comment.
Looks good! Just one suggestion regarding example app and one minor question.
…field Address review feedback (@wzieba): the hardcoded `sandbox.joshhanson.io` constants and "Track ... (sandbox)" buttons read as internal-team noise in a customer-facing example app. Replaced with a generic flow: - Added a `custom_url` EditText alongside the existing `custom_site_id` field. Both default to internal example values when empty (URL falls back to `http://example.com/article1.html`). - The existing "Track URL" button now reads from `custom_url`. - Replaced the two sandbox-specific buttons with a single generic "Track Conversion" button that uses the same URL + site ID fields, hardcodes type `SUBSCRIPTION` + label `demo_conversion` to keep the API surface visible in the example code. Internal testing against the sandbox apikey still works the same way: just type `sandbox.joshhanson.io` into the site ID field and the sandbox URL into the URL field before tapping the buttons. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
wzieba
approved these changes
May 19, 2026
Collaborator
wzieba
left a comment
There was a problem hiding this comment.
Thanks @randyriback, LGTM 👍
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.
Summary
ParselyTracker.trackConversion(url, conversionType, conversionLabel, ...)for firing conversion events (newsletter signups, subscriptions, purchases, link clicks, lead capture, custom). Internally constructs an event withaction="conversion"and merges_conversion_typeand_conversion_labelintoextra_data, which the Parse.ly conversions backend (conversions-realtime) extracts and uses as the goal identity.ConversionTypeenum mirrors the categories accepted server-side (newsletter_signup,lead_capture,link_click,subscription,purchase,custom).EventsBuilder/InMemoryBuffer/FlushQueue/ParselyAPIConnectionpipeline — zero changes to the network layer, the buffer, or the flush manager.This is the Android counterpart to the iOS SDK's
trackConversion(parallel PR on AnalyticsSDK-iOS).Test plan
Unit tests (all passing)
EventsBuilderTest.when building conversion event, then build the correct one— verifies the built event hasaction == "conversion", the righturlandidsite, nopvid/vsid, and that_conversion_type/_conversion_labelplus caller-supplied keys land indata.ParselyTrackerTest.given tracker initialized, when calling trackConversion, do not throw any exception— smoke test for the public entry point (mirrors the existing call-doesn't-throw tests for other tracking methods).Full suite (
./gradlew :parsely:testDebugUnitTest): EventsBuilderTest 11 tests / ParselyTrackerTest 5 tests / 0 failures.Manual end-to-end (Android emulator: Pixel 5, android-34, default arm64-v8a)
dryRuntofalsetemporarily inMainActivity.javato exercise the real network path.sandbox.joshhanson.ioapikey.adb logcat Parsely:V '*:S':{ "action": "conversion", "url": "https://sandbox.joshhanson.io/path/test-conversion2", "idsite": "sandbox.joshhanson.io", "data": { "_conversion_type": "subscription", "_conversion_label": "android_sdk_smoke_test", "plan": "weekly", "source": "android_demo_app", "os": "android", "os_version": "34", "parsely_site_uuid": "...", "ts": 1778782087996 } }Testing Screenshots