analytics-ruby 2.2.6.pre → 2.3.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 16a399d60ac370a68cbb28f5887da70711403133e683d7acfe5db4b6eb8fb78d
4
- data.tar.gz: 02c96de2188fb9b79b4d567c36a61ddf2ce0b62610adb6848a777ad327e47535
3
+ metadata.gz: 783cffe105e269e46ad1a00c48deef3a8259a909ea0c5840a187cd37ec13f00d
4
+ data.tar.gz: d2255cdde8b5ea28ade9b3c4a58459d5488423ad53241d284bf0b3d883e97863
5
5
  SHA512:
6
- metadata.gz: 69d989c8e9483dea80c707ddd4ca456d0d7891cd8b5624056a2131bd006dca153b00e46a22c582e26b0ad94978bd6beca4036a13b9921b1511b4d3ffb76b1339
7
- data.tar.gz: 2c9a86a62efe64cbe7baea4faa9b605e32394b207eac8bd277bf1b3ca420aea6f9e34c7da4d476996f38907d1ca7a0d9e4d3abf2bd5088bd397d94a1db6641cc
6
+ metadata.gz: f81af66cb669884d651cc24972795e72141696b13458786593d82b31f15d5c3589ebf2047e98f1a3d3ec276fc4d7e705436865bd0e349643161bfa7356618b46
7
+ data.tar.gz: 7c477ea2e3cfb3fe4c7540d649c33e2efd906690a32841d1a549820a0575818637611e389f47c3644ec0380dab3cfdf9ebf124b095a29066d7962a5322f2d003
data/bin/analytics CHANGED
@@ -29,6 +29,7 @@ command :send do |c|
29
29
  c.option '--userId=<userId>', String, 'the user id to send the event as'
30
30
  c.option '--anonymousId=<anonymousId>', String, 'the anonymous user id to send the event as'
31
31
  c.option '--context=<context>', 'additional context for the event (JSON-encoded)'
32
+ c.option '--integrations=<integrations>', 'additional integrations for the event (JSON-encoded)'
32
33
 
33
34
  c.option '--event=<event>', String, 'the event name to send with the event'
34
35
  c.option '--properties=<properties>', 'the event properties to send (JSON-encoded)'
@@ -38,6 +39,7 @@ command :send do |c|
38
39
  c.option '--traits=<traits>', 'the identify/group traits to send (JSON-encoded)'
39
40
 
40
41
  c.option '--groupId=<groupId>', String, 'the group id'
42
+ c.option '--previousId=<previousId>', String, 'the previous id'
41
43
 
42
44
  c.action do |args, options|
43
45
  Analytics = Segment::Analytics.new({
@@ -52,7 +54,8 @@ command :send do |c|
52
54
  event: options.event,
53
55
  anonymous_id: options.anonymousId,
54
56
  properties: json_hash(options.properties),
55
- context: json_hash(options.context)
57
+ context: json_hash(options.context),
58
+ integrations: json_hash(options.integrations)
56
59
  })
57
60
  when "page"
58
61
  Analytics.page({
@@ -60,22 +63,25 @@ command :send do |c|
60
63
  anonymous_id: options.anonymousId,
61
64
  name: options.name,
62
65
  properties: json_hash(options.properties),
63
- context: json_hash(options.context)
66
+ context: json_hash(options.context),
67
+ integrations: json_hash(options.integrations)
64
68
  })
65
69
  when "screen"
66
70
  Analytics.screen({
67
71
  user_id: options.userId,
68
72
  anonymous_id: options.anonymousId,
69
- name: option.name,
70
- traits: json_hash(options.traits),
71
- properties: json_hash(option.properties)
73
+ name: options.name,
74
+ properties: json_hash(options.properties),
75
+ context: json_hash(options.context),
76
+ integrations: json_hash(options.integrations)
72
77
  })
73
78
  when "identify"
74
79
  Analytics.identify({
75
80
  user_id: options.userId,
76
81
  anonymous_id: options.anonymousId,
77
82
  traits: json_hash(options.traits),
78
- context: json_hash(options.context)
83
+ context: json_hash(options.context),
84
+ integrations: json_hash(options.integrations)
79
85
  })
80
86
  when "group"
