snowplow-tracker 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- NmI4MjYwZDE5ZGEyNjA0MTJkNTA1ZTdkYWU3MDRlOWNjZjEyNGI1NQ==
4
+ MTZkNTg1MGZiZTIyNzY0NmY4ZTk2ZDYxMjVkMTU3ZmJkZDllODlkMA==
5
5
  data.tar.gz: !binary |-
6
- MjhiYjIxZWY4OGVhMmI2ODEzODY0NzQzYThhODNhMDY1YzE2Y2IwMA==
6
+ YTQ5ZDhhYTFiNmJlODI4YTMyNTg1YWIwODQ3ZWJmMzNkZDk4MmE1YQ==
7
7
  SHA512:
8
8
  metadata.gz: !binary |-
9
- M2Q0MzY5MzUyZjRhZGJkOTc2YzYyYTNmYmEzZDc5YjY1OTQyZjRjOTc5M2Q4
10
- NTViOGZjOTUxZmVlMDI4NTJkOTFmZmVjMmQyYjE5NjdiZTc2NzZlZTY3YmUx
11
- NjUwNTg4ZjNmYzQxMGUwOTE4YWE4NTEzMDM0ZDBlODJhOWI3M2E=
9
+ ODhmY2ZmMmNjMTA2MzNmZTg2OGEzNDRhODVkZjc3YjY0NGI5NzAyZjUwNjc2
10
+ MDFmYzZhYjNmZjg4ZmIwZTA4MmFlOTI5NmZlODljYjAwNWQ1OGVlZGFmOTFl
11
+ ZjhhOTVjNGE3NzY2ZTViMjE2OTI0YmUzYTg1Zjg2OWJkZWJkNjU=
12
12
  data.tar.gz: !binary |-
13
- ZWRjZWRmNjRkZDlkMjNjMjlmNDU4ZWY0NzBmM2Q0OGM0NDZmNDU2YjRiOTA0
14
- NjZlYTE2N2M5NWU4MjE1MzkyYzE2NzhiYmE1OGZjMTQ5NTNlZjZjOGZmNjk4
15
- NDQ5NzRiYTAxNDVmOWNkOTJhMDIwNmE3MzdlY2I4Y2E3ZmQ1MzM=
13
+ Y2UyMTIwOWRhNWYxNTkxZTAxYjgxMTFhMjMzMWMxYjc0MDYyNTNkMTZiYmNk
14
+ MGU2MjQ0MzU2ODAyNGZhZjk0YmIxYTNhOWI5MjhhNzFmNGYyMTdmZGM4Mzlh
15
+ OTg4MDUyZTNiY2NmN2Q1MjZjNmEwMGM0MDQ1YTQ3MWEyMzJkM2Q=
data/README.md CHANGED
@@ -30,9 +30,9 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
30
30
  See the License for the specific language governing permissions and
31
31
  limitations under the License.
32
32
 
33
- [ruby]: xxx
34
- [rails]: xxx
35
- [rubygems]: xxx
33
+ [ruby]: https://www.ruby-lang.org/en/
34
+ [rails]: http://rubyonrails.org/
35
+ [rubygems]: https://rubygems.org/
36
36
 
37
37
  [snowplow]: http://snowplowanalytics.com
38
38
 
@@ -1,4 +1,4 @@
1
- # Copyright (c) 2013-2014 SnowPlow Analytics Ltd. All rights reserved.
1
+ # Copyright (c) 2013-2014 Snowplow Analytics Ltd. All rights reserved.
2
2
  #
3
3
  # This program is licensed to you under the Apache License Version 2.0,
4
4
  # and you may not use this file except in compliance with the Apache License Version 2.0.
@@ -10,7 +10,7 @@
10
10
  # See the Apache License Version 2.0 for the specific language governing permissions and limitations there under.
11
11
 
12
12
  # Author:: Alex Dean, Fred Blundun (mailto:support@snowplowanalytics.com)
13
- # Copyright:: Copyright (c) 2013-2014 SnowPlow Analytics Ltd
13
+ # Copyright:: Copyright (c) 2013-2014 Snowplow Analytics Ltd
14
14
  # License:: Apache License Version 2.0
