snowplow-tracker 0.7.0 → 0.8.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|