Module: Controllers::AnalyticsEvents
- Extended by:
- ActiveSupport::Concern
- Included in:
- ApplicationController
- Defined in:
- app/concerns/controllers/analytics_events.rb
Overview
Server-side analytics event tracking that bridges to client-side Analytics.js
This concern allows controllers to queue analytics events that will be
fired client-side on the next page load (including after redirects).
Events are stored in session[SESSION_KEY] and delivered via the
globals.json response. The client-side primeval.js handler fires them
through the Analytics service.
Why session and not flash?
We previously stored events in flash[:analytics_events]. flash is meant
for short user-facing strings and is auto-rendered by toast/flash partials,
so structured analytics payloads (Arrays of Hashes) crashed those
partials and could be silently dropped if the user made a non-globals.json
request between the redirect and the next page load. Session storage is
durable across multiple intermediate requests and is consumed (drained)
exactly once by GlobalsController#show.
Supported Events:
ALL VENDORS (GA4, Google Ads, Facebook, Bing):
- 'Cart - Product Added'
- 'Cart - Order Completed'
- 'Lead - Form Submitted'
- 'Instant Quote - Completed FH'
- 'Instant Quote - Completed SM'
GA4 ONLY (funnel analysis):
- 'Cart - Viewed'
- 'Cart - Customer Info Entered'
- 'Cart - Shipping Info Added'
- 'Cart - Payment Info Entered'
- 'My Account - Quote Viewed'
Usage:
In controller action:
track_event('Cart - Product Added', { quoteId: @room.id, value: @room.total })
redirect_to cart_path
See: doc/features/ANALYTICS_TRACKING_EVENTS.MD for full documentation
Constant Summary collapse
- SESSION_KEY =
'queued_analytics_events'- MAX_QUEUED_EVENTS =
Hard cap to keep the session cookie small if a controller misbehaves and
never triggers a globals.json drain (e.g. headless bot traffic). 25
Instance Method Summary collapse
-
#consume_queued_analytics_events ⇒ Array<Hash>
protected
Pop and clear all queued events.
-
#track_event(event_name, properties = {}) ⇒ Object
protected
Queue an analytics event to be fired client-side via globals.json.
Instance Method Details
#consume_queued_analytics_events ⇒ Array<Hash> (protected)
Pop and clear all queued events. Intended for GlobalsController#show.
78 79 80 81 |
# File 'app/concerns/controllers/analytics_events.rb', line 78 def consume_queued_analytics_events events = session.delete(SESSION_KEY) events.presence end |
#track_event(event_name, properties = {}) ⇒ Object (protected)
Queue an analytics event to be fired client-side via globals.json
55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 |
# File 'app/concerns/controllers/analytics_events.rb', line 55 def track_event(event_name, properties = {}) # Drop server-queued conversion events when an employee is masquerading as # a customer ("Login as this user"). Every track_event call (orders, # leads, instant quotes) flows through here, so this single guard blocks # GA4/Google Ads/FB/Bing pushes at the source. Client-side Analytics.js # has its own short-circuit via the heatwave:masquerade meta tag, but we # don't even queue the event so the customer's Analytics history stays # untouched. if respond_to?(:account_impersonated?) && account_impersonated? Rails.logger.info "[track_event] skip '#{event_name}' because masquerade session active" return end queue = session[SESSION_KEY] || [] queue << { 'event' => event_name, 'properties' => properties.deep_stringify_keys } session[SESSION_KEY] = queue.last(MAX_QUEUED_EVENTS) end |