15
15
 
16
16
  require 'base64'
@@ -1,4 +1,4 @@
1
- # Copyright (c) 2013-2014 SnowPlow Analytics Ltd. All rights reserved.
1
+ # Copyright (c) 2013-2014 Snowplow Analytics Ltd. All rights reserved.
2
2
  #
3
3
  # This program is licensed to you under the Apache License Version 2.0,
4
4
  # and you may not use this file except in compliance with the Apache License Version 2.0.
@@ -10,7 +10,7 @@
10
10
  # See the Apache License Version 2.0 for the specific language governing permissions and limitations there under.
11
11
 
12
12
  # Author:: Alex Dean, Fred Blundun (mailto:support@snowplowanalytics.com)
13
- # Copyright:: Copyright (c) 2013-2014 SnowPlow Analytics Ltd
13
+ # Copyright:: Copyright (c) 2013-2014 Snowplow Analytics Ltd
14
14
  # License:: Apache License Version 2.0
15
15
 
16
16
  require 'net/http'
@@ -18,13 +18,15 @@ require 'contracts'
18
18
  require 'set'
19
19
  include Contracts
20
20
 
21
+ require 'uuid'
22
+
21
23
  module SnowplowTracker
22
24
 
23
25
  class Tracker
24
26
 
25
27
  @@required_transaction_keys = Set.new(%w(order_id total_value))
26
28
  @@recognised_transaction_keys = Set.new(%w(order_id total_value affiliation tax_value shipping city state country currency))
27
-
29
+
28
30
  @@Transaction = lambda { |x|
29
31
  return false unless x.class == Hash
30
32
  transaction_keys = Set.new(x.keys)
@@ -42,8 +44,8 @@ module SnowplowTracker
42
44
  item_keys.subset? @@recognised_item_keys
43
45
  }
44
46
 
45
- @@required_augmented_item_keys = Set.new(%w(sku price quantity tstamp tid order_id))
46
- @@recognised_augmented_item_keys = Set.new(%w(sku price quantity name category context tstamp tid order_id currency))
47
+ @@required_augmented_item_keys = Set.new(%w(sku price quantity tstamp order_id))
48
+ @@recognised_augmented_item_keys = Set.new(%w(sku price quantity name category context tstamp order_id currency))
47
49
 
48
50
  @@AugmentedItem = lambda { |x|
49
51
  return false unless x.class == Hash
@@ -52,17 +54,31 @@ module SnowplowTracker
52
54
  augmented_item_keys.subset? @@recognised_augmented_item_keys
53
55
  }
54
56
 
57
+ @@SelfDescribingJson = Or[{
58
+ schema: String,
59
+ data: Any
60
+ }, {
61
+ 'schema' => String,
62
+ 'data' => Any
63
+ }]
64
+
65
+ @@ContextsInput = ArrayOf[@@SelfDescribingJson]
66
+
55
67
  @@version = TRACKER_VERSION
56
68
  @@default_encode_base64 = true
57
69
  @@default_platform = 'pc'
58
- @@default_vendor = 'com.snowplowanalytics'
59
70
  @@supported_platforms = ['pc', 'tv', 'mob', 'cnsl', 'iot']
60
71
  @@http_errors = ['host not found',
61
72
  'No address associated with name',
62
73
  'No address associated with hostname']
63
74
 
64
- Contract String, Maybe[String], Maybe[String], Maybe[String], Bool => Tracker
65
- def initialize(endpoint, namespace=nil, app_id=nil, context_vendor=nil, encode_base64=@@default_encode_base64)
75
+ @@base_schema_path = "iglu:com.snowplowanalytics.snowplow"
76
+ @@schema_tag = "jsonschema"
77
+ @@context_schema = "#{@@base_schema_path}/contexts/#{@@schema_tag}/1-0-0"
78
+ @@unstruct_event_schema = "#{@@base_schema_path}/unstruct_event/#{@@schema_tag}/1-0-0"
79
+
80
+ Contract String, Maybe[String], Maybe[String], Bool => Tracker
81
+ def initialize(endpoint, namespace=nil, app_id=nil, encode_base64=@@default_encode_base64)
66
82
  @collector_uri = as_collector_uri(endpoint)
