1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360
|
# Copyright (c) 2013-2021 Snowplow Analytics Ltd. All rights reserved.
#
# This program is licensed to you under the Apache License Version 2.0,
# and you may not use this file except in compliance with the Apache License Version 2.0.
# You may obtain a copy of the Apache License Version 2.0 at http://www.apache.org/licenses/LICENSE-2.0.
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the Apache License Version 2.0 is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the Apache License Version 2.0 for the specific language governing permissions and limitations there under.
# Author:: Snowplow Analytics Ltd
# Copyright:: Copyright (c) 2013-2021 Snowplow Analytics Ltd
# License:: Apache License Version 2.0
module SnowplowTracker
# Subject objects store information about the user associated with the event,
# such as their `user_id`, what type of device they used, or what size screen
# that device had. Also, they store which platform the event occurred on -
# e.g. server-side app, mobile, games console, etc.
#
# Subject parameters are saved into the tracked event as part of the 'atomic'
# event properties, which have their own column in the eventual table of
# events. For example, a Subject's `user_id` parameter will be sent as `uid`
# in the raw event payload, ending up in the `user_id` column. These
# parameters represent part of the [Snowplow Tracker
# Protocol](https://docs.snowplowanalytics.com/docs/collecting-data/collecting-from-own-applications/snowplow-tracker-protocol),
# which defines a Snowplow event.
#
# Each {Tracker} is initialized with a Subject. This means that every event by
# default has the platform (`p` parameter in the raw event) `srv`: server-side
# app. Platform is the only preset Subject parameter, which can be overriden
# using the {#set_platform} method. All other parameters must be set manually.
# This can be done directly on the Subject, or, if it is associated with a
# Tracker, via the Tracker, which has access to all the methods of its
# Subject.
#
# Your server-side code may not have access to all these parameters, or they
# might not be useful to you. All the Subject parameters are optional, except
# `platform`.
#
# @example Subject methods can be called from their associated Tracker
# # Creating the components explicitly
# emitter = SnowplowTracker::Emitter.new(endpoint: 'localhost')
# subject = SnowplowTracker::Subject.new
# tracker = SnowplowTracker::Tracker.new(emitters: emitter, subject: subject)
#
# # These lines are equivalent
# subject.set_user_id('12345')
# tracker.set_user_id('12345')
#
# # This would also be equivalent
# emitter = SnowplowTracker::Emitter.new(endpoint: 'localhost')
# subject = SnowplowTracker::Subject.new
# subject.set_user_id('12345')
# tracker = SnowplowTracker::Tracker.new(emitters: emitter, subject: subject)
#
# @example Adding properties to the auto-generated Tracker-associated Subject
# # Creating the components
# emitter = SnowplowTracker::Emitter.new(endpoint: 'localhost')
# tracker = SnowplowTracker::Tracker.new(emitters: emitter)
#
# # Set Subject parameters via the Tracker
# tracker.set_user_id('12345')
#
# Since many of the Subject parameters describe the user, different Subject
# properties may often be desired for each event, if there are multiple users.
# This can be achieved in one of three ways:
#
# 1. the properties of the Tracker-associated Subject can be overriden by the
# properties of an event-specific Subject. A Subject can be added to any
# Tracker `#track_x_event` method call, as one of the arguments. Remember to
# set the platform for the event Subject if you're not using `srv`.
# 2. the Tracker-associated Subject can be swapped for another Subject, using
# the Tracker method {Tracker#set_subject}.
# 3. the properties of the Tracker-associated Subject can be changed before
# every `#track_x_event`, by calling the Subject methods via the Tracker.
#
# @see Tracker#set_subject
# @see
# https://docs.snowplowanalytics.com/docs/collecting-data/collecting-from-own-applications/snowplow-tracker-protocol
# the Snowplow Tracker Protocol
# @see
# https://docs.snowplowanalytics.com/docs/collecting-data/collecting-from-own-applications/ruby-tracker/enriching-your-events/
# the Snowplow docs page about adding context and other extra data to events
# @api public
#
# @note All the Subject instance methods return the Subject object, allowing
# method chaining, e.g.
# `SnowplowTracker::Subject.new.set_timezone('Europe/London').set_user_id('12345')`
class Subject
# @private
DEFAULT_PLATFORM = 'srv'
# @api public
#
# | `p` value | Platform |
# | ---- | ---- |
# | app | General App |
# | cnsl | Games Console |
# | iot | Internet of Things |
# | mob | Mobile/Tablet |
# | pc | Desktop/Laptop/Netbook |
# | srv [DEFAULT] | Server-side App |
# | tv | Connected TV |
# | web | Web (including Mobile Web) |
SUPPORTED_PLATFORMS = %w[app cnsl iot mob pc srv tv web]
# Access the Subject parameters
# @example
# SnowplowTracker::Subject.new.set_user_id('12345').details
# => {"p"=>"srv", "uid"=>"12345"}
# @api public
attr_reader :details
# @api public
def initialize
@details = { 'p' => DEFAULT_PLATFORM }
end
# Set the platform to one of the supported platform values.
# @note Value is sent in the event as `p` (raw event) or `platform` (processed event).
# @see Subject::SUPPORTED_PLATFORMS
# @param [String] platform a valid platform choice
# @example
# subject.set_platform('app')
# @return self
# @api public
def set_platform(platform)
raise "#{platform} is not a supported platform" unless SUPPORTED_PLATFORMS.include?(platform)
@details['p'] = platform
self
end
# Set the unique business-defined user ID for a user.
# @note Value is sent in the event as `uid` (raw event) or `user_id` (processed event).
# For example, an email address.
# @example Example user IDs
# # an email address
# janet.bloggs@email.com
#
# # a username
# janetabloggs2021
#
# @param [String] user_id a unique user ID
# @return self
# @api public
def set_user_id(user_id)
@details['uid'] = user_id
self
end
# Set a business-defined fingerprint for a user.
# @note Value is sent in the event as `fp` (raw event) or `user_fingerprint` (processed event).
# @param [Num] fingerprint a user fingerprint
# @return self
# @example
# subject.set_fingerprint(4048966212)
# @api public
def set_fingerprint(fingerprint)
@details['fp'] = fingerprint
self
end
# Set the device screen resolution.
# @note Value is sent in the event as `res` (raw event) or `dvce_screenheight` and `dvce_screenwidth` (processed event).
# @param [Integer] width the screen width, in pixels (must be a positive integer)
# @param [Integer] height the screen height, in pixels (must be a positive integer)
# @return self
# @example
# subject.set_screen_resolution(width: 2880, height: 1800)
# @api public
def set_screen_resolution(width:, height:)
@details['res'] = "#{width}x#{height}"
self
end
# Set the dimensions of the current viewport.
# @note Value is sent in the event as `vp` (raw event) or `br_viewwidth` and `br_viewheight` (processed event).
# @param [Integer] width the viewport width, in pixels (must be a positive integer)
# @param [Integer] height the viewport height, in pixels (must be a positive integer)
# @return self
# @example
# subject.set_viewport(width: 1440, height: 762)
# @api public
def set_viewport(width:, height:)
@details['vp'] = "#{width}x#{height}"
self
end
# Set the color depth of the browser, in bits per pixel.
# @note Value is sent in the event as `cd` (raw event) or `br_colordepth` (processed event).
# @param [Num] depth the colour depth
# @example
# subject.set_color_depth(24)
# @return self
# @api public
def set_color_depth(depth)
@details['cd'] = depth
self
end
# Set the timezone to that of the user's OS.
# @note Value is sent in the event as `tz` (raw event) or `os_timezone` (processed event).
# @example
# subject.set_timezone('Africa/Lagos')
# @param [String] timezone the timezone
# @return self
# @api public
def set_timezone(timezone)
@details['tz'] = timezone
self
end
# Set the language.
# @note Value is sent in the event as `lang` (raw event) or `br_lang` (processed event).
# @example Setting the language to Spanish
# subject.set_lang('es')
# @param [String] lang the language being used on the device
# @return self
# @api public
def set_lang(lang)
@details['lang'] = lang
self
end
# Set the domain user ID.
# @note Value is sent in the event as `duid` (raw event) or `domain_userid` (processed event).
# @see Subject#set_network_user_id
# @see Subject#set_domain_session_id
# @see Subject#set_domain_session_idx
# @see https://github.com/simplybusiness/snowplow_ruby_duid/ snowplow_ruby_duid, a third party gem
# @see https://github.com/snowplow-incubator/snowplow-ruby-tracker-examples
# Ruby tracker example Rails app
# @example
# subject.set_domain_user_id('aeb1691c5a0ee5a6')
# @param [String] duid the unique domain user ID
# @return self
# @api public
#
# The `domain_userid` is a client-side unique user ID, which is set by the
# browser-based JavaScript tracker, and stored in a first party cookie
# (cookie name: `_sp_id`). For stitching together client-side and
# server-side events originating from the same user, the domain user ID can
# be extracted from the cookie and set using this method. A third party gem,
# [snowplow_ruby_duid](https://github.com/simplybusiness/snowplow_ruby_duid/),
# has been created to help with this.
#
# @example Ruby on Rails: getting the domain_user_id from the cookie
# # Assuming the Snowplow JavaScript has also been incorporated
# # cookies are accessible only within a Controller
# def snowplow_domain_userid
# sp_cookie = cookies.find { |key, _value| key =~ /^_sp_id/ }
# sp_cookie.last.split(".").first if sp_cookie.present?
# end
#
def set_domain_user_id(duid)
@details['duid'] = duid
self
end
# Set the domain session ID.
# @note Value is sent in the event as `sid` (raw event) or `domain_sessionid` (processed event).
# @see Subject#set_network_user_id
# @see Subject#set_domain_user_id
# @see Subject#set_domain_session_idx
# @example
# subject.set_domain_session_id('9c65e7f3-8e8e-470d-b243-910b5b300da0')
# @param [String] sid the unique domain session ID
# @return self
# @api public
#
# The `domain_sessionid` is a client-side unique ID for a user's current
# session. It is set by the browser-based JavaScript trackers, and stored in
# a first party cookie (cookie name: `_sp_id`), along with other parameters
# such as `domain_userid`. For stitching together client-side and
# server-side events originating from the same user and session, the domain
# session ID can be extracted from the cookie and set using this method.
def set_domain_session_id(sid)
@details['sid'] = sid
self
end
# Set the domain session index.
# @note Value is sent in the event as `vid` (raw event) or `domain_sessionidx` (processed event).
# @see Subject#set_network_user_id
# @see Subject#set_domain_user_id
# @see Subject#set_domain_session_id
# @example
# subject.set_domain_session_idx(3)
# @param [Num] vid the number of sessions
# @return self
# @api public
#
# The `domain_sessionidx` is a client-side property that records how many
# visits (unique `domain_sessionid`s) a user (a unique `domain_userid`) has
# made to the site. It is stored in the first party cookie set by the
# JavaScript tracker, along with other parameters such as `domain_userid`.
# For stitching together client-side and server-side events originating from
# the same user and session, the domain session index can be extracted from
# the cookie and set using this method.
def set_domain_session_idx(vid)
@details['vid'] = vid
self
end
# Set the user's IP address.
# @note Value is sent in the event as `ip` (raw event) or `user_ipaddress` (processed event).
# @param [String] ip the IP address
# @return self
# @example
# subject.set_ip_address('37.157.33.178')
# @api public
def set_ip_address(ip)
@details['ip'] = ip
self
end
# Set the browser user agent.
# @note Value is sent in the event as `ua` (raw event) or `useragent` (processed event).
# @example
# subject.set_useragent('Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:92.0) Gecko/20100101 Firefox/92.0')
# @param [String] useragent the user agent string
# @return self
# @api public
def set_useragent(useragent)
@details['ua'] = useragent
self
end
# Set the network user ID.
# @note Value is sent in the event as `tnuid` (raw event) and `network_userid` (processed event).
# @see Subject#set_domain_user_id
#
# The network user ID is, like the `domain_userid`, a cookie-based unique
# user ID. It is stored in a third party cookie set by the event collector,
# hence the name "network" as it is set at a network level. It is the
# server-side user identifier. The raw event does not contain a `nuid`
# value; the `network_userid` property is added when the event is processed.
#
# The default behaviour is for the collector to provide a new cookie/network
# user ID for each event it receives. This method provides the ability to
# override the collector cookie's value with your own generated ID.
#
# Domain user IDs set on the Subject in this way are sent as `tnuid` in the
# raw event.
#
# @example
# subject.set_network_user_id('ecdff4d0-9175-40ac-a8bb-325c49733607')
# @param [String] nuid the network user ID
# @return self
# @api public
def set_network_user_id(nuid)
@details['tnuid'] = nuid
self
end
end
end
|