81
87
  Analytics.group({
@@ -83,7 +89,16 @@ command :send do |c|
83
89
  anonymous_id: options.anonymousId,
84
90
  group_id: options.groupId,
85
91
  traits: json_hash(options.traits),
86
- context: json_hash(options.context)
92
+ context: json_hash(options.context),
93
+ integrations: json_hash(options.integrations)
94
+ })
95
+ when "alias"
96
+ Analytics.alias({
97
+ previous_id: options.previousId,
98
+ user_id: options.userId,
99
+ anonymous_id: options.anonymousId,
100
+ context: json_hash(options.context),
101
+ integrations: json_hash(options.integrations)
87
102
  })
88
103
  else
89
104
  raise "Invalid Message Type #{options.type}"
@@ -1,9 +1,10 @@
1
1
  require 'segment/analytics/version'
2
2
  require 'segment/analytics/defaults'
3
3
  require 'segment/analytics/utils'
4
+ require 'segment/analytics/field_parser'
4
5
  require 'segment/analytics/client'
5
6
  require 'segment/analytics/worker'
6
- require 'segment/analytics/request'
7
+ require 'segment/analytics/transport'
7
8
  require 'segment/analytics/response'
8
9
  require 'segment/analytics/logging'
9
10
 
@@ -17,7 +18,7 @@ module Segment
17
18
  # @option options [Boolean] :stub (false) If true, requests don't hit the
18
19
  # server and are stubbed to be successful.
19
20
  def initialize(options = {})
20
- Request.stub = options[:stub] if options.has_key?(:stub)
21
+ Transport.stub = options[:stub] if options.has_key?(:stub)
21
22
  @client = Segment::Analytics::Client.new options
22
23
  end
23
24
 
@@ -23,9 +23,9 @@ module Segment
23
23
  @queue = Queue.new
24
24
  @write_key = opts[:write_key]
25
25
  @max_queue_size = opts[:max_queue_size] || Defaults::Queue::MAX_SIZE
26
- @options = opts
27
26
  @worker_mutex = Mutex.new
28
- @worker = Worker.new(@queue, @write_key, @options)
27
+ @worker = Worker.new(@queue, @write_key, opts)
28
+ @worker_thread = nil
29
29
 
30
30
  check_write_key!
31
31
 
@@ -43,58 +43,32 @@ module Segment
43
43
  end
44
44
  end
45
45
 
46
+ # @!macro common_attrs
47
+ # @option attrs [String] :anonymous_id ID for a user when you don't know
48
+ # who they are yet. (optional but you must provide either an
49
+ # `anonymous_id` or `user_id`)
50
+ # @option attrs [Hash] :context ({})
51
+ # @option attrs [Hash] :integrations What integrations this event
52
+ # goes to (optional)
53
+ # @option attrs [String] :message_id ID that uniquely
54
+ # identifies a message across the API. (optional)
55
+ # @option attrs [Time] :timestamp When the event occurred (optional)
56
+ # @option attrs [String] :user_id The ID for this user in your database
57
+ # (optional but you must provide either an `anonymous_id` or `user_id`)
58
+ # @option attrs [Hash] :options Options such as user traits (optional)
59
+
46
60
  # Tracks an event
47
61
  #
48
62
  # @see https://segment.com/docs/sources/server/ruby/#track
49
63
  #
50
64
  # @param [Hash] attrs
51
- # @option attrs [String] :anonymous_id ID for a user when you don't know
52
- # who they are yet. (optional but you must provide either an
53
- # `anonymous_id` or `user_id`)
54
- # @option attrs [Hash] :context ({})
65
+ #
55
66
  # @option attrs [String] :event Event name
56
- # @option attrs [Hash] :integrations What integrations this event
57
- # goes to (optional)
58
- # @option attrs [Hash] :options Options such as user traits (optional)
59
67
  # @option attrs [Hash] :properties Event properties (optional)
60
- # @option attrs [Time] :timestamp When the event occurred (optional)
61
- # @option attrs [String] :user_id The ID for this user in your database
62
- # (optional but you must provide either an `anonymous_id` or `user_id`)
63
- # @option attrs [String] :message_id ID that uniquely
64
- # identifies a message across the API. (optional)
68
+ # @macro common_attrs
65
69
  def track(attrs)
66
70
  symbolize_keys! attrs