67
83
  @standard_nv_pairs = {
68
84
  'tna' => namespace,
@@ -71,9 +87,9 @@ module SnowplowTracker
71
87
  'aid' => app_id
72
88
  }
73
89
  @config = {
74
- 'context_vendor' => context_vendor,
75
90
  'encode_base64' => encode_base64
76
91
  }
92
+ @uuid = UUID.new
77
93
  self
78
94
  end
79
95
 
@@ -84,11 +100,10 @@ module SnowplowTracker
84
100
  "http://#{host}/i"
85
101
  end
86
102
 
87
- # Randomly generates a hopefully unique internal transaction ID for each event
88
- #
89
- Contract nil => Num
90
- def get_transaction_id
91
- rand(100000..999999)
103
+ # Generates a type-4 UUID to identify this event
104
+ Contract nil => String
105
+ def get_event_id()
106
+ @uuid.generate
92
107
  end
93
108
 
94
109
  # Generates the timestamp (in milliseconds) to be attached to each event
@@ -98,6 +113,16 @@ module SnowplowTracker
98
113
  (Time.now.to_f * 1000).to_i
99
114
  end
100
115
 
116
+ # Builds a self-describing JSON from an array of custom contexts
117
+ #
118
+ Contract @@ContextsInput => @@SelfDescribingJson
119
+ def build_context(context)
120
+ {
121
+ schema: @@context_schema,
122
+ data: context
123
+ }
124
+ end
125
+
101
126
  # Send request
102
127
  #
103
128
  Contract Payload => [Bool, Num]
@@ -116,7 +141,7 @@ module SnowplowTracker
116
141
  # Setter methods
117
142
 
118
143
  # Specify the platform
119
- #
144
+ #
120
145
  Contract String => String
121
146
  def set_platform(value)
122
147
  if @@supported_platforms.include?(value)
@@ -141,7 +166,7 @@ module SnowplowTracker
141
166
  end
142
167
 
143
168
  # Set the dimensions of the current viewport
144
- #
169
+ #
145
170
  Contract Num, Num => String
146
171
  def set_viewport(width, height)
147
172
  @standard_nv_pairs['vp'] = "#{width}x#{height}"
@@ -176,25 +201,24 @@ module SnowplowTracker
176
201
  Contract Payload => [Bool, Num]
177
202
  def track(pb)
178
203
  pb.add_dict(@standard_nv_pairs)
179
- if pb.context.key? 'co' or pb.context.key? 'cx'
180
- pb.add('cv', @config['context_vendor'])
181
- end
204
+ pb.add('eid', get_event_id())
205
+
182
206
  http_get(pb)
183
207
  end
184
208
 
185
209
  # Log a visit to this page
186
210
  #
187
- Contract String, Maybe[String], Maybe[String], Maybe[Hash] => [Bool, Num]
211
+ Contract String, Maybe[String], Maybe[String], Maybe[@@ContextsInput] => [Bool, Num]
188
212
  def track_page_view(page_url, page_title=nil, referrer=nil, context=nil, tstamp=nil)
189
213
  pb = Payload.new
190
214
  pb.add('e', 'pv')
191
215
  pb.add('url', page_url)
192
216
  pb.add('page', page_title)
193
217
  pb.add('refr', referrer)
194
- pb.add('evn', @@default_vendor)
195
- pb.add_json(context, @config['encode_base64'], 'cx', 'co')
196
- tid = get_transaction_id
197
- pb.add('tid', tid)
218
+ unless context.nil?
219
+ pb.add_json(build_context(context), @config['encode_base64'], 'cx', 'co')
220
+ end
221
+
198
222
  if tstamp.nil?
199
223
  tstamp = get_timestamp
200
224
  end
@@ -216,16 +240,16 @@ module SnowplowTracker
216
240
  pb.add('ti_nm', argmap['name'])
217
241
  pb.add('ti_ca', argmap['category'])
218
242
  pb.add('ti_cu', argmap['currency'])
