snowplow-tracker 0.7.0 → 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +11 -8
- data/lib/snowplow-tracker/emitters.rb +25 -48
- data/lib/snowplow-tracker/page.rb +1 -6
- data/lib/snowplow-tracker/payload.rb +0 -7
- data/lib/snowplow-tracker/self_describing_json.rb +1 -1
- data/lib/snowplow-tracker/subject.rb +25 -27
- data/lib/snowplow-tracker/timestamp.rb +15 -19
- data/lib/snowplow-tracker/tracker.rb +45 -86
- data/lib/snowplow-tracker/version.rb +1 -8
- metadata +2 -22
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 828096deb0a370f527d14f17e2e48eb1481428b5cdc1b2897235b539be64f327
|
4
|
+
data.tar.gz: e0b5b026cfad092a2c4269876bc0b7e5d240ba5ec8b18b67b8a1e97d7c127a93
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b75d45c5b03f55398ab27a9945d9ddbe91340348d803e8be8d4c74b108f39931cd7a7e17a661a818ffd9e3d81aac71bdf3a8d5486c397881a741bfc5e1b881b0
|
7
|
+
data.tar.gz: 650468a842f96ab6951aa54bc374115ee0dc3a466b6f15807c8a0e8fb1e86127b630ee226f8c0ba49b3316ae20d342c24c6211810e2c2eac65791d7f4fa9f478
|
data/README.md
CHANGED
@@ -9,30 +9,28 @@
|
|
9
9
|
|
10
10
|
## Overview
|
11
11
|
|
12
|
-
Add analytics to your Ruby and Rails apps and gems with the **[Snowplow][snowplow]** event tracker for **[Ruby][ruby]**.
|
12
|
+
Add analytics to your **[Ruby][ruby]** and **[Ruby on Rails][rails]** apps and **[gems][rubygems]** with the **[Snowplow][snowplow]** event tracker for **[Ruby][ruby]**.
|
13
13
|
|
14
14
|
Snowplow is a scalable open-source platform for rich, high quality, low-latency data collection. It is designed to collect high quality, complete behavioral data for enterprise business.
|
15
15
|
|
16
16
|
**To find out more, please check out the [Snowplow website][snowplow] and our [documentation][docs].**
|
17
17
|
|
18
|
-
With this tracker you can collect event data from your **[Ruby][ruby]** applications, **[Ruby on Rails][rails]** web applications and **[Ruby gems][rubygems]**.
|
19
|
-
|
20
18
|
## Quickstart
|
21
19
|
|
22
20
|
Add this gem to your Gemfile. It is compatible with Ruby versions 2.1 to 3.0+.
|
23
21
|
|
24
22
|
```ruby
|
25
|
-
gem "snowplow-tracker", "~> 0.
|
23
|
+
gem "snowplow-tracker", "~> 0.8.0"
|
26
24
|
```
|
27
25
|
|
28
26
|
See our [demo app][demoapp] for an example of implementing the Ruby tracker in a Rails app.
|
29
27
|
|
30
28
|
## Find out more
|
31
29
|
|
32
|
-
|
|
30
|
+
| Snowplow Docs | API Docs | Contributing |
|
33
31
|
| ------------------------------ | ----------------------- | ----------------------------------- |
|
34
32
|
| ![i1][techdocs-image] | ![i1][techdocs-image] | ![i4][contributing-image] |
|
35
|
-
| **[
|
33
|
+
| **[Snowplow Docs][techdocs]** | **[API Docs][apidocs]** | **[Contributing](Contributing.md)** |
|
36
34
|
|
37
35
|
## Maintainer Quickstart
|
38
36
|
|
@@ -47,11 +45,16 @@ The `-v` flag for `docker run` creates a bind mount for the project directory. T
|
|
47
45
|
|
48
46
|
Alternatively, test directly by installing Ruby 2.1+ and [Bundler][bundler]. Then run:
|
49
47
|
|
50
|
-
```
|
48
|
+
```bash
|
51
49
|
bundle install
|
52
50
|
rspec
|
53
51
|
```
|
54
52
|
|
53
|
+
To generate documentation using YARD, make sure the YARD and redcarpet gems are installed locally. Then run:
|
54
|
+
```bash
|
55
|
+
yard doc
|
56
|
+
```
|
57
|
+
|
55
58
|
## Contributing
|
56
59
|
|
57
60
|
Feedback and contributions are welcome - if you have identified a bug, please log an issue on this repo. For all other feedback, discussion or questions please open a thread on our [Discourse forum][discourse].
|
@@ -72,7 +75,7 @@ limitations under the License.
|
|
72
75
|
[license-image]: https://img.shields.io/badge/license-Apache--2-blue.svg?style=flat
|
73
76
|
[license]: https://www.apache.org/licenses/LICENSE-2.0
|
74
77
|
[gh-actions]: https://github.com/snowplow/snowplow-ruby-tracker/actions
|
75
|
-
[gh-actions-image]: https://github.com/snowplow/snowplow-ruby-tracker/workflows/
|
78
|
+
[gh-actions-image]: https://github.com/snowplow/snowplow-ruby-tracker/workflows/Test/badge.svg
|
76
79
|
[tracker-classification]: https://docs.snowplowanalytics.com/docs/collecting-data/collecting-from-own-applications/tracker-maintenance-classification/
|
77
80
|
[early-release]: https://img.shields.io/static/v1?style=flat&label=Snowplow&message=Early%20Release&color=014477&labelColor=9ba0aa&logo=data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAAeFBMVEVMaXGXANeYANeXANZbAJmXANeUANSQAM+XANeMAMpaAJhZAJeZANiXANaXANaOAM2WANVnAKWXANZ9ALtmAKVaAJmXANZaAJlXAJZdAJxaAJlZAJdbAJlbAJmQAM+UANKZANhhAJ+EAL+BAL9oAKZnAKVjAKF1ALNBd8J1AAAAKHRSTlMAa1hWXyteBTQJIEwRgUh2JjJon21wcBgNfmc+JlOBQjwezWF2l5dXzkW3/wAAAHpJREFUeNokhQOCA1EAxTL85hi7dXv/E5YPCYBq5DeN4pcqV1XbtW/xTVMIMAZE0cBHEaZhBmIQwCFofeprPUHqjmD/+7peztd62dWQRkvrQayXkn01f/gWp2CrxfjY7rcZ5V7DEMDQgmEozFpZqLUYDsNwOqbnMLwPAJEwCopZxKttAAAAAElFTkSuQmCC
|
78
81
|
|
@@ -17,7 +17,6 @@
|
|
17
17
|
require 'net/https'
|
18
18
|
require 'set'
|
19
19
|
require 'logger'
|
20
|
-
require 'contracts'
|
21
20
|
|
22
21
|
module SnowplowTracker
|
23
22
|
# @see Emitter
|
@@ -38,7 +37,10 @@ module SnowplowTracker
|
|
38
37
|
# | Buffer size | 1 |
|
39
38
|
# | Path | `/i` |
|
40
39
|
#
|
41
|
-
# The buffer size is
|
40
|
+
# The buffer size is the number of events which will be buffered before they
|
41
|
+
# are all sent simultaneously. The process of sending all buffered events is
|
42
|
+
# called "flushing". The default buffer size is 1 because GET requests can
|
43
|
+
# only contain one event.
|
42
44
|
#
|
43
45
|
# If you choose to use POST requests, the buffer_size defaults to 10, and the
|
44
46
|
# buffered events are all sent together in a single request. The default path
|
@@ -61,42 +63,15 @@ module SnowplowTracker
|
|
61
63
|
# require 'logger'
|
62
64
|
# SnowplowTracker::LOGGER.level = Logger::DEBUG
|
63
65
|
class Emitter
|
64
|
-
include Contracts
|
65
|
-
|
66
|
-
# Contract types
|
67
|
-
|
68
|
-
# @private
|
69
|
-
CONFIG_HASH = {
|
70
|
-
path: Maybe[String],
|
71
|
-
protocol: Maybe[Or['http', 'https']],
|
72
|
-
port: Maybe[Num],
|
73
|
-
method: Maybe[Or['get', 'post']],
|
74
|
-
buffer_size: Maybe[Num],
|
75
|
-
on_success: Maybe[Func[Num => Any]],
|
76
|
-
on_failure: Maybe[Func[Num, Hash => Any]],
|
77
|
-
thread_count: Maybe[Num],
|
78
|
-
logger: Maybe[Logger]
|
79
|
-
}
|
80
|
-
|
81
|
-
# @private
|
82
|
-
STRICT_CONFIG_HASH = And[CONFIG_HASH, ->(x) {
|
83
|
-
(x.class == Hash) && Set.new(x.keys).subset?(Set.new(CONFIG_HASH.keys))
|
84
|
-
}]
|
85
|
-
|
86
|
-
# @!group Public constants
|
87
|
-
|
88
66
|
# Default Emitter settings
|
89
67
|
DEFAULT_CONFIG = {
|
90
68
|
protocol: 'http',
|
91
69
|
method: 'get'
|
92
70
|
}
|
93
71
|
|
94
|
-
# @!endgroup
|
95
|
-
|
96
72
|
# @private
|
97
73
|
attr_reader :logger
|
98
74
|
|
99
|
-
Contract KeywordArgs[endpoint: String, options: Optional[STRICT_CONFIG_HASH]] => Any
|
100
75
|
# Create a new Emitter instance. The endpoint is required.
|
101
76
|
#
|
102
77
|
# @example Initializing an Emitter with all the possible extra configuration.
|
@@ -105,7 +80,7 @@ module SnowplowTracker
|
|
105
80
|
# puts "#{success_count} events sent successfully, #{failures.size} sent unsuccessfully"
|
106
81
|
# end
|
107
82
|
#
|
108
|
-
# Emitter.new(endpoint: 'collector.example.com',
|
83
|
+
# SnowplowTracker::Emitter.new(endpoint: 'collector.example.com',
|
109
84
|
# options: { path: '/my-pipeline/1',
|
110
85
|
# protocol: 'https',
|
111
86
|
# port: 443,
|
@@ -124,8 +99,8 @@ module SnowplowTracker
|
|
124
99
|
# | port | The port for the connection | Integer |
|
125
100
|
# | method | 'get' or 'post' | String |
|
126
101
|
# | buffer_size | Number of events to send at once | Integer |
|
127
|
-
# | on_success | A
|
128
|
-
# | on_failure | A
|
102
|
+
# | on_success | A method to call if events were sent successfully | Method |
|
103
|
+
# | on_failure | A method to call if events did not send | Method |
|
129
104
|
# | thread_count | Number of threads to use | Integer |
|
130
105
|
# | logger | Log somewhere other than STDERR | Logger |
|
131
106
|
#
|
@@ -134,6 +109,13 @@ module SnowplowTracker
|
|
134
109
|
#
|
135
110
|
# If you choose to use HTTPS, we recommend using port 443.
|
136
111
|
#
|
112
|
+
# Only 2xx and 3xx status codes are considered successes.
|
113
|
+
#
|
114
|
+
# The `on_success` callback should accept one argument: the number of
|
115
|
+
# requests sent this way. The `on_failure` callback should accept two
|
116
|
+
# arguments: the number of successfully sent events, and an array containing
|
117
|
+
# the unsuccessful events.
|
118
|
+
#
|
137
119
|
# @param endpoint [String] the endpoint to send the events to
|
138
120
|
# @param options [Hash] allowed configuration options
|
139
121
|
#
|
@@ -153,7 +135,6 @@ module SnowplowTracker
|
|
153
135
|
logger.info("#{self.class} initialized with endpoint #{@collector_uri}")
|
154
136
|
end
|
155
137
|
|
156
|
-
Contract Hash => Num
|
157
138
|
# Creates the `@buffer_size` variable during initialization. Unless
|
158
139
|
# otherwise defined, it's 1 for Emitters using GET and 10 for Emitters using
|
159
140
|
# POST requests.
|
@@ -164,7 +145,6 @@ module SnowplowTracker
|
|
164
145
|
config[:method] == 'get' ? 1 : 10
|
165
146
|
end
|
166
147
|
|
167
|
-
Contract Hash => String
|
168
148
|
# Creates the `@path` variable during initialization. Allows a non-standard
|
169
149
|
# path to be provided.
|
170
150
|
# @private
|
@@ -174,9 +154,6 @@ module SnowplowTracker
|
|
174
154
|
config[:method] == 'get' ? '/i' : '/com.snowplowanalytics.snowplow/tp2'
|
175
155
|
end
|
176
156
|
|
177
|
-
# Build the collector URI from the configuration hash
|
178
|
-
#
|
179
|
-
Contract String, String, Maybe[Num], String => String
|
180
157
|
# Creates the `@collector_uri` variable during initialization.
|
181
158
|
# The default is "http://{endpoint}/i".
|
182
159
|
# @private
|
@@ -186,7 +163,6 @@ module SnowplowTracker
|
|
186
163
|
"#{protocol}://#{endpoint}#{port_string}#{path}"
|
187
164
|
end
|
188
165
|
|
189
|
-
Contract Hash => nil
|
190
166
|
# Add an event to the buffer and flush it if maximum size has been reached.
|
191
167
|
# This method is not required for standard Ruby tracker usage. A {Tracker}
|
192
168
|
# privately calls this method once the event payload is ready to send.
|
@@ -197,6 +173,9 @@ module SnowplowTracker
|
|
197
173
|
# to send. You could use {#input} as part of your callback to immediately
|
198
174
|
# retry the failed event.
|
199
175
|
#
|
176
|
+
# The `on_failure` callback should accept two arguments: the number of
|
177
|
+
# successfully sent events, and an array containing the unsuccessful events.
|
178
|
+
#
|
200
179
|
# @example A possible `on_failure` method using `#input`
|
201
180
|
# def retry_on_failure(failed_event_count, failed_events)
|
202
181
|
# # possible backoff-and-retry timeout here
|
@@ -216,7 +195,6 @@ module SnowplowTracker
|
|
216
195
|
nil
|
217
196
|
end
|
218
197
|
|
219
|
-
Contract Bool => nil
|
220
198
|
# Flush the Emitter, forcing it to send all the events in its
|
221
199
|
# buffer, even if the buffer is not full. {Emitter} objects, unlike
|
222
200
|
# {AsyncEmitter}s, can only `flush` synchronously. A {Tracker} can manually flush all
|
@@ -237,7 +215,6 @@ module SnowplowTracker
|
|
237
215
|
nil
|
238
216
|
end
|
239
217
|
|
240
|
-
Contract ArrayOf[Hash] => nil
|
241
218
|
# Send all events in the buffer to the collector
|
242
219
|
# @private
|
243
220
|
def send_requests(events)
|
@@ -262,7 +239,6 @@ module SnowplowTracker
|
|
262
239
|
nil
|
263
240
|
end
|
264
241
|
|
265
|
-
Contract ArrayOf[Hash] => nil
|
266
242
|
# Part of {#send_requests}.
|
267
243
|
# @private
|
268
244
|
def send_requests_with_post(events)
|
@@ -286,7 +262,6 @@ module SnowplowTracker
|
|
286
262
|
nil
|
287
263
|
end
|
288
264
|
|
289
|
-
Contract ArrayOf[Hash] => nil
|
290
265
|
# Part of {#send_requests}.
|
291
266
|
# @private
|
292
267
|
def send_requests_with_get(events)
|
@@ -307,7 +282,6 @@ module SnowplowTracker
|
|
307
282
|
nil
|
308
283
|
end
|
309
284
|
|
310
|
-
Contract Hash => Bool
|
311
285
|
# Part of {#send_requests_with_get}.
|
312
286
|
# @private
|
313
287
|
def process_get_event(event)
|
@@ -321,7 +295,6 @@ module SnowplowTracker
|
|
321
295
|
get_succeeded
|
322
296
|
end
|
323
297
|
|
324
|
-
Contract Hash => ->(x) { x.is_a? Net::HTTPResponse }
|
325
298
|
# Part of {#process_get_event}. This sends a GET request.
|
326
299
|
# @private
|
327
300
|
def http_get(payload)
|
@@ -339,7 +312,6 @@ module SnowplowTracker
|
|
339
312
|
response
|
340
313
|
end
|
341
314
|
|
342
|
-
Contract Hash => ->(x) { x.is_a? Net::HTTPResponse }
|
343
315
|
# Part of {#send_requests_with_post}. This sends a POST request.
|
344
316
|
# @private
|
345
317
|
def http_post(payload)
|
@@ -359,7 +331,6 @@ module SnowplowTracker
|
|
359
331
|
response
|
360
332
|
end
|
361
333
|
|
362
|
-
Contract String => Bool
|
363
334
|
# Check if the response is good.
|
364
335
|
# Only 2xx and 3xx status codes are considered successes.
|
365
336
|
# @private
|
@@ -381,7 +352,6 @@ module SnowplowTracker
|
|
381
352
|
# @see Emitter
|
382
353
|
# @api public
|
383
354
|
class AsyncEmitter < Emitter
|
384
|
-
Contract KeywordArgs[endpoint: String, options: Optional[STRICT_CONFIG_HASH]] => Any
|
385
355
|
# Create a new AsyncEmitter object. The endpoint is required.
|
386
356
|
#
|
387
357
|
# @example Initializing an AsyncEmitter with all the possible extra configuration.
|
@@ -390,7 +360,7 @@ module SnowplowTracker
|
|
390
360
|
# puts "#{success_count} events sent successfully, #{failures.size} sent unsuccessfully"
|
391
361
|
# end
|
392
362
|
#
|
393
|
-
# Emitter.new(endpoint: 'collector.example.com',
|
363
|
+
# SnowplowTracker::Emitter.new(endpoint: 'collector.example.com',
|
394
364
|
# options: { path: '/my-pipeline/1',
|
395
365
|
# protocol: 'https',
|
396
366
|
# port: 443,
|
@@ -420,6 +390,13 @@ module SnowplowTracker
|
|
420
390
|
#
|
421
391
|
# If you choose to use HTTPS, we recommend using port 443.
|
422
392
|
#
|
393
|
+
# Only 2xx and 3xx status codes are considered successes.
|
394
|
+
#
|
395
|
+
# The `on_success` callback should accept one argument: the number of
|
396
|
+
# requests sent this way. The `on_failure` callback should accept two
|
397
|
+
# arguments: the number of successfully sent events, and an array containing
|
398
|
+
# the unsuccessful events.
|
399
|
+
#
|
423
400
|
# @note if you test the AsyncEmitter by using a short script to send an
|
424
401
|
# event, you may find that the event fails to send. This is because the
|
425
402
|
# process exits before the flushing thread is finished. You can get round
|
@@ -14,8 +14,6 @@
|
|
14
14
|
# License:: Apache License Version 2.0
|
15
15
|
|
16
16
|
|
17
|
-
require 'contracts'
|
18
|
-
|
19
17
|
module SnowplowTracker
|
20
18
|
# If the Ruby tracker is incorporated into a website server, the events
|
21
19
|
# tracked will describe user activity on specific webpages. Knowing on which
|
@@ -33,18 +31,15 @@ module SnowplowTracker
|
|
33
31
|
# @note For {Tracker#track_page_view}, properties set in the Page object will
|
34
32
|
# override those properties given as arguments.
|
35
33
|
class Page
|
36
|
-
include Contracts
|
37
|
-
|
38
34
|
# @return [Hash] the stored page properties
|
39
35
|
attr_reader :details
|
40
36
|
|
41
|
-
Contract KeywordArgs[page_url: Maybe[String], page_title: Maybe[String], referrer: Maybe[String]] => Any
|
42
37
|
# Create a Page object for attaching page properties to events.
|
43
38
|
#
|
44
39
|
# Page properties will directly populate the event's `page_url`, `page_title` and `referrer` parameters.
|
45
40
|
#
|
46
41
|
# @example Creating a Page
|
47
|
-
# Page.new(page_url: 'http://www.example.com/second-page',
|
42
|
+
# SnowplowTracker::Page.new(page_url: 'http://www.example.com/second-page',
|
48
43
|
# page_title: 'Example title',
|
49
44
|
# referrer: 'http://www.example.com/first-page')
|
50
45
|
#
|
@@ -17,7 +17,6 @@
|
|
17
17
|
require 'base64'
|
18
18
|
require 'json'
|
19
19
|
require 'net/http'
|
20
|
-
require 'contracts'
|
21
20
|
|
22
21
|
module SnowplowTracker
|
23
22
|
# @private
|
@@ -26,28 +25,22 @@ module SnowplowTracker
|
|
26
25
|
# hash. These properties form the raw event, after the completed hash is
|
27
26
|
# given to the Emitter.
|
28
27
|
class Payload
|
29
|
-
include Contracts
|
30
|
-
|
31
28
|
attr_reader :data
|
32
29
|
|
33
|
-
Contract nil => Any
|
34
30
|
def initialize
|
35
31
|
@data = {}
|
36
32
|
end
|
37
33
|
|
38
|
-
Contract String, Or[String, Bool, Num, nil] => Or[String, Bool, Num, nil]
|
39
34
|
# Add a single name-value pair to @data.
|
40
35
|
def add(name, value)
|
41
36
|
@data[name] = value if (value != '') && !value.nil?
|
42
37
|
end
|
43
38
|
|
44
|
-
Contract Hash => Hash
|
45
39
|
# Add each name-value pair in a hash to @data.
|
46
40
|
def add_hash(hash)
|
47
41
|
hash.each { |key, value| add(key, value) }
|
48
42
|
end
|
49
43
|
|
50
|
-
Contract Maybe[Hash], Bool, String, String => Maybe[String]
|
51
44
|
# Stringify a JSON and add it to @data.
|
52
45
|
#
|
53
46
|
# In practice, the JSON provided will be a SelfDescribingJson. This method
|
@@ -77,7 +77,7 @@ module SnowplowTracker
|
|
77
77
|
# # Creating the SelfDescribingJson
|
78
78
|
# schema_name = "iglu:com.snowplowanalytics/ad_click/jsonschema/1-0-0"
|
79
79
|
# event_data = { bannerId: "4acd518feb82" }
|
80
|
-
# SelfDescribingJson.new(schema_name, event_data)
|
80
|
+
# SnowplowTracker::SelfDescribingJson.new(schema_name, event_data)
|
81
81
|
#
|
82
82
|
# # The self-describing JSON that will be sent (stringified) with the event
|
83
83
|
# {
|
@@ -14,8 +14,6 @@
|
|
14
14
|
# License:: Apache License Version 2.0
|
15
15
|
|
16
16
|
|
17
|
-
require 'contracts'
|
18
|
-
|
19
17
|
module SnowplowTracker
|
20
18
|
# Subject objects store information about the user associated with the event,
|
21
19
|
# such as their `user_id`, what type of device they used, or what size screen
|
@@ -68,7 +66,7 @@ module SnowplowTracker
|
|
68
66
|
#
|
69
67
|
# Since many of the Subject parameters describe the user, different Subject
|
70
68
|
# properties may often be desired for each event, if there are multiple users.
|
71
|
-
# This can be achieved in one of
|
69
|
+
# This can be achieved in one of three ways:
|
72
70
|
#
|
73
71
|
# 1. the properties of the Tracker-associated Subject can be overriden by the
|
74
72
|
# properties of an event-specific Subject. A Subject can be added to any
|
@@ -76,19 +74,22 @@ module SnowplowTracker
|
|
76
74
|
# set the platform for the event Subject if you're not using `srv`.
|
77
75
|
# 2. the Tracker-associated Subject can be swapped for another Subject, using
|
78
76
|
# the Tracker method {Tracker#set_subject}.
|
77
|
+
# 3. the properties of the Tracker-associated Subject can be changed before
|
78
|
+
# every `#track_x_event`, by calling the Subject methods via the Tracker.
|
79
79
|
#
|
80
80
|
# @see Tracker#set_subject
|
81
81
|
# @see
|
82
82
|
# https://docs.snowplowanalytics.com/docs/collecting-data/collecting-from-own-applications/snowplow-tracker-protocol
|
83
83
|
# the Snowplow Tracker Protocol
|
84
|
+
# @see
|
85
|
+
# https://docs.snowplowanalytics.com/docs/collecting-data/collecting-from-own-applications/ruby-tracker/enriching-your-events/
|
86
|
+
# the Snowplow docs page about adding context and other extra data to events
|
84
87
|
# @api public
|
85
88
|
#
|
86
89
|
# @note All the Subject instance methods return the Subject object, allowing
|
87
90
|
# method chaining, e.g.
|
88
|
-
# `Subject.new.set_timezone('Europe/London').set_user_id('12345')`
|
91
|
+
# `SnowplowTracker::Subject.new.set_timezone('Europe/London').set_user_id('12345')`
|
89
92
|
class Subject
|
90
|
-
include Contracts
|
91
|
-
|
92
93
|
# @private
|
93
94
|
DEFAULT_PLATFORM = 'srv'
|
94
95
|
|
@@ -108,22 +109,22 @@ module SnowplowTracker
|
|
108
109
|
|
109
110
|
# Access the Subject parameters
|
110
111
|
# @example
|
111
|
-
# Subject.new.set_user_id('12345').details
|
112
|
+
# SnowplowTracker::Subject.new.set_user_id('12345').details
|
112
113
|
# => {"p"=>"srv", "uid"=>"12345"}
|
113
114
|
# @api public
|
114
115
|
attr_reader :details
|
115
116
|
|
116
|
-
Contract None => Any
|
117
117
|
# @api public
|
118
118
|
def initialize
|
119
119
|
@details = { 'p' => DEFAULT_PLATFORM }
|
120
120
|
end
|
121
121
|
|
122
|
-
Contract String => Subject
|
123
122
|
# Set the platform to one of the supported platform values.
|
124
123
|
# @note Value is sent in the event as `p` (raw event) or `platform` (processed event).
|
125
124
|
# @see Subject::SUPPORTED_PLATFORMS
|
126
125
|
# @param [String] platform a valid platform choice
|
126
|
+
# @example
|
127
|
+
# subject.set_platform('app')
|
127
128
|
# @return self
|
128
129
|
# @api public
|
129
130
|
def set_platform(platform)
|
@@ -133,7 +134,6 @@ module SnowplowTracker
|
|
133
134
|
self
|
134
135
|
end
|
135
136
|
|
136
|
-
Contract String => Subject
|
137
137
|
# Set the unique business-defined user ID for a user.
|
138
138
|
# @note Value is sent in the event as `uid` (raw event) or `user_id` (processed event).
|
139
139
|
# For example, an email address.
|
@@ -152,45 +152,49 @@ module SnowplowTracker
|
|
152
152
|
self
|
153
153
|
end
|
154
154
|
|
155
|
-
Contract Num => Subject
|
156
155
|
# Set a business-defined fingerprint for a user.
|
157
156
|
# @note Value is sent in the event as `fp` (raw event) or `user_fingerprint` (processed event).
|
158
157
|
# @param [Num] fingerprint a user fingerprint
|
159
158
|
# @return self
|
159
|
+
# @example
|
160
|
+
# subject.set_fingerprint(4048966212)
|
160
161
|
# @api public
|
161
162
|
def set_fingerprint(fingerprint)
|
162
163
|
@details['fp'] = fingerprint
|
163
164
|
self
|
164
165
|
end
|
165
166
|
|
166
|
-
Contract KeywordArgs[width: Num, height: Num] => Subject
|
167
167
|
# Set the device screen resolution.
|
168
168
|
# @note Value is sent in the event as `res` (raw event) or `dvce_screenheight` and `dvce_screenwidth` (processed event).
|
169
|
-
# @param [
|
170
|
-
# @param [
|
169
|
+
# @param [Integer] width the screen width, in pixels (must be a positive integer)
|
170
|
+
# @param [Integer] height the screen height, in pixels (must be a positive integer)
|
171
171
|
# @return self
|
172
|
+
# @example
|
173
|
+
# subject.set_screen_resolution(width: 2880, height: 1800)
|
172
174
|
# @api public
|
173
175
|
def set_screen_resolution(width:, height:)
|
174
176
|
@details['res'] = "#{width}x#{height}"
|
175
177
|
self
|
176
178
|
end
|
177
179
|
|
178
|
-
Contract KeywordArgs[width: Num, height: Num] => Subject
|
179
180
|
# Set the dimensions of the current viewport.
|
180
181
|
# @note Value is sent in the event as `vp` (raw event) or `br_viewwidth` and `br_viewheight` (processed event).
|
181
|
-
# @param [
|
182
|
-
# @param [
|
182
|
+
# @param [Integer] width the viewport width, in pixels (must be a positive integer)
|
183
|
+
# @param [Integer] height the viewport height, in pixels (must be a positive integer)
|
183
184
|
# @return self
|
185
|
+
# @example
|
186
|
+
# subject.set_viewport(width: 1440, height: 762)
|
184
187
|
# @api public
|
185
188
|
def set_viewport(width:, height:)
|
186
189
|
@details['vp'] = "#{width}x#{height}"
|
187
190
|
self
|
188
191
|
end
|
189
192
|
|
190
|
-
|
191
|
-
# Set the color depth of the device, in bits per pixel.
|
193
|
+
# Set the color depth of the browser, in bits per pixel.
|
192
194
|
# @note Value is sent in the event as `cd` (raw event) or `br_colordepth` (processed event).
|
193
195
|
# @param [Num] depth the colour depth
|
196
|
+
# @example
|
197
|
+
# subject.set_color_depth(24)
|
194
198
|
# @return self
|
195
199
|
# @api public
|
196
200
|
def set_color_depth(depth)
|
@@ -198,7 +202,6 @@ module SnowplowTracker
|
|
198
202
|
self
|
199
203
|
end
|
200
204
|
|
201
|
-
Contract String => Subject
|
202
205
|
# Set the timezone to that of the user's OS.
|
203
206
|
# @note Value is sent in the event as `tz` (raw event) or `os_timezone` (processed event).
|
204
207
|
# @example
|
@@ -211,7 +214,6 @@ module SnowplowTracker
|
|
211
214
|
self
|
212
215
|
end
|
213
216
|
|
214
|
-
Contract String => Subject
|
215
217
|
# Set the language.
|
216
218
|
# @note Value is sent in the event as `lang` (raw event) or `br_lang` (processed event).
|
217
219
|
# @example Setting the language to Spanish
|
@@ -224,7 +226,6 @@ module SnowplowTracker
|
|
224
226
|
self
|
225
227
|
end
|
226
228
|
|
227
|
-
Contract String => Subject
|
228
229
|
# Set the domain user ID.
|
229
230
|
# @note Value is sent in the event as `duid` (raw event) or `domain_userid` (processed event).
|
230
231
|
# @see Subject#set_network_user_id
|
@@ -260,7 +261,6 @@ module SnowplowTracker
|
|
260
261
|
self
|
261
262
|
end
|
262
263
|
|
263
|
-
Contract String => Subject
|
264
264
|
# Set the domain session ID.
|
265
265
|
# @note Value is sent in the event as `sid` (raw event) or `domain_sessionid` (processed event).
|
266
266
|
# @see Subject#set_network_user_id
|
@@ -283,7 +283,6 @@ module SnowplowTracker
|
|
283
283
|
self
|
284
284
|
end
|
285
285
|
|
286
|
-
Contract Num => Subject
|
287
286
|
# Set the domain session index.
|
288
287
|
# @note Value is sent in the event as `vid` (raw event) or `domain_sessionidx` (processed event).
|
289
288
|
# @see Subject#set_network_user_id
|
@@ -307,18 +306,18 @@ module SnowplowTracker
|
|
307
306
|
self
|
308
307
|
end
|
309
308
|
|
310
|
-
Contract String => Subject
|
311
309
|
# Set the user's IP address.
|
312
310
|
# @note Value is sent in the event as `ip` (raw event) or `user_ipaddress` (processed event).
|
313
311
|
# @param [String] ip the IP address
|
314
312
|
# @return self
|
313
|
+
# @example
|
314
|
+
# subject.set_ip_address('37.157.33.178')
|
315
315
|
# @api public
|
316
316
|
def set_ip_address(ip)
|
317
317
|
@details['ip'] = ip
|
318
318
|
self
|
319
319
|
end
|
320
320
|
|
321
|
-
Contract String => Subject
|
322
321
|
# Set the browser user agent.
|
323
322
|
# @note Value is sent in the event as `ua` (raw event) or `useragent` (processed event).
|
324
323
|
# @example
|
@@ -331,7 +330,6 @@ module SnowplowTracker
|
|
331
330
|
self
|
332
331
|
end
|
333
332
|
|
334
|
-
Contract String => Subject
|
335
333
|
# Set the network user ID.
|
336
334
|
# @note Value is sent in the event as `tnuid` (raw event) and `network_userid` (processed event).
|
337
335
|
# @see Subject#set_domain_user_id
|
@@ -38,41 +38,39 @@ module SnowplowTracker
|
|
38
38
|
# DeviceTimestamp by the Tracker, and will still be recorded as `dtm` in
|
39
39
|
# the event.
|
40
40
|
# 2. Manually create a DeviceTimestamp (e.g.
|
41
|
-
# `DeviceTimestamp.new(1633596554978)`), and provide this to the
|
41
|
+
# `SnowplowTracker::DeviceTimestamp.new(1633596554978)`), and provide this to the
|
42
42
|
# `#track_x_event` method. This will still be recorded as `dtm` in the
|
43
43
|
# event.
|
44
44
|
# 3. Provide a TrueTimestamp object to the `track_x_event` method (e.g.
|
45
|
-
# `TrueTimestamp.new(1633596554978)`). This will result in a `ttm` field in
|
45
|
+
# `SnowplowTracker::TrueTimestamp.new(1633596554978)`). This will result in a `ttm` field in
|
46
46
|
# the event.
|
47
47
|
#
|
48
48
|
# The timestamps that are added to the event once it has been emitted are not
|
49
49
|
# the responsibility of this class. The collector receives the event and adds a
|
50
50
|
# `collector_tstamp`. A later part of the pipeline adds the `etl_tstamp` when
|
51
|
-
# the event enrichment has finished.
|
52
|
-
#
|
53
|
-
#
|
54
|
-
#
|
51
|
+
# the event enrichment has finished.
|
52
|
+
#
|
53
|
+
# When DeviceTimestamp is used, a `derived_tstamp` is also calculated and
|
54
|
+
# added to the event. This timestamp attempts to take latency and possible
|
55
|
+
# inaccuracy of the device clock into account. It is calculated by
|
56
|
+
# `collector_tstamp - (dvce_sent_tstamp - dvce_created_tstamp)`. When
|
57
|
+
# TrueTimestamp is used, the `derived_stamp` will be the same as
|
58
|
+
# `true_tstamp`.
|
55
59
|
#
|
56
60
|
# @see
|
57
61
|
# https://docs.snowplowanalytics.com/docs/collecting-data/collecting-from-own-applications/snowplow-tracker-protocol
|
58
62
|
# the Snowplow Tracker Protocol
|
63
|
+
# @see
|
64
|
+
# https://discourse.snowplowanalytics.com/t/which-timestamp-is-the-best-to-see-when-an-event-occurred/538
|
65
|
+
# A Discourse forums post explaining timestamps
|
59
66
|
# @api public
|
60
67
|
class Timestamp
|
61
|
-
include Contracts
|
62
|
-
|
63
68
|
# @private
|
64
69
|
attr_reader :type
|
65
70
|
|
66
71
|
# @private
|
67
72
|
attr_reader :value
|
68
73
|
|
69
|
-
# @private
|
70
|
-
# Contract type
|
71
|
-
TIMESTAMP = ->(x) {
|
72
|
-
return false unless x.is_a? Integer
|
73
|
-
x.to_s.length == 13
|
74
|
-
}
|
75
|
-
|
76
74
|
# @private
|
77
75
|
def initialize(type, value)
|
78
76
|
@type = type
|
@@ -92,10 +90,9 @@ module SnowplowTracker
|
|
92
90
|
# it is, namely `ttm`. This raw event `ttm` field will be processed into
|
93
91
|
# `true_tstamp` in the completed event.
|
94
92
|
class TrueTimestamp < Timestamp
|
95
|
-
Contract TIMESTAMP => Any
|
96
93
|
# @param [Num] value timestamp in milliseconds since the Unix epoch
|
97
94
|
# @example
|
98
|
-
# TrueTimestamp.new(1633596346786)
|
95
|
+
# SnowplowTracker::TrueTimestamp.new(1633596346786)
|
99
96
|
def initialize(value)
|
100
97
|
super 'ttm', value
|
101
98
|
end
|
@@ -107,10 +104,9 @@ module SnowplowTracker
|
|
107
104
|
# it is, namely `dtm`. This raw event `dtm` field will be processed into
|
108
105
|
# `dvce_created_tstamp` in the completed event.
|
109
106
|
class DeviceTimestamp < Timestamp
|
110
|
-
Contract TIMESTAMP => Any
|
111
107
|
# @param [Num] value timestamp in milliseconds since the Unix epoch
|
112
108
|
# @example
|
113
|
-
# DeviceTimestamp.new(1633596346786)
|
109
|
+
# SnowplowTracker::DeviceTimestamp.new(1633596346786)
|
114
110
|
def initialize(value)
|
115
111
|
super 'dtm', value
|
116
112
|
end
|
@@ -14,7 +14,6 @@
|
|
14
14
|
# License:: Apache License Version 2.0
|
15
15
|
|
16
16
|
|
17
|
-
require 'contracts'
|
18
17
|
require 'securerandom'
|
19
18
|
require 'set'
|
20
19
|
|
@@ -118,62 +117,16 @@ module SnowplowTracker
|
|
118
117
|
# https://docs.snowplowanalytics.com/docs/collecting-data/collecting-from-own-applications/snowplow-tracker-protocol
|
119
118
|
# the Snowplow Tracker Protocol
|
120
119
|
# @see
|
120
|
+
# https://docs.snowplowanalytics.com/docs/collecting-data/collecting-from-own-applications/ruby-tracker/tracking-events/
|
121
|
+
# the Snowplow docs page about tracking events
|
122
|
+
# @see
|
123
|
+
# https://docs.snowplowanalytics.com/docs/collecting-data/collecting-from-own-applications/ruby-tracker/enriching-your-events/
|
124
|
+
# the Snowplow docs page about adding context and other extra data to events
|
125
|
+
# @see
|
121
126
|
# https://docs.snowplowanalytics.com/docs/understanding-tracking-design/introduction-to-tracking-design/
|
122
127
|
# introduction to Snowplow tracking design
|
123
128
|
# @api public
|
124
129
|
class Tracker
|
125
|
-
include Contracts
|
126
|
-
|
127
|
-
# Contract types
|
128
|
-
|
129
|
-
# @private
|
130
|
-
EMITTER_INPUT = Or[->(x) { x.is_a? Emitter }, ArrayOf[->(x) { x.is_a? Emitter }]]
|
131
|
-
|
132
|
-
# @private
|
133
|
-
REQUIRED_TRANSACTION_KEYS = Set.new(%w[order_id total_value])
|
134
|
-
# @private
|
135
|
-
RECOGNISED_TRANSACTION_KEYS = Set.new(%w[
|
136
|
-
order_id total_value affiliation tax_value
|
137
|
-
shipping city state country currency
|
138
|
-
])
|
139
|
-
|
140
|
-
# @private
|
141
|
-
TRANSACTION = ->(x) {
|
142
|
-
return false unless x.class == Hash
|
143
|
-
transaction_keys = Set.new(x.keys.map(&:to_s))
|
144
|
-
REQUIRED_TRANSACTION_KEYS.subset?(transaction_keys) &&
|
145
|
-
transaction_keys.subset?(RECOGNISED_TRANSACTION_KEYS)
|
146
|
-
}
|
147
|
-
# @private
|
148
|
-
REQUIRED_ITEM_KEYS = Set.new(%w[sku price quantity])
|
149
|
-
# @private
|
150
|
-
RECOGNISED_ITEM_KEYS = Set.new(%w[sku price quantity name category context])
|
151
|
-
|
152
|
-
# @private
|
153
|
-
ITEM = ->(x) {
|
154
|
-
return false unless x.class == Hash
|
155
|
-
item_keys = Set.new(x.keys.map(&:to_s))
|
156
|
-
REQUIRED_ITEM_KEYS.subset?(item_keys) &&
|
157
|
-
item_keys.subset?(RECOGNISED_ITEM_KEYS)
|
158
|
-
}
|
159
|
-
# @private
|
160
|
-
REQUIRED_AUGMENTED_ITEM_KEYS = Set.new(%w[sku price quantity tstamp order_id])
|
161
|
-
# @private
|
162
|
-
RECOGNISED_AUGMENTED_ITEM_KEYS = Set.new(%w[sku price quantity name category context tstamp order_id currency])
|
163
|
-
|
164
|
-
# @private
|
165
|
-
AUGMENTED_ITEM = ->(x) {
|
166
|
-
return false unless x.class == Hash
|
167
|
-
augmented_item_keys = Set.new(x.keys)
|
168
|
-
REQUIRED_AUGMENTED_ITEM_KEYS.subset?(augmented_item_keys) &&
|
169
|
-
augmented_item_keys.subset?(RECOGNISED_AUGMENTED_ITEM_KEYS)
|
170
|
-
}
|
171
|
-
|
172
|
-
# @private
|
173
|
-
CONTEXTS_INPUT = ArrayOf[SelfDescribingJson]
|
174
|
-
|
175
|
-
# Other constants
|
176
|
-
|
177
130
|
# @!group Public constants
|
178
131
|
|
179
132
|
# SelfDescribingJson objects are sent encoded by default
|
@@ -192,8 +145,6 @@ module SnowplowTracker
|
|
192
145
|
|
193
146
|
# @!endgroup
|
194
147
|
|
195
|
-
Contract KeywordArgs[emitters: EMITTER_INPUT, subject: Maybe[Subject], namespace: Maybe[String],
|
196
|
-
app_id: Maybe[String], encode_base64: Optional[Bool]] => Any
|
197
148
|
# Create a new Tracker. `emitters` is the only strictly required parameter.
|
198
149
|
#
|
199
150
|
# @param emitters [Emitter, Array<Emitter>] one or more Emitter objects
|
@@ -202,14 +153,18 @@ module SnowplowTracker
|
|
202
153
|
# @param app_id [String] the app ID
|
203
154
|
# @param encode_base64 [Bool] whether JSONs will be base64-encoded or not
|
204
155
|
# @example Initializing a Tracker with all possible options
|
205
|
-
# Tracker.new(
|
206
|
-
# emitters: Emitter.new('collector.example.com'),
|
207
|
-
# subject: Subject.new,
|
156
|
+
# SnowplowTracker::Tracker.new(
|
157
|
+
# emitters: SnowplowTracker::Emitter.new(endpoint: 'collector.example.com'),
|
158
|
+
# subject: SnowplowTracker::Subject.new,
|
208
159
|
# namespace: 'tracker_no_encode',
|
209
160
|
# app_id: 'rails_main',
|
210
161
|
# encode_base64: false
|
211
162
|
# )
|
212
163
|
# @api public
|
164
|
+
#
|
165
|
+
# @note All the Tracker instance methods return the Tracker object, allowing
|
166
|
+
# method chaining, e.g.
|
167
|
+
# `SnowplowTracker::Tracker.new.set_user_id('12345').track_page_view(page_url: 'www.example.com`
|
213
168
|
def initialize(emitters:, subject: nil, namespace: nil, app_id: nil, encode_base64: DEFAULT_ENCODE_BASE64)
|
214
169
|
@emitters = Array(emitters)
|
215
170
|
@subject = if subject.nil?
|
@@ -269,14 +224,12 @@ module SnowplowTracker
|
|
269
224
|
end
|
270
225
|
end
|
271
226
|
|
272
|
-
Contract nil => String
|
273
227
|
# Generates a type-4 UUID to identify this event
|
274
228
|
# @private
|
275
229
|
def event_id
|
276
230
|
SecureRandom.uuid
|
277
231
|
end
|
278
232
|
|
279
|
-
Contract CONTEXTS_INPUT => Hash
|
280
233
|
# Builds a single self-describing JSON from an array of custom contexts
|
281
234
|
# @private
|
282
235
|
def build_context(context)
|
@@ -286,7 +239,6 @@ module SnowplowTracker
|
|
286
239
|
).to_json
|
287
240
|
end
|
288
241
|
|
289
|
-
Contract Payload => nil
|
290
242
|
# Sends the payload hash as a request to the Emitter(s)
|
291
243
|
# @private
|
292
244
|
def track(payload)
|
@@ -295,7 +247,6 @@ module SnowplowTracker
|
|
295
247
|
nil
|
296
248
|
end
|
297
249
|
|
298
|
-
Contract Or[Timestamp, Num, nil] => Timestamp
|
299
250
|
# Ensures that either a DeviceTimestamp or TrueTimestamp is associated with
|
300
251
|
# every event.
|
301
252
|
# @private
|
@@ -305,7 +256,6 @@ module SnowplowTracker
|
|
305
256
|
tstamp
|
306
257
|
end
|
307
258
|
|
308
|
-
Contract Payload, Maybe[CONTEXTS_INPUT], Timestamp, Maybe[Subject], Maybe[Page] => nil
|
309
259
|
# Attaches the more generic fields to the event payload. This includes
|
310
260
|
# context, Subject, and Page if they are present. The timestamp is added, as
|
311
261
|
# well as all fields from `@settings`.
|
@@ -329,10 +279,11 @@ module SnowplowTracker
|
|
329
279
|
nil
|
330
280
|
end
|
331
281
|
|
332
|
-
Contract KeywordArgs[page_url: String, page_title: Maybe[String], referrer: Maybe[String],
|
333
|
-
context: Maybe[CONTEXTS_INPUT], tstamp: Or[Timestamp, Num, nil],
|
334
|
-
subject: Maybe[Subject], page: Maybe[Page]] => Tracker
|
335
282
|
# Track a visit to a page.
|
283
|
+
# @example
|
284
|
+
# SnowplowTracker::Tracker.new.track_page_view(page_url: 'www.example.com',
|
285
|
+
# page_title: 'example',
|
286
|
+
# referrer: 'www.referrer.com')
|
336
287
|
#
|
337
288
|
# @param page_url [String] the URL of the page
|
338
289
|
# @param page_title [String] the page title
|
@@ -359,9 +310,6 @@ module SnowplowTracker
|
|
359
310
|
self
|
360
311
|
end
|
361
312
|
|
362
|
-
Contract KeywordArgs[transaction: TRANSACTION, items: ArrayOf[ITEM],
|
363
|
-
context: Maybe[CONTEXTS_INPUT], tstamp: Or[Timestamp, Num, nil],
|
364
|
-
subject: Maybe[Subject], page: Maybe[Page]] => Tracker
|
365
313
|
# Track an eCommerce transaction, and all the items in it.
|
366
314
|
#
|
367
315
|
# This method is unique in sending multiple events: one `transaction` event,
|
@@ -482,7 +430,6 @@ module SnowplowTracker
|
|
482
430
|
hash.keys.each { |key| hash[key.to_s] = hash.delete key }
|
483
431
|
end
|
484
432
|
|
485
|
-
Contract AUGMENTED_ITEM, Maybe[Subject], Maybe[Page] => self
|
486
433
|
# Track a single item within an ecommerce transaction.
|
487
434
|
# @private
|
488
435
|
def track_ecommerce_transaction_item(details, subject, page)
|
@@ -502,10 +449,6 @@ module SnowplowTracker
|
|
502
449
|
self
|
503
450
|
end
|
504
451
|
|
505
|
-
Contract KeywordArgs[category: String, action: String, label: Maybe[String],
|
506
|
-
property: Maybe[String], value: Maybe[Num],
|
507
|
-
context: Maybe[CONTEXTS_INPUT], tstamp: Or[Timestamp, Num, nil],
|
508
|
-
subject: Maybe[Subject], page: Maybe[Page]] => Tracker
|
509
452
|
# Track a structured event. `category` and `action` are required.
|
510
453
|
#
|
511
454
|
# This event type can be used to track many types of user activity, as it is
|
@@ -516,6 +459,15 @@ module SnowplowTracker
|
|
516
459
|
# For fully customizable event tracking, we recommend you use
|
517
460
|
# self-describing events.
|
518
461
|
#
|
462
|
+
# @example
|
463
|
+
# SnowplowTracker::Tracker.new.track_struct_event(
|
464
|
+
# category: 'shop',
|
465
|
+
# action: 'add-to-basket',
|
466
|
+
# property: 'pcs',
|
467
|
+
# value: 2
|
468
|
+
# )
|
469
|
+
#
|
470
|
+
#
|
519
471
|
# @see #track_self_describing_event
|
520
472
|
#
|
521
473
|
# @param category [String] the event category
|
@@ -547,9 +499,6 @@ module SnowplowTracker
|
|
547
499
|
self
|
548
500
|
end
|
549
501
|
|
550
|
-
Contract KeywordArgs[name: Maybe[String], id: Maybe[String],
|
551
|
-
context: Maybe[CONTEXTS_INPUT], tstamp: Or[Timestamp, Num, nil],
|
552
|
-
subject: Maybe[Subject], page: Maybe[Page]] => Tracker
|
553
502
|
# Track a screen view event. Note that while the `name` and `id` parameters
|
554
503
|
# are both optional, you must provided at least one of them to create a
|
555
504
|
# valid event.
|
@@ -560,6 +509,11 @@ module SnowplowTracker
|
|
560
509
|
# "iglu:com.snowplowanalytics.snowplow/screen_view/jsonschema/1-0-0", and
|
561
510
|
# the data field will contain the name and/or ID.
|
562
511
|
#
|
512
|
+
# @example
|
513
|
+
# SnowplowTracker::Tracker.new.track_screen_view(name: 'HUD > Save Game',
|
514
|
+
# id: 'screen23')
|
515
|
+
#
|
516
|
+
#
|
563
517
|
# @see #track_page_view
|
564
518
|
# @see #track_self_describing_event
|
565
519
|
#
|
@@ -583,9 +537,6 @@ module SnowplowTracker
|
|
583
537
|
self
|
584
538
|
end
|
585
539
|
|
586
|
-
Contract KeywordArgs[event_json: SelfDescribingJson, context: Maybe[CONTEXTS_INPUT],
|
587
|
-
tstamp: Or[Timestamp, Num, nil], subject: Maybe[Subject],
|
588
|
-
page: Maybe[Page]] => Tracker
|
589
540
|
# Track a self-describing event. These are custom events based on
|
590
541
|
# {SelfDescribingJson}, i.e. a JSON schema and a defined set of properties.
|
591
542
|
#
|
@@ -595,6 +546,20 @@ module SnowplowTracker
|
|
595
546
|
# This method creates an `unstruct` event type. It is actually an alias for
|
596
547
|
# {#track_unstruct_event}, which is depreciated due to its unhelpful name.
|
597
548
|
#
|
549
|
+
# @example
|
550
|
+
# self_desc_json = SnowplowTracker::SelfDescribingJson.new(
|
551
|
+
# "iglu:com.example_company/save_game/jsonschema/1-0-2",
|
552
|
+
# {
|
553
|
+
# "saveId" => "4321",
|
554
|
+
# "level" => 23,
|
555
|
+
# "difficultyLevel" => "HARD",
|
556
|
+
# "dlContent" => true
|
557
|
+
# }
|
558
|
+
# )
|
559
|
+
#
|
560
|
+
# SnowplowTracker::Tracker.new.track_self_describing_event(event_json: self_desc_json)
|
561
|
+
#
|
562
|
+
#
|
598
563
|
# @param event_json [SelfDescribingJson] a SelfDescribingJson object
|
599
564
|
# @param context [Array<SelfDescribingJson>] an array of SelfDescribingJson objects
|
600
565
|
# @param tstamp [DeviceTimestamp, TrueTimestamp, Num] override the default DeviceTimestamp of the event
|
@@ -607,9 +572,6 @@ module SnowplowTracker
|
|
607
572
|
tstamp: tstamp, subject: subject, page: page)
|
608
573
|
end
|
609
574
|
|
610
|
-
Contract KeywordArgs[event_json: SelfDescribingJson, context: Maybe[CONTEXTS_INPUT],
|
611
|
-
tstamp: Or[Timestamp, Num, nil], subject: Maybe[Subject],
|
612
|
-
page: Maybe[Page]] => Tracker
|
613
575
|
# @deprecated Use {#track_self_describing_event} instead.
|
614
576
|
#
|
615
577
|
# @api public
|
@@ -628,7 +590,6 @@ module SnowplowTracker
|
|
628
590
|
self
|
629
591
|
end
|
630
592
|
|
631
|
-
Contract KeywordArgs[async: Optional[Bool]] => Tracker
|
632
593
|
# Manually flush all events stored in all Tracker-associated Emitters. By
|
633
594
|
# default, this happens synchronously. {Emitter}s can only send events
|
634
595
|
# synchronously, while {AsyncEmitter}s can send either synchronously or
|
@@ -645,7 +606,6 @@ module SnowplowTracker
|
|
645
606
|
self
|
646
607
|
end
|
647
608
|
|
648
|
-
Contract Subject => Tracker
|
649
609
|
# Replace the existing Tracker-associated Subject with the provided one. All
|
650
610
|
# subsequent events will have the properties of the new Subject, unless they
|
651
611
|
# are overriden by event-specific Subject parameters.
|
@@ -658,7 +618,6 @@ module SnowplowTracker
|
|
658
618
|
self
|
659
619
|
end
|
660
620
|
|
661
|
-
Contract Emitter => Tracker
|
662
621
|
# Add a new Emitter to the internal array of Tracker-associated Emitters.
|
663
622
|
#
|
664
623
|
# @param emitter [Emitter] an Emitter object
|
@@ -24,13 +24,6 @@
|
|
24
24
|
# see an example of how to incorporate the Snowplow Ruby tracker in Ruby on
|
25
25
|
# Rails app.
|
26
26
|
#
|
27
|
-
# # Type checking
|
28
|
-
#
|
29
|
-
# This gem uses the [Contracts](https://github.com/egonSchiele/contracts.ruby)
|
30
|
-
# gem for typechecking. This cannot be disabled. The {Tracker} `track_x_event`
|
31
|
-
# methods expect arguments of a certain type. If a check fails, a runtime error
|
32
|
-
# is thrown.
|
33
|
-
#
|
34
27
|
# @see https://github.com/snowplow/snowplow-ruby-tracker
|
35
28
|
# Ruby tracker on Github
|
36
29
|
# @see https://github.com/snowplow-incubator/snowplow-ruby-tracker-examples
|
@@ -41,7 +34,7 @@
|
|
41
34
|
# @api public
|
42
35
|
module SnowplowTracker
|
43
36
|
# The version of Ruby Snowplow tracker you are using
|
44
|
-
VERSION = '0.
|
37
|
+
VERSION = '0.8.0'
|
45
38
|
|
46
39
|
# All events from this tracker will have this string
|
47
40
|
TRACKER_VERSION = "rb-#{VERSION}"
|
metadata
CHANGED
@@ -1,35 +1,15 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: snowplow-tracker
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.8.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Snowplow Analytics Ltd
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-10-
|
11
|
+
date: 2021-10-29 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
|
-
- !ruby/object:Gem::Dependency
|
14
|
-
name: contracts
|
15
|
-
requirement: !ruby/object:Gem::Requirement
|
16
|
-
requirements:
|
17
|
-
- - "~>"
|
18
|
-
- !ruby/object:Gem::Version
|
19
|
-
version: '0.7'
|
20
|
-
- - "<"
|
21
|
-
- !ruby/object:Gem::Version
|
22
|
-
version: '0.17'
|
23
|
-
type: :runtime
|
24
|
-
prerelease: false
|
25
|
-
version_requirements: !ruby/object:Gem::Requirement
|
26
|
-
requirements:
|
27
|
-
- - "~>"
|
28
|
-
- !ruby/object:Gem::Version
|
29
|
-
version: '0.7'
|
30
|
-
- - "<"
|
31
|
-
- !ruby/object:Gem::Version
|
32
|
-
version: '0.17'
|
33
13
|
- !ruby/object:Gem::Dependency
|
34
14
|
name: rspec
|
35
15
|
requirement: !ruby/object:Gem::Requirement
|