Class: SnowplowTracker::Tracker
- Inherits:
-
Object
- Object
- SnowplowTracker::Tracker
- Defined in:
- lib/snowplow-tracker/tracker.rb
Overview
Allows the tracking of events. The tracker accepts event properties to its
various track_x_event
methods, and creates an appropriate event payload.
This payload is passed to one or more Emitters for sending to the event
collector.
A Tracker is always associated with one Subject, and one or more Emitter. The Subject object stores information about the user, and will be generated automatically if one is not provided during initialization. It can be swapped out for another Subject using #set_subject.
Tracker objects can access the methods of their associated Subject, e.g. #set_user_id.
The Emitter, or an array of Emitters, must be given during initialization. They will send the prepared events to the event collector. It's possible to add further Emitters to an existing Tracker, using #add_emitter. However, Emitters cannot be removed from Trackers.
At initialization, two Tracker parameters can be set which will be added to
all events. The first is the Tracker namespace. This is especially useful to
distinguish between events from different Trackers, if more than one is
being used. The namespace value will be sent as the tna
field in the raw
event, mapping to name_tracker
in the processed event.
The second user-set Tracker property is the app ID (aid
; app_id
). This
is the unique identifier for the site or application, and is particularly
useful for distinguishing between events when Snowplow tracking has been
implemented in multiple apps.
The final initialization parameter is a setting for the base64-encoding of any JSONs in the event payload. These will be the SelfDescribingJsons used to provide context to events, or in the #track_self_describing_event method. The default is for JSONs to be encoded. Once the Tracker has been instantiated, it is not possible to change this setting.
Tracking events
The Tracker #track_x_event
methods all work similarly. An event payload is
created containing the relevant properties, which is passed to an Emitter
for sending. All payloads have a unique event ID (event_id
) added to them
(a type-4 UUID created using the SecureRandom module). This is sent as the
eid
field in the raw event.
The Ruby tracker provides the ability to track multiple types of events
out-of-the-box. The #track_x_event
methods range from single purpose
methods, such as #track_page_view, to the more complex but flexible
#track_self_describing_event, which can be used to track any kind of
event. We strongly recommend using #track_self_describing_event for your
tracking, as it allows you to design custom event types to match your
business requirements.
This table gives the event type in the raw and processed events, defined in
the Snowplow Tracker Protocol. This is the e
or event
parameter. Note
that #track_screen_view calls #track_self_describing_event behind the
scenes, resulting in a ue
event type.
Tracker method | e (raw) |
event (processed) |
---|---|---|
#track_self_describing_event | ue |
unstruct |
#track_struct_event | se |
struct |
#track_page_view | pv |
page_view |
#track_ecommerce_transaction | tr and ti |
transaction and transaction_item |
#track_screen_view | ue |
unstruct |
The name ue
, "unstructured event", is partially depreciated. This event
type was originally created as a counterpart to "structured event", but the
name is misleading. An unstruct
event requires a schema ruleset and
therefore can be considered more structured than a struct
event. We prefer
the name "self-describing event", after the SelfDescribingJson schema.
Changing the event name in the Tracker Protocol would be a breaking change,
so for now the self-describing events are still sent as "unstruct".
All the #track_x_event
methods share common features and parameters. Every
type of event can have an optional context, Subject, and Page added. A
Timestamp can also be provided for all event types to override the default
event timestamp.
Event context can be provided as an array of SelfDescribingJson. Each element of the array is called an entity. Contextual entities can be used to describe the setting in which the event occurred. For example, a "user" entity could be created and attached to all events from each user. For a search event, entities could be attached for each of the search results. The Ruby tracker does not automatically add any event context. This is in contrast to the Snowplow JavaScript Tracker, which automatically attaches a "webpage" entity to every event that it tracks, containing a unique ID for that loaded page.
Public constants collapse
- DEFAULT_ENCODE_BASE64 =
SelfDescribingJson objects are sent encoded by default
true
Instance Method Summary collapse
-
#add_emitter(emitter) ⇒ Object
Add a new Emitter to the internal array of Tracker-associated Emitters.
-
#flush(async: false) ⇒ Object
Manually flush all events stored in all Tracker-associated Emitters.
-
#initialize(emitters:, subject: nil, namespace: nil, app_id: nil, encode_base64: DEFAULT_ENCODE_BASE64) ⇒ Tracker
constructor
Create a new Tracker.
-
#set_color_depth(depth) ⇒ Object
call Subject#set_color_depth.
- #set_domain_session_id(sid) ⇒ Object
- #set_domain_session_idx(vid) ⇒ Object
- #set_domain_user_id(duid) ⇒ Object
-
#set_fingerprint(fingerprint) ⇒ Object
call Subject#set_fingerprint.
-
#set_ip_address(ip) ⇒ Object
call Subject#set_ip_address.
-
#set_lang(lang) ⇒ Object
call Subject#set_lang.
- #set_network_user_id(nuid) ⇒ Object
-
#set_platform(platform) ⇒ Object
call Subject#set_platform.
- #set_screen_resolution(width: , height: ) ⇒ Object
-
#set_subject(subject) ⇒ Object
Replace the existing Tracker-associated Subject with the provided one.
-
#set_timezone(timezone) ⇒ Object
call Subject#set_timezone.
-
#set_user_id(user_id) ⇒ Object
call Subject#set_user_id.
-
#set_useragent(useragent) ⇒ Object
call Subject#set_useragent.
-
#set_viewport(width: , height: ) ⇒ Object
call Subject#set_viewport.
-
#track_ecommerce_transaction(transaction:, items:, context: nil, tstamp: nil, subject: nil, page: nil) ⇒ Object
Track an eCommerce transaction, and all the items in it.
-
#track_page_view(page_url:, page_title: nil, referrer: nil, context: nil, tstamp: nil, subject: nil, page: nil) ⇒ Object
Track a visit to a page.
-
#track_screen_view(name: nil, id: nil, context: nil, tstamp: nil, subject: nil, page: nil) ⇒ Object
Track a screen view event.
-
#track_self_describing_event(event_json:, context: nil, tstamp: nil, subject: nil, page: nil) ⇒ Object
Track a self-describing event.
-
#track_struct_event(category:, action:, label: nil, property: nil, value: nil, context: nil, tstamp: nil, subject: nil, page: nil) ⇒ Object
Track a structured event.
-
#track_unstruct_event(event_json:, context: nil, tstamp: nil, subject: nil, page: nil) ⇒ Object
deprecated
Deprecated.
Use #track_self_describing_event instead.
Constructor Details
#initialize(emitters:, subject: nil, namespace: nil, app_id: nil, encode_base64: DEFAULT_ENCODE_BASE64) ⇒ Tracker
All the Tracker instance methods return the Tracker object, allowing
method chaining, e.g.
SnowplowTracker::Tracker.new.set_user_id('12345').track_page_view(page_url: 'www.example.com
Create a new Tracker. emitters
is the only strictly required parameter.
168 169 170 171 172 173 174 175 176 177 178 179 180 181 |
# File 'lib/snowplow-tracker/tracker.rb', line 168 def initialize(emitters:, subject: nil, namespace: nil, app_id: nil, encode_base64: DEFAULT_ENCODE_BASE64) @emitters = Array(emitters) @subject = if subject.nil? Subject.new else subject end @settings = { 'tna' => namespace, 'tv' => TRACKER_VERSION, 'aid' => app_id } @encode_base64 = encode_base64 end |
Instance Method Details
#add_emitter(emitter) ⇒ Object
Add a new Emitter to the internal array of Tracker-associated Emitters.
626 627 628 629 |
# File 'lib/snowplow-tracker/tracker.rb', line 626 def add_emitter(emitter) @emitters.push(emitter) self end |
#flush(async: false) ⇒ Object
Manually flush all events stored in all Tracker-associated Emitters. By default, this happens synchronously. Emitters can only send events synchronously, while AsyncEmitters can send either synchronously or asynchronously.
601 602 603 604 605 606 607 |
# File 'lib/snowplow-tracker/tracker.rb', line 601 def flush(async: false) @emitters.each do |emitter| emitter.flush(async) end self end |
#set_color_depth(depth) ⇒ Object
211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 |
# File 'lib/snowplow-tracker/tracker.rb', line 211 Subject.instance_methods(false).each do |name| if RUBY_VERSION >= '3.0.0' define_method name, ->(*args, **kwargs) do @subject.method(name.to_sym).call(*args, **kwargs) self end else define_method name, ->(*args) do @subject.method(name.to_sym).call(*args) self end end end |
#set_domain_session_id(sid) ⇒ Object
211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 |
# File 'lib/snowplow-tracker/tracker.rb', line 211 Subject.instance_methods(false).each do |name| if RUBY_VERSION >= '3.0.0' define_method name, ->(*args, **kwargs) do @subject.method(name.to_sym).call(*args, **kwargs) self end else define_method name, ->(*args) do @subject.method(name.to_sym).call(*args) self end end end |
#set_domain_session_idx(vid) ⇒ Object
211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 |
# File 'lib/snowplow-tracker/tracker.rb', line 211 Subject.instance_methods(false).each do |name| if RUBY_VERSION >= '3.0.0' define_method name, ->(*args, **kwargs) do @subject.method(name.to_sym).call(*args, **kwargs) self end else define_method name, ->(*args) do @subject.method(name.to_sym).call(*args) self end end end |
#set_domain_user_id(duid) ⇒ Object
211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 |
# File 'lib/snowplow-tracker/tracker.rb', line 211 Subject.instance_methods(false).each do |name| if RUBY_VERSION >= '3.0.0' define_method name, ->(*args, **kwargs) do @subject.method(name.to_sym).call(*args, **kwargs) self end else define_method name, ->(*args) do @subject.method(name.to_sym).call(*args) self end end end |
#set_fingerprint(fingerprint) ⇒ Object
211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 |
# File 'lib/snowplow-tracker/tracker.rb', line 211 Subject.instance_methods(false).each do |name| if RUBY_VERSION >= '3.0.0' define_method name, ->(*args, **kwargs) do @subject.method(name.to_sym).call(*args, **kwargs) self end else define_method name, ->(*args) do @subject.method(name.to_sym).call(*args) self end end end |
#set_ip_address(ip) ⇒ Object
211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 |
# File 'lib/snowplow-tracker/tracker.rb', line 211 Subject.instance_methods(false).each do |name| if RUBY_VERSION >= '3.0.0' define_method name, ->(*args, **kwargs) do @subject.method(name.to_sym).call(*args, **kwargs) self end else define_method name, ->(*args) do @subject.method(name.to_sym).call(*args) self end end end |
#set_lang(lang) ⇒ Object
call Subject#set_lang
211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 |
# File 'lib/snowplow-tracker/tracker.rb', line 211 Subject.instance_methods(false).each do |name| if RUBY_VERSION >= '3.0.0' define_method name, ->(*args, **kwargs) do @subject.method(name.to_sym).call(*args, **kwargs) self end else define_method name, ->(*args) do @subject.method(name.to_sym).call(*args) self end end end |
#set_network_user_id(nuid) ⇒ Object
211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 |
# File 'lib/snowplow-tracker/tracker.rb', line 211 Subject.instance_methods(false).each do |name| if RUBY_VERSION >= '3.0.0' define_method name, ->(*args, **kwargs) do @subject.method(name.to_sym).call(*args, **kwargs) self end else define_method name, ->(*args) do @subject.method(name.to_sym).call(*args) self end end end |
#set_platform(platform) ⇒ Object
call Subject#set_platform
211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 |
# File 'lib/snowplow-tracker/tracker.rb', line 211 Subject.instance_methods(false).each do |name| if RUBY_VERSION >= '3.0.0' define_method name, ->(*args, **kwargs) do @subject.method(name.to_sym).call(*args, **kwargs) self end else define_method name, ->(*args) do @subject.method(name.to_sym).call(*args) self end end end |
#set_screen_resolution(width: , height: ) ⇒ Object
211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 |
# File 'lib/snowplow-tracker/tracker.rb', line 211 Subject.instance_methods(false).each do |name| if RUBY_VERSION >= '3.0.0' define_method name, ->(*args, **kwargs) do @subject.method(name.to_sym).call(*args, **kwargs) self end else define_method name, ->(*args) do @subject.method(name.to_sym).call(*args) self end end end |
#set_subject(subject) ⇒ Object
Replace the existing Tracker-associated Subject with the provided one. All subsequent events will have the properties of the new Subject, unless they are overriden by event-specific Subject parameters.
616 617 618 619 |
# File 'lib/snowplow-tracker/tracker.rb', line 616 def set_subject(subject) @subject = subject self end |
#set_timezone(timezone) ⇒ Object
call Subject#set_timezone
211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 |
# File 'lib/snowplow-tracker/tracker.rb', line 211 Subject.instance_methods(false).each do |name| if RUBY_VERSION >= '3.0.0' define_method name, ->(*args, **kwargs) do @subject.method(name.to_sym).call(*args, **kwargs) self end else define_method name, ->(*args) do @subject.method(name.to_sym).call(*args) self end end end |
#set_user_id(user_id) ⇒ Object
call Subject#set_user_id
211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 |
# File 'lib/snowplow-tracker/tracker.rb', line 211 Subject.instance_methods(false).each do |name| if RUBY_VERSION >= '3.0.0' define_method name, ->(*args, **kwargs) do @subject.method(name.to_sym).call(*args, **kwargs) self end else define_method name, ->(*args) do @subject.method(name.to_sym).call(*args) self end end end |
#set_useragent(useragent) ⇒ Object
211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 |
# File 'lib/snowplow-tracker/tracker.rb', line 211 Subject.instance_methods(false).each do |name| if RUBY_VERSION >= '3.0.0' define_method name, ->(*args, **kwargs) do @subject.method(name.to_sym).call(*args, **kwargs) self end else define_method name, ->(*args) do @subject.method(name.to_sym).call(*args) self end end end |
#set_viewport(width: , height: ) ⇒ Object
call Subject#set_viewport
211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 |
# File 'lib/snowplow-tracker/tracker.rb', line 211 Subject.instance_methods(false).each do |name| if RUBY_VERSION >= '3.0.0' define_method name, ->(*args, **kwargs) do @subject.method(name.to_sym).call(*args, **kwargs) self end else define_method name, ->(*args) do @subject.method(name.to_sym).call(*args) self end end end |
#track_ecommerce_transaction(transaction:, items:, context: nil, tstamp: nil, subject: nil, page: nil) ⇒ Object
Track an eCommerce transaction, and all the items in it.
This method is unique in sending multiple events: one transaction
event,
and one transaction_item
event for each item. If Subject or Page objects
are provided, their parameters will be merged into both transaction
and
transaction_item
events. The timestamp and event ID of the
transaction_item
events will always be the same as the transaction
.
Transaction items are also automatically populated with the order_id
and
currency
fields from the transaction.
Event context is handled differently for transaction
and
transaction_item
events. A context array argument provided to this
method will be attached to the transaction
event only. To attach a
context array to a transaction item, use the key "context" in the item
hash.
The transaction and item hash arguments must contain the correct keys, as shown in the tables below.
Transaction fields | Description | Required? | Type |
---|---|---|---|
order_id | ID of the eCommerce transaction | Yes | String |
total_value | Total transaction value | Yes | Num |
affiliation | Transaction affiliation | No | String |
tax_value | Transaction tax value | No | Num |
shipping | Delivery cost charged | No | Num |
city | Delivery address city | No | String |
state | Delivery address state | No | String |
country | Delivery address country | No | String |
currency | Transaction currency | No | String |
Item fields | Description | Required? | Type |
---|---|---|---|
sku | Item SKU | Yes | String |
price | Item price | Yes | Num |
quantity | Item quantity | Yes | Integer |
name | Item name | No | String |
category | Item category | No | String |
context | Item event context | No | Array[SelfDescribingJson] |
392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 |
# File 'lib/snowplow-tracker/tracker.rb', line 392 def track_ecommerce_transaction(transaction:, items:, context: nil, tstamp: nil, subject: nil, page: nil) tstamp = process_tstamp(tstamp) transform_keys(transaction) payload = Payload.new payload.add('e', 'tr') payload.add('tr_id', transaction['order_id']) payload.add('tr_tt', transaction['total_value']) payload.add('tr_af', transaction['affiliation']) payload.add('tr_tx', transaction['tax_value']) payload.add('tr_sh', transaction['shipping']) payload.add('tr_ci', transaction['city']) payload.add('tr_st', transaction['state']) payload.add('tr_co', transaction['country']) payload.add('tr_cu', transaction['currency']) finalise_payload(payload, context, tstamp, subject, page) track(payload) items.each do |item| transform_keys(item) item['tstamp'] = tstamp item['order_id'] = transaction['order_id'] item['currency'] = transaction['currency'] track_ecommerce_transaction_item(item, subject, page) end self end |
#track_page_view(page_url:, page_title: nil, referrer: nil, context: nil, tstamp: nil, subject: nil, page: nil) ⇒ Object
Track a visit to a page.
297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 |
# File 'lib/snowplow-tracker/tracker.rb', line 297 def track_page_view(page_url:, page_title: nil, referrer: nil, context: nil, tstamp: nil, subject: nil, page: nil) tstamp = process_tstamp(tstamp) payload = Payload.new payload.add('e', 'pv') payload.add('url', page_url) payload.add('page', page_title) payload.add('refr', referrer) finalise_payload(payload, context, tstamp, subject, page) track(payload) self end |
#track_screen_view(name: nil, id: nil, context: nil, tstamp: nil, subject: nil, page: nil) ⇒ Object
Track a screen view event. Note that while the name
and id
parameters
are both optional, you must provided at least one of them to create a
valid event.
This method creates an unstruct
event, by creating a
SelfDescribingJson and calling #track_self_describing_event. The
schema ID for this is
"iglu:com.snowplowanalytics.snowplow/screen_view/jsonschema/1-0-0", and
the data field will contain the name and/or ID.
528 529 530 531 532 533 534 535 536 537 538 |
# File 'lib/snowplow-tracker/tracker.rb', line 528 def track_screen_view(name: nil, id: nil, context: nil, tstamp: nil, subject: nil, page: nil) screen_view_properties = {} screen_view_properties['name'] = name unless name.nil? screen_view_properties['id'] = id unless id.nil? event_json = SelfDescribingJson.new(SCREEN_VIEW_SCHEMA, screen_view_properties) track_unstruct_event(event_json: event_json, context: context, tstamp: tstamp, subject: subject, page: page) self end |
#track_self_describing_event(event_json:, context: nil, tstamp: nil, subject: nil, page: nil) ⇒ Object
Track a self-describing event. These are custom events based on SelfDescribingJson, i.e. a JSON schema and a defined set of properties.
This is useful for tracking specific or proprietary event types, or events with unpredicable or frequently changing properties.
This method creates an unstruct
event type. It is actually an alias for
#track_unstruct_event, which is depreciated due to its unhelpful name.
570 571 572 573 |
# File 'lib/snowplow-tracker/tracker.rb', line 570 def track_self_describing_event(event_json:, context: nil, tstamp: nil, subject: nil, page: nil) track_unstruct_event(event_json: event_json, context: context, tstamp: tstamp, subject: subject, page: page) end |
#track_struct_event(category:, action:, label: nil, property: nil, value: nil, context: nil, tstamp: nil, subject: nil, page: nil) ⇒ Object
Track a structured event. category
and action
are required.
This event type can be used to track many types of user activity, as it is somewhat customizable. This event type is provided particularly for concordance with Google Analytics tracking, where events are structured by "category", "action", "label", and "value".
For fully customizable event tracking, we recommend you use self-describing events.
484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 |
# File 'lib/snowplow-tracker/tracker.rb', line 484 def track_struct_event(category:, action:, label: nil, property: nil, value: nil, context: nil, tstamp: nil, subject: nil, page: nil) tstamp = process_tstamp(tstamp) payload = Payload.new payload.add('e', 'se') payload.add('se_ca', category) payload.add('se_ac', action) payload.add('se_la', label) payload.add('se_pr', property) payload.add('se_va', value) finalise_payload(payload, context, tstamp, subject, page) track(payload) self end |
#track_unstruct_event(event_json:, context: nil, tstamp: nil, subject: nil, page: nil) ⇒ Object
Use #track_self_describing_event instead.
578 579 580 581 582 583 584 585 586 587 588 589 590 591 |
# File 'lib/snowplow-tracker/tracker.rb', line 578 def track_unstruct_event(event_json:, context: nil, tstamp: nil, subject: nil, page: nil) tstamp = process_tstamp(tstamp) payload = Payload.new payload.add('e', 'ue') envelope = SelfDescribingJson.new(UNSTRUCT_EVENT_SCHEMA, event_json.to_json) payload.add_json(envelope.to_json, @encode_base64, 'ue_px', 'ue_pr') finalise_payload(payload, context, tstamp, subject, page) track(payload) self end |