219
- pb.add('evn', @default_vendor)
220
- pb.add_json(argmap['context'], @config['encode_base64'], 'cx', 'co')
221
- pb.add('tid', argmap['tid'])
243
+ unless argmap['context'].nil?
244
+ pb.add_json(build_context(argmap['context']), @config['encode_base64'], 'cx', 'co')
245
+ end
222
246
  pb.add('dtm', argmap['tstamp'])
223
247
  track(pb)
224
248
  end
225
249
 
226
250
  # Track an ecommerce transaction and all the items in it
227
251
  #
228
- Contract @@Transaction, ArrayOf[@@Item], Maybe[Hash], Maybe[Num] => ({'transaction_result' => [Bool, Num], 'item_results' => ArrayOf[[Bool, Num]]})
252
+ Contract @@Transaction, ArrayOf[@@Item], Maybe[@@ContextsInput], Maybe[Num] => ({'transaction_result' => [Bool, Num], 'item_results' => ArrayOf[[Bool, Num]]})
229
253
  def track_ecommerce_transaction(transaction, items,
230
254
  context=nil, tstamp=nil)
231
255
  pb = Payload.new
@@ -239,10 +263,10 @@ module SnowplowTracker
239
263
  pb.add('tr_st', transaction['state'])
240
264
  pb.add('tr_co', transaction['country'])
241
265
  pb.add('tr_cu', transaction['currency'])
242
- pb.add('evn', @@default_vendor)
243
- pb.add_json(context, @config['encode_base64'], 'cx', 'co')
244
- tid = get_transaction_id
245
- pb.add('tid', tid)
266
+ unless context.nil?
267
+ pb.add_json(build_context(context), @config['encode_base64'], 'cx', 'co')
268
+ end
269
+
246
270
  if tstamp.nil?
247
271
  tstamp = get_timestamp
248
272
  end
@@ -253,7 +277,6 @@ module SnowplowTracker
253
277
 
254
278
  for item in items
255
279
  item['tstamp'] = tstamp
256
- item['tid'] = tid
257
280
  item['order_id'] = transaction['order_id']
258
281
  item['currency'] = transaction['currency']
259
282
  item_results.push(track_ecommerce_transaction_item(item))
@@ -264,7 +287,7 @@ module SnowplowTracker
264
287
 
265
288
  # Track a structured event
266
289
  #
267
- Contract String, String, Maybe[String], Maybe[String], Maybe[Num], Maybe[Hash], Maybe[Num] => [Bool, Num]
290
+ Contract String, String, Maybe[String], Maybe[String], Maybe[Num], Maybe[@@ContextsInput], Maybe[Num] => [Bool, Num]
268
291
  def track_struct_event(category, action, label=nil, property=nil, value=nil, context=nil, tstamp=nil)
269
292
  pb = Payload.new
270
293
  pb.add('e', 'se')
@@ -273,9 +296,9 @@ module SnowplowTracker
273
296
  pb.add('se_la', label)
274
297
  pb.add('se_pr', property)
275
298
  pb.add('se_va', value)
276
- pb.add_json(context, @config['encode_base64'], 'cx', 'co')
277
- tid = get_transaction_id
278
- pb.add('tid', tid)
299
+ unless context.nil?
300
+ pb.add_json(build_context(context), @config['encode_base64'], 'cx', 'co')
301
+ end
279
302
  if tstamp.nil?
280
303
  tstamp = get_timestamp
281
304
  end
@@ -285,33 +308,46 @@ module SnowplowTracker
285
308
 
286
309
  # Track a screen view event
287
310
  #
288
- Contract String, Maybe[String], Maybe[Hash], Maybe[Num] => [Bool, Num]
311
+ Contract String, Maybe[String], Maybe[@@ContextsInput], Maybe[Num] => [Bool, Num]
289
312
  def track_screen_view(name, id=nil, context=nil, tstamp=nil)
290
- self.track_unstruct_event('screen_view', {'name' => name, 'id' => id}, @@default_vendor, context, tstamp)
313
+ screen_view_properties = {'name' => name}
314
+ unless id.nil?
315
+ screen_view_properties['id'] = id
316
+ end
317
+ screen_view_schema = "#{@@base_schema_path}/screen_view/#{@@schema_tag}/1-0-0"
318
+ event_json = {schema: screen_view_schema, data: screen_view_properties}
319
+
320
+ self.track_unstruct_event(event_json, context, tstamp)
291
321
  end
292
322
 
293
323
  # Track an unstructured event
294
324
  #
295
- Contract String, Hash, Maybe[String], Maybe[Hash], Maybe[Num] => [Bool, Num]
296
- def track_unstruct_event(event_name, dict, event_vendor=nil, context=nil, tstamp=nil)
325
+ Contract @@SelfDescribingJson, Maybe[@@ContextsInput], Maybe[Num] => [Bool, Num]
326
+ def track_unstruct_event(event_json, context=nil, tstamp=nil)
297
327
  pb = Payload.new
298
328
  pb.add('e', 'ue')
299
- pb.add('ue_na', event_name)
300
- pb.add_json(dict, @config['encode_base64'], 'ue_px', 'ue_pr')
301
- pb.add('evn', event_vendor)
302
- pb.add_json(context, @config['encode_base64'], 'cx', 'co')
303
- tid = get_transaction_id
304
- pb.add('tid', tid)
329
+
330
+ envelope = {
331
+ schema: @@unstruct_event_schema,
332
+ data: event_json
333
+ }
334
+ pb.add_json(envelope, @config['encode_base64'], 'ue_px', 'ue_pr')
335
+
336
+ unless context.nil?
337
+ pb.add_json(build_context(context), @config['encode_base64'], 'cx', 'co')
338
+ end
339
+
305
340
  if tstamp.nil?
306
341
  tstamp = get_timestamp
307
342
  end
308
343
  pb.add('dtm', tstamp)
344
+
309
345
  track(pb)
310
346
  end
311
347
 
312
348
  private :as_collector_uri,
313
- :get_transaction_id,
314
349
  :get_timestamp,
350
+ :build_context,
315
351
  :http_get,
316
352
  :track,
317
353
  :track_ecommerce_transaction_item
@@ -1,4 +1,4 @@
1
- # Copyright (c) 2013-2014 SnowPlow Analytics Ltd. All rights reserved.
1
+ # Copyright (c) 2013-2014 Snowplow Analytics Ltd. All rights reserved.
2
2
  #
3
3
  # This program is licensed to you under the Apache License Version 2.0,
4
4
  # and you may not use this file except in compliance with the Apache License Version 2.0.
@@ -10,10 +10,10 @@
10
10
  # See the Apache License Version 2.0 for the specific language governing permissions and limitations there under.
11
11
 
12
12
  # Author:: Alex Dean, Fred Blundun (mailto:support@snowplowanalytics.com)
13
- # Copyright:: Copyright (c) 2013-2014 SnowPlow Analytics Ltd
13
+ # Copyright:: Copyright (c) 2013-2014 Snowplow Analytics Ltd
14
14
  # License:: Apache License Version 2.0
15
15
 
16
16
  module SnowplowTracker
17
- VERSION = '0.1.0'
17
+ VERSION = '0.2.0'
18
18
  TRACKER_VERSION = "rb-#{VERSION}"
19
19
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: snowplow-tracker
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Alexander Dean
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2014-04-23 00:00:00.000000000 Z
12
+ date: 2014-07-31 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: contracts
@@ -25,6 +25,20 @@ dependencies:
25
25
  - - '='
26
26
  - !ruby/object:Gem::Version
27
27
  version: '0.3'
28
+ - !ruby/object:Gem::Dependency
29
+ name: uuid
30
+ requirement: !ruby/object:Gem::Requirement
31
+ requirements:
32
+ - - ~>
33
+ - !ruby/object:Gem::Version
34
+ version: 2.3.7
35
+ type: :runtime
36
+ prerelease: false
37
+ version_requirements: !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - ~>
40
+ - !ruby/object:Gem::Version
41
+ version: 2.3.7
28
42
  - !ruby/object:Gem::Dependency
29
43
  name: rspec
30
44
  requirement: !ruby/object:Gem::Requirement