Skip to content

feat: add statsd and matomo tracking for signup and activation funnel - #13190

Merged
mekarpeles merged 3 commits into
internetarchive:masterfrom
Sadashii:4369/feature/statsd-email-verification
Jul 30, 2026
Merged

feat: add statsd and matomo tracking for signup and activation funnel#13190
mekarpeles merged 3 commits into
internetarchive:masterfrom
Sadashii:4369/feature/statsd-email-verification

Conversation

@Sadashii

@Sadashii Sadashii commented Jul 21, 2026

Copy link
Copy Markdown
Collaborator

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__members in admin/numbers.py counts new /type/user records 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.
  • Sets a short-lived (300s) ol_activation cookie 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 (in openlibrary/templates/account/verify.html): Fires on the "check your email" page load.
  • ActivationSuccess (in openlibrary/templates/site/head.html): Reads the ol_activation cookie, tracks the event, and immediately clears the cookie.

Testing

  • Existing test suite passed.
  • Verified that the cookie-based redirection flow does not interrupt core user session logins.

Stakeholders

@mek

Copilot AI review requested due to automatic review settings July 21, 2026 17:01

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@Sadashii
Sadashii force-pushed the 4369/feature/statsd-email-verification branch from 24b5792 to 6210717 Compare July 21, 2026 17:12
@mekarpeles

Copy link
Copy Markdown
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 Sadashii changed the title feat: add statsd counters for signup funnel (account created + email verified, by device) feat: add statsd and matomo tracking for signup and activation funnel Jul 27, 2026
@Sadashii
Sadashii force-pushed the 4369/feature/statsd-email-verification branch from 6210717 to e0f0cc6 Compare July 27, 2026 09:23
Comment thread openlibrary/plugins/upstream/account.py Outdated
Comment thread openlibrary/plugins/upstream/account.py Outdated
@mekarpeles
mekarpeles merged commit 7ea6b9e into internetarchive:master Jul 30, 2026
3 of 4 checks passed
@mekarpeles mekarpeles mentioned this pull request Aug 2, 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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants