feat: add statsd and matomo tracking for signup and activation funnel - #13190
Merged
mekarpeles merged 3 commits intoJul 30, 2026
Merged
Conversation
Sadashii
force-pushed
the
4369/feature/statsd-email-verification
branch
from
July 21, 2026 17:12
24b5792 to
6210717
Compare
Member
|
As noted in our 1:1 conversation, statsd + devices might be challenging It might make more sense to use matomo (which already has device type) The question becomes much simpler; how can we trigger a matomo event on the page or redirect triggered by the activate endpoint |
This commit adds observability to measure signup to email verification funnel rates:
1. Statsd counters (ol.account.created, ol.account.verify.success, and ol.account.verify.fail)
to track raw signup events, activation success events, and activation failures.
2. Matomo trackEvent ('Account', 'RegistrationSuccess') and ('Account', 'ActivationSuccess')
pushed via JavaScript so Matomo can capture device types natively from the User-Agent.
Sadashii
force-pushed
the
4369/feature/statsd-email-verification
branch
from
July 27, 2026 09:23
6210717 to
e0f0cc6
Compare
mekarpeles
reviewed
Jul 30, 2026
mekarpeles
reviewed
Jul 30, 2026
mekarpeles
added a commit
that referenced
this pull request
Aug 5, 2026
…the resumed path PreserveIntent|Continue was the only data-ol-link-track attribute in the codebase applied via JS (setAttribute at DOMContentLoaded) rather than server-rendered; the other 59 template files emit it statically. Matomo ingests these through a tag-manager trigger that does not see attributes added after the document is parsed, so the click reached Athena but never Matomo — roughly 10 events/day against ~3,500 daily registrations. Emitting the attribute from get_pending_action_banner() puts it in the original DOM and makes the DOMContentLoaded setAttribute redundant; the cookie-clearing listener stays. Adds the two events needed to make the funnel legible, both in Matomo so they stay segmentable by device type and patron cohort: PreserveIntent | BannerShown impressions, pushed when the banner renders PreserveIntent | ResumedViaRedirect the silent success path ResumedViaRedirect is the one nothing could previously observe: when the redirect is usable the cookie is cleared and the patron goes straight to their action, so no banner renders and there is no element for a click event. Login sets a short-lived ol_pi_resumed cookie which site/head.html converts into a Matomo event and clears — the same one-shot pattern ol_activation uses for ActivationSuccess (#13190). It fires once and does not refire on subsequent pageviews. Impressions and clicks both come from Matomo, so the click-through rate holds even though the absolute counts undercount via ad-blockers and Do-Not-Track. ref #13261
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.
Closes #
This PR adds statsd counters and Matomo event tracking to measure the signup-to-verification funnel — i.e. what percentage of users who create an account actually complete email verification, along with device classification.
Background / Hunch:
Currently there is no way to compute a signup funnel rate in Grafana.
admin_range__membersinadmin/numbers.pycounts new/type/userrecords daily, but a user record is only created after successful verification and first login — so it's already post-dropoff. There's no counter for attempted signups.The hypothesis being investigated: when a user signs up on one device but hasn't logged into their email on that device, clicking the verification link either opens a new browser session with no context, or forces an app switch. This cross-device friction likely causes a meaningful portion of signups to bounce before verifying. Tracking mobile vs desktop at both the signup and verification steps will let us quantify this before deciding whether to invest in an OTP-based alternative (which would let users type a short code instead of clicking a link).
Proposed Changes
1. Statsd Funnel & Ops Counters (Backend)
Added to
openlibrary/plugins/upstream/account.py:ol.account.created: Incremented upon successful submission of the registration form.ol.account.verify.success: Incremented when the email verification link is successfully clicked and the account is activated.ol.account.verify.fail: Incremented if the verification link fails (invalid or expired token) for outage and TTL failure detection.300s)ol_activationcookie upon successful verification to communicate activation status to the frontend.2. Matomo Event Tracking (Frontend)
Added to layout/templates to capture device analytics natively within Matomo (e.g. mobile vs desktop via User-Agent):
RegistrationSuccess(inopenlibrary/templates/account/verify.html): Fires on the "check your email" page load.ActivationSuccess(inopenlibrary/templates/site/head.html): Reads theol_activationcookie, tracks the event, and immediately clears the cookie.Testing
Stakeholders
@mek