67
- check_user_id! attrs
68
-
69
- event = attrs[:event]
70
- properties = attrs[:properties] || {}
71
- timestamp = attrs[:timestamp] || Time.new
72
- context = attrs[:context] || {}
73
- message_id = attrs[:message_id].to_s if attrs[:message_id]
74
-
75
- check_timestamp! timestamp
76
-
77
- if event.nil? || event.empty?
78
- raise ArgumentError, 'Must supply event as a non-empty string'
79
- end
80
-
81
- raise ArgumentError, 'Properties must be a Hash' unless properties.is_a? Hash
82
- isoify_dates! properties
83
-
84
- add_context context
85
-
86
- enqueue({
87
- :event => event,
88
- :userId => attrs[:user_id],
89
- :anonymousId => attrs[:anonymous_id],
90
- :context => context,
91
- :options => attrs[:options],
92
- :integrations => attrs[:integrations],
93
- :properties => properties,
94
- :messageId => message_id,
95
- :timestamp => datetime_in_iso8601(timestamp),
96
- :type => 'track'
97
- })
71
+ enqueue(FieldParser.parse_for_track(attrs))
98
72
  end
99
73
 
100
74
  # Identifies a user
@@ -102,46 +76,12 @@ module Segment
102
76
  # @see https://segment.com/docs/sources/server/ruby/#identify
103
77
  #
104
78
  # @param [Hash] attrs
105
- # @option attrs [String] :anonymous_id ID for a user when you don't know
106
- # who they are yet. (optional but you must provide either an
107
- # `anonymous_id` or `user_id`)
108
- # @option attrs [Hash] :context ({})
109
- # @option attrs [Hash] :integrations What integrations this event
110
- # goes to (optional)
111
- # @option attrs [Hash] :options Options such as user traits (optional)
112
- # @option attrs [Time] :timestamp When the event occurred (optional)
79
+ #
113
80
  # @option attrs [Hash] :traits User traits (optional)
114
- # @option attrs [String] :user_id The ID for this user in your database
115
- # (optional but you must provide either an `anonymous_id` or `user_id`)
116
- # @option attrs [String] :message_id ID that uniquely identifies a
117
- # message across the API. (optional)
81
+ # @macro common_attrs
118
82
  def identify(attrs)
119
83
  symbolize_keys! attrs
120
- check_user_id! attrs
121
-
122
- traits = attrs[:traits] || {}
123
- timestamp = attrs[:timestamp] || Time.new
124
- context = attrs[:context] || {}
125
- message_id = attrs[:message_id].to_s if attrs[:message_id]
126
-
127
- check_timestamp! timestamp
128
-
129
- raise ArgumentError, 'Must supply traits as a hash' unless traits.is_a? Hash
130
- isoify_dates! traits
131
-
132
- add_context context
133
-
134
- enqueue({
135
- :userId => attrs[:user_id],
136
- :anonymousId => attrs[:anonymous_id],
137
- :integrations => attrs[:integrations],
138
- :context => context,
139
- :traits => traits,
140
- :options => attrs[:options],
141
- :messageId => message_id,
142
- :timestamp => datetime_in_iso8601(timestamp),
143
- :type => 'identify'
144
- })
84
+ enqueue(FieldParser.parse_for_identify(attrs))
145
85
  end
146
86
 
147
87
  # Aliases a user from one id to another
@@ -149,39 +89,12 @@ module Segment
149
89
  # @see https://segment.com/docs/sources/server/ruby/#alias
150
90
  #
151
91
  # @param [Hash] attrs
152
- # @option attrs [Hash] :context ({})
153
- # @option attrs [Hash] :integrations What integrations this must be
154
- # sent to (optional)
155
- # @option attrs [Hash] :options Options such as user traits (optional)
92
+ #
156
93
  # @option attrs [String] :previous_id The ID to alias from
157
- # @option attrs [Time] :timestamp When the alias occurred (optional)
158
- # @option attrs [String] :user_id The ID to alias to
159
- # @option attrs [String] :message_id ID that uniquely identifies a
160
- # message across the API. (optional)
94
+ # @macro common_attrs
161
95
  def alias(attrs)
162
96
  symbolize_keys! attrs
163
-
164
- from = attrs[:previous_id]
165
- to = attrs[:user_id]
166
- timestamp = attrs[:timestamp] || Time.new
167
- context = attrs[:context] || {}
168
- message_id = attrs[:message_id].to_s if attrs[:message_id]
169
-
170
- check_presence! from, 'previous_id'
171
- check_presence! to, 'user_id'
172
- check_timestamp! timestamp
173
- add_context context
174
-
175
- enqueue({
176
- :previousId => from,
177
- :userId => to,
178
- :integrations => attrs[:integrations],
179
- :context => context,
180
- :options => attrs[:options],
181
- :messageId => message_id,
182
- :timestamp => datetime_in_iso8601(timestamp),
183
- :type => 'alias'
184
- })
97
+ enqueue(FieldParser.parse_for_alias(attrs))
185
98
  end
186
99
 
187
100
  # Associates a user identity with a group.
@@ -189,48 +102,13 @@ module Segment
189
102
  # @see https://segment.com/docs/sources/server/ruby/#group
190
103
  #
191
104
  # @param [Hash] attrs
192
- # @option attrs [String] :anonymous_id ID for a user when you don't know
193
- # who they are yet. (optional but you must provide either an
194
- # `anonymous_id` or `user_id`)
195
- # @option attrs [Hash] :context ({})
105
+ #
196
106
  # @option attrs [String] :group_id The ID of the group
197
- # @option attrs [Hash] :integrations What integrations this event
198
- # goes to (optional)
199
- # @option attrs [Hash] :options Options such as user traits (optional)
200
- # @option attrs [Time] :timestamp When the event occurred (optional)
201
- # @option attrs [String] :user_id The ID for the user that is part of
202
- # the group
203
- # @option attrs [String] :message_id ID that uniquely identifies a
204
- # message across the API. (optional)
107
+ # @option attrs [Hash] :traits User traits (optional)
108
+ # @macro common_attrs
205
109
  def group(attrs)
206
110
  symbolize_keys! attrs
207
- check_user_id! attrs
208
-
209
- group_id = attrs[:group_id]
210
- user_id = attrs[:user_id]
211
- traits = attrs[:traits] || {}
212
- timestamp = attrs[:timestamp] || Time.new
213
- context = attrs[:context] || {}
214
- message_id = attrs[:message_id].to_s if attrs[:message_id]
215
-
216
- raise ArgumentError, '.traits must be a hash' unless traits.is_a? Hash
217
- isoify_dates! traits
218
-
219
- check_presence! group_id, 'group_id'
220
- check_timestamp! timestamp
221
- add_context context
222
-
223
- enqueue({
224
- :groupId => group_id,
225
- :userId => user_id,
226
- :traits => traits,
227
- :integrations => attrs[:integrations],
228
- :options => attrs[:options],
229
- :context => context,
230
- :messageId => message_id,
231
- :timestamp => datetime_in_iso8601(timestamp),
232
- :type => 'group'
233
- })
111
+ enqueue(FieldParser.parse_for_group(attrs))
234
112
  end
235
113
 
236
114
  # Records a page view
@@ -238,97 +116,26 @@ module Segment
238
116
  # @see https://segment.com/docs/sources/server/ruby/#page
239
117
  #
240
118
  # @param [Hash] attrs
241
- # @option attrs [String] :anonymous_id ID for a user when you don't know
242
- # who they are yet. (optional but you must provide either an
243
- # `anonymous_id` or `user_id`)
244
- # @option attrs [String] :category The page category (optional)
245
- # @option attrs [Hash] :context ({})
246
- # @option attrs [Hash] :integrations What integrations this event
247
- # goes to (optional)
119
+ #
248
120
  # @option attrs [String] :name Name of the page
249
- # @option attrs [Hash] :options Options such as user traits (optional)
250
121
  # @option attrs [Hash] :properties Page properties (optional)
251
- # @option attrs [Time] :timestamp When the pageview occurred (optional)
252
- # @option attrs [String] :user_id The ID of the user viewing the page
253
- # @option attrs [String] :message_id ID that uniquely identifies a
254
- # message across the API. (optional)
122
+ # @macro common_attrs
255
123
  def page(attrs)
256
124
  symbolize_keys! attrs
257
- check_user_id! attrs
258
-
259
- name = attrs[:name].to_s
260
- properties = attrs[:properties] || {}
261
- timestamp = attrs[:timestamp] || Time.new
262
- context = attrs[:context] || {}
263
- message_id = attrs[:message_id].to_s if attrs[:message_id]
264
-
265
- raise ArgumentError, '.properties must be a hash' unless properties.is_a? Hash
266
- isoify_dates! properties
267
-
268
- check_timestamp! timestamp
269
- add_context context
270
-
271
- enqueue({
272
- :userId => attrs[:user_id],
273
- :anonymousId => attrs[:anonymous_id],
274
- :name => name,
275
- :category => attrs[:category],
276
- :properties => properties,
277
- :integrations => attrs[:integrations],
278
- :options => attrs[:options],
279
- :context => context,
280
- :messageId => message_id,
281
- :timestamp => datetime_in_iso8601(timestamp),
282
- :type => 'page'
283
- })
125
+ enqueue(FieldParser.parse_for_page(attrs))
284
126
  end
285
127
 
286
128
  # Records a screen view (for a mobile app)
287
129
  #
288
130
  # @param [Hash] attrs
289
- # @option attrs [String] :anonymous_id ID for a user when you don't know
290
- # who they are yet. (optional but you must provide either an
291
- # `anonymous_id` or `user_id`)
292
- # @option attrs [String] :category The screen category (optional)
293
- # @option attrs [Hash] :context ({})
294
- # @option attrs [Hash] :integrations What integrations this event
295
- # goes to (optional)
131
+ #
296
132
  # @option attrs [String] :name Name of the screen
297
- # @option attrs [Hash] :options Options such as user traits (optional)
298
- # @option attrs [Hash] :properties Page properties (optional)
299
- # @option attrs [Time] :timestamp When the pageview occurred (optional)
300
- # @option attrs [String] :user_id The ID of the user viewing the screen
301
- # @option attrs [String] :message_id ID that uniquely identifies a
302
- # message across the API. (optional)
133
+ # @option attrs [Hash] :properties Screen properties (optional)
134
+ # @option attrs [String] :category The screen category (optional)
135
+ # @macro common_attrs
303
136
  def screen(attrs)
304
137
  symbolize_keys! attrs
305
- check_user_id! attrs
306
-
307
- name = attrs[:name].to_s
308
- properties = attrs[:properties] || {}
309
- timestamp = attrs[:timestamp] || Time.new
310
- context = attrs[:context] || {}
311
- message_id = attrs[:message_id].to_s if attrs[:message_id]
312
-
313
- raise ArgumentError, '.properties must be a hash' unless properties.is_a? Hash
314
- isoify_dates! properties
315
-
316
- check_timestamp! timestamp
317
- add_context context
318
-
319
- enqueue({
320
- :userId => attrs[:user_id],
321
- :anonymousId => attrs[:anonymous_id],
322
- :name => name,
323
- :properties => properties,
324
- :category => attrs[:category],
325
- :options => attrs[:options],
326
- :integrations => attrs[:integrations],
327
- :context => context,
328
- :messageId => message_id,
329
- :timestamp => timestamp.iso8601,
330
- :type => 'screen'
331
- })
138
+ enqueue(FieldParser.parse_for_screen(attrs))
332
139
  end
333
140
 
334
141
  # @return [Fixnum] number of messages in the queue
@@ -360,53 +167,11 @@ module Segment
360
167
  end
361
168
  end
362
169
 
363
- # private: Ensures that a string is non-empty
364
- #
365
- # obj - String|Number that must be non-blank
366
- # name - Name of the validated value
367
- #
368
- def check_presence!(obj, name)
369
- if obj.nil? || (obj.is_a?(String) && obj.empty?)
370
- raise ArgumentError, "#{name} must be given"
371
- end
372
- end
373
-
374
- # private: Adds contextual information to the call
375
- #
376
- # context - Hash of call context
377
- def add_context(context)
378
- context[:library] = { :name => 'analytics-ruby', :version => Segment::Analytics::VERSION.to_s }
379
- end
380
-
381
170
  # private: Checks that the write_key is properly initialized
382
171
  def check_write_key!
383
172
  raise ArgumentError, 'Write key must be initialized' if @write_key.nil?
384
173
  end
385
174
 
386
- # private: Checks the timstamp option to make sure it is a Time.
387
- def check_timestamp!(timestamp)
388
- raise ArgumentError, 'Timestamp must be a Time' unless timestamp.is_a? Time
389
- end
390
-
391
- def event(attrs)
392
- symbolize_keys! attrs
393
-
394
- {
395
- :userId => user_id,
396
- :name => name,
397
- :properties => properties,
398
- :context => context,
399
- :timestamp => datetime_in_iso8601(timestamp),
400
- :type => 'screen'
401
- }
402
- end
403
-
404
- def check_user_id!(attrs)
405
- unless attrs[:user_id] || attrs[:anonymous_id]
406
- raise ArgumentError, 'Must supply either user_id or anonymous_id'
407
- end
408
- end
409
-
410
175
  def ensure_worker_running
411
176
  return if worker_running?
412
177
  @worker_mutex.synchronize do