Module: TrackRelay

Defined in:
lib/track_relay.rb,
lib/track_relay/errors.rb,
lib/track_relay/linter.rb,
lib/track_relay/catalog.rb,
lib/track_relay/current.rb,
lib/track_relay/railtie.rb,
lib/track_relay/testing.rb,
lib/track_relay/version.rb,
lib/track_relay/manifest.rb,
lib/track_relay/dispatcher.rb,
lib/track_relay/client_id/ga.rb,
lib/track_relay/delivery_job.rb,
lib/track_relay/instrumenter.rb,
lib/track_relay/job_tracking.rb,
lib/track_relay/configuration.rb,
lib/track_relay/event_payload.rb,
lib/track_relay/testing/helpers.rb,
lib/track_relay/event_definition.rb,
lib/track_relay/subscribers/ahoy.rb,
lib/track_relay/subscribers/base.rb,
lib/track_relay/subscribers/test.rb,
lib/track_relay/client_id/session.rb,
lib/track_relay/dsl/event_builder.rb,
lib/track_relay/dsl/param_builder.rb,
lib/track_relay/subscribers/logger.rb,
lib/track_relay/controller_tracking.rb,
lib/track_relay/client_id/ahoy_visitor.rb,
lib/track_relay/validators/ga4_constraints.rb,
lib/track_relay/testing/minitest_assertions.rb,
lib/track_relay/validators/catalog_validator.rb,
lib/generators/track_relay/event/event_generator.rb,
lib/generators/track_relay/install/install_generator.rb,
lib/track_relay/subscribers/ga4_measurement_protocol.rb,
lib/generators/track_relay/subscriber/subscriber_generator.rb

Defined Under Namespace

Modules: Catalog, ClientId, ControllerTracking, DSL, Dispatcher, Generators, Instrumenter, JobTracking, Manifest, Subscribers, Testing, Validators Classes: CatalogError, Configuration, Current, DeliveryDiscardableError, DeliveryJob, DeliveryRetriableError, Error, EventDefinition, EventPayload, Ga4ConstraintError, Linter, Railtie, ReservedKeyError, UnknownEventError, ValidationError

Constant Summary collapse

RESERVED_KEYS =

Param keys that cannot appear in a catalog event because they collide with the runtime context that track_relay injects automatically (TrackRelay::Current + reserved-key extraction in ‘track`).

If a catalog event declares any of these as params, the catalog validator raises ReservedKeyError at load time so the conflict surfaces during boot rather than at track time.

%i[user visitor_token client_id request].freeze
GA4_RESERVED_NAMES =

Event names Google Analytics 4 reserves for its own use. Custom events in the catalog must not use any of these names — GA4 silently drops them on ingestion. Source: support.google.com/analytics/answer/9234069

Kept here as a frozen Array of Strings so GA4_RESERVED_NAMES.include? works against both String and Symbol input via to_s coercion in the validator.

%w[
  ad_click
  ad_exposure
  ad_query
  ad_reward
  adunit_exposure
  app_clear_data
  app_exception
  app_install
  app_remove
  app_store_refund
  app_store_subscription_cancel
  app_store_subscription_convert
  app_store_subscription_renew
  app_update
  click
  error
  file_download
  first_open
  first_visit
  form_start
  form_submit
  in_app_purchase
  notification_dismiss
  notification_foreground
  notification_open
  notification_receive
  os_update
  page_view
  screen_view
  scroll
  session_start
  session_start_with_rollout
  session_resume_with_rollout
  user_engagement
  video_complete
  video_progress
  video_start
  view_search_results
].freeze
VERSION =
"1.0.0"

Class Method Summary collapse

Class Method Details

.catalog(&block) ⇒ Object

Top-level entry point for the catalog DSL.

Evaluates ‘block` against a TrackRelay::DSL::EventBuilder so callers can use `event :name do … end` and `user_property :name, :type` directly:

TrackRelay.catalog do
  event :article_viewed do
    integer :article_id, required: true
  end

  user_property :plan, :string
end

Each ‘event` declaration validates against GA4 + reserved-key rules and registers the resulting EventDefinition in Catalog before returning. Failures raise Ga4ConstraintError, ReservedKeyError, or CatalogError depending on the violation.



200
201
202
# File 'lib/track_relay.rb', line 200

def self.catalog(&block)
  DSL::EventBuilder.new.instance_exec(&block)
end

.configConfiguration

Process-wide Configuration singleton. Lazily instantiated on first access. Reset between tests via reset_config!.

Returns:



98
99
100
# File 'lib/track_relay.rb', line 98

def config
  @config ||= Configuration.new
end

.configure {|config| ... } ⇒ Configuration

Yield the Configuration singleton for host-app setup, then return it so callers can chain.

TrackRelay.configure do |c|
  c.subscribe(MySubscriber.new)
  c.untyped_events_allowed = false
end

Yield Parameters:

Returns:



112
113
114
115
# File 'lib/track_relay.rb', line 112

def configure
  yield(config)
  config
end

.identify(user, **user_properties) ⇒ void

This method returns an undefined value.

Identify a user — Phase 01 thin pass-through.

See TrackRelay::Instrumenter.identify.

Parameters:

  • user (Object)
  • user_properties (Hash)


150
151
152
# File 'lib/track_relay.rb', line 150

def self.identify(user, **user_properties)
  Instrumenter.identify(user, **user_properties)
end

.reset_config!Configuration

Replace the singleton with a fresh Configuration. Used by the test suite’s teardown hook so per-test mutations do not leak.

Returns:



121
122
123
# File 'lib/track_relay.rb', line 121

def reset_config!
  @config = Configuration.new
end

.subscribe(subscriber_or_class, only: nil, except: nil) ⇒ Subscribers::Base

Register a subscriber with optional per-instance event-name filters.

TrackRelay.subscribe(MySubscriber)
TrackRelay.subscribe(MySubscriber, only: %i[purchase sign_up])
TrackRelay.subscribe(MySubscriber, except: %i[page_view])
TrackRelay.subscribe(MySubscriber.new, only: %i[purchase])

Accepts either a subscriber class (instantiated via ‘.new`) or a pre-built instance. When `only:` or `except:` is non-nil, the value is coerced to `Set<Symbol>` and stored as a SINGLETON-CLASS override on the registered instance. Other instances of the same class — and the class-level defaults declared via `filter only:` / `filter except:` — are NOT mutated.

The instance is appended to TrackRelay::Configuration#subscribers via TrackRelay::Configuration#subscribe and returned, so callers can hold a reference (e.g. for tests).

Parameters:

  • subscriber_or_class (Class, Subscribers::Base)
  • only (Array<Symbol, String>, nil) (defaults to: nil)

    allow-list override

  • except (Array<Symbol, String>, nil) (defaults to: nil)

    deny-list override

Returns:



176
177
178
179
180
181
# File 'lib/track_relay.rb', line 176

def self.subscribe(subscriber_or_class, only: nil, except: nil)
  instance = subscriber_or_class.is_a?(Class) ? subscriber_or_class.new : subscriber_or_class
  instance.set_filter_overrides!(only: only, except: except)
  config.subscribe(instance)
  instance
end

.test_mode!Subscribers::Test

Convenience delegate to TrackRelay::Testing.test_mode!.

Returns:



66
67
68
# File 'lib/track_relay/testing.rb', line 66

def test_mode!
  Testing.test_mode!
end

.test_mode_off!void

This method returns an undefined value.

Convenience delegate to TrackRelay::Testing.test_mode_off!.



73
74
75
# File 'lib/track_relay/testing.rb', line 73

def test_mode_off!
  Testing.test_mode_off!
end

.test_subscriberSubscribers::Test?

Convenience delegate to TrackRelay::Testing.test_subscriber.

Returns:



80
81
82
# File 'lib/track_relay/testing.rb', line 80

def test_subscriber
  Testing.test_subscriber
end

.track(name, **params) ⇒ void

This method returns an undefined value.

Track an event — typed (catalog-defined) or untyped.

Reserved keys (‘:user`, `:request`, `:client_id`, `:visitor_token`) are partitioned out of `params` BEFORE catalog lookup so they never appear in `payload.params`. `:user`/`:request`/`:client_id` are bound on Current for the duration of the call; `:visitor_token` is merged directly into `payload.context`.

See TrackRelay::Instrumenter.track for full semantics.

Parameters:

  • name (Symbol)
  • params (Hash)


139
140
141
# File 'lib/track_relay.rb', line 139

def self.track(name, **params)
  Instrumenter.track(name, **params)
end