mixpanel-ruby 2.0.1 → 2.1.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
  SHA1:
3
- metadata.gz: 286b3bfe7565a25de53140a93d879b403331b87d
4
- data.tar.gz: b6eed03923e1eee12b21075e5afe48ac4c81807a
3
+ metadata.gz: f9e1a1a4366eebfc28e385aafb1a74df684b02d4
4
+ data.tar.gz: 2569a46638a4c168e6766ca21c3ce54adf5d9ee4
5
5
  SHA512:
6
- metadata.gz: 765115c755470429ef8a93609b2e42578a1cfb762df1474d1e98b0eb3188c869235b2d7e7a4e1569a1aa098fc1211478285434b9e689d3186caa512c5f7b83ad
7
- data.tar.gz: 4844747e4c68ecaca350d4c720118716014306e803eb5f414bd4a3ed11e701ea474bd7e321bc539e9ea2134186e69fe968263322ac57ff9bb99e3c99cce0be08
6
+ metadata.gz: 2e759bb1cd88260c95e1d5edf2efd61bcf284984f3595c5e1b3126b3db428db85806942bf09d73e2974cd0da8b292d8c8edd9315ad2cb81a9456bfe555049ee6
7
+ data.tar.gz: 9d53eccb3b1cee24a2dbda7cf16719feb5933002bf394079050bd10882493ecd53f93263e489df28a049e649344f5cfc992cce10914aa24417a958e342606020
@@ -49,6 +49,12 @@ In particular, for Rails apps, the following projects are currently actively mai
49
49
 
50
50
  == Changes
51
51
 
52
+ == 2.1.0
53
+ * Add Mixpanel::Tracker#generate_tracking_url, which generates {pixel tracking urls}[https://mixpanel.com/docs/api-documentation/pixel-based-event-tracking].
54
+ * Rescue JSONErrors in the consumer and raise Mixpanel::ServerError in Mixpanel::Consumer#send!.
55
+ * Make it clear how to import events with custom timestamp.
56
+ * Update dependancies in gemspec
57
+
52
58
  == 2.0.1
53
59
  * Add Deprecated version of Mixpanel::BufferedConsumer#send
54
60
 
@@ -35,7 +35,7 @@ module Mixpanel
35
35
  @@init_http = block
36
36
  end
37
37
 
38
- # A Consumer recieves messages from a Mixpanel::Tracker, and
38
+ # A Consumer receives messages from a Mixpanel::Tracker, and
39
39
  # sends them elsewhere- probably to Mixpanel's analytics services,
40
40
  # but can also enqueue them for later processing, log them to a
41
41
  # file, or do whatever else you might find useful.
@@ -100,13 +100,16 @@ module Mixpanel
100
100
  raise ConnectionError.new("Could not connect to Mixpanel, with error \"#{e.message}\".")
101
101
  end
102
102
 
103
- succeeded = nil
103
+ result = {}
104
104
  if response_code.to_i == 200
105
- result = JSON.load(response_body) rescue {}
106
- succeeded = result['status'] == 1
105
+ begin
106
+ result = JSON.parse(response_body.to_s)
107
+ rescue JSON::JSONError
108
+ raise ServerError.new("Could not interpret Mixpanel server response: '#{response_body}'")
109
+ end
107
110
  end
108
111
 
109
- if !succeeded
112
+ if result['status'] != 1
110
113
  raise ServerError.new("Could not write to Mixpanel, server responded with #{response_code} returning: '#{response_body}'")
111
114
  end
112
115
  end
@@ -123,7 +126,7 @@ module Mixpanel
123
126
  # [response code, response body]
124
127
  #
125
128
  # as the result of the response. Response code should be nil if
126
- # the request never recieves a response for some reason.
129
+ # the request never receives a response for some reason.
127
130
  def request(endpoint, form_data)
128
131
  uri = URI(endpoint)
129
132
  request = Net::HTTP::Post.new(uri.request_uri)
@@ -141,7 +144,6 @@ module Mixpanel
141
144
  response = client.request(request)
142
145
  [response.code, response.body]
143
146
  end
144
-
145
147
  end
146
148
 
147
149
  # BufferedConsumer buffers messages in memory, and sends messages as
@@ -79,7 +79,9 @@ module Mixpanel
79
79
  # representing the source of that event (for example, a user id),
80
80
  # an event name describing the event and a set of properties
81
81
  # describing that event. Properties are provided as a Hash with
82
- # string keys and strings, numbers or booleans as values.
82
+ # string keys and strings, numbers or booleans as values. By default,
83
+ # we pass the time of the method call as the time the event occured, if you
84
+ # wish to override this pass a timestamp in the properties hash.
83
85
  #
84
86
  # tracker = Mixpanel::Tracker.new
85
87
  #
@@ -90,7 +92,8 @@ module Mixpanel
90
92
  # # or aspects of the source or user associated with the event
91
93
  # tracker.import("API_KEY", "12345", "Welcome Email Sent", {
92
94
  # 'Email Template' => 'Pretty Pink Welcome',
93
- # 'User Sign-up Cohort' => 'July 2013'
95
+ # 'User Sign-up Cohort' => 'July 2013',
96
+ # 'time' => 1369353600,
94
97
  # })
95
98
  def import(api_key, distinct_id, event, properties={}, ip=nil)
96
99
  properties = {
@@ -131,5 +131,42 @@ module Mixpanel
131
131
 
132
132
  ret
133
133
  end
134
+
135
+ # A call to #generate_tracking_url will return a formatted url for
136
+ # pixel based tracking. #generate_tracking_url takes a distinct_id
137
+ # representing the source of that event (for example, a user id),
138
+ # an event name describing the event, and a set of properties describing
139
+ # that event. Properties are provided as a Hash with string keys and
140
+ # strings, numbers or booleans as values. For more information, please see:
141
+ # https://mixpanel.com/docs/api-documentation/pixel-based-event-tracking
142
+ #
143
+ # tracker = Mixpanel::Tracker.new
144
+ #
145
+ # # generate pixel tracking url in order to track that user
146
+ # # "12345"'s credit card was declined
147
+ # url = tracker.generate_tracking_url("12345", "Credit Card Declined", {
148
+ # 'time' => 1310111365
149
+ # })
150
+ #
151
+ # url == 'https://api.mixpanel.com/track/?data=[BASE_64_JSON_EVENT]&ip=1&img=1'
152
+ def generate_tracking_url(distinct_id, event, properties={}, endpoint=nil)
153
+ properties = {
154
+ 'distinct_id' => distinct_id,
155
+ 'token' => @token,
156
+ 'time' => Time.now.to_i,
157
+ 'mp_lib' => 'ruby',
158
+ '$lib_version' => Mixpanel::VERSION,
159
+ }.merge(properties)
160
+
161
+ raw_data = {
162
+ 'event' => event,
163
+ 'properties' => properties,
164
+ }
165
+
166
+ endpoint = endpoint || 'https://api.mixpanel.com/track/'
167
+ data = Base64.urlsafe_encode64(raw_data.to_json)
168
+
169
+ "#{endpoint}?data=#{data}&ip=1&img=1"
170
+ end
134
171
  end
135
172
  end
@@ -1,3 +1,3 @@
1
1
  module Mixpanel
2
- VERSION = '2.0.1'
2
+ VERSION = '2.1.0'
3
3
  end
@@ -14,7 +14,7 @@ spec = Gem::Specification.new do |spec|
14
14
 
15
15
  spec.required_ruby_version = '>= 2.0.0'
16
16
 
17
- spec.add_development_dependency 'rake'
18
- spec.add_development_dependency 'rspec', '~> 3.0.0'
19
- spec.add_development_dependency 'webmock', '~> 1.18.0'
17
+ spec.add_development_dependency 'rake', '~> 0'
18
+ spec.add_development_dependency 'rspec', '~> 3.0'
19
+ spec.add_development_dependency 'webmock', '~> 1.18'
20
20
  end
@@ -46,6 +46,20 @@ describe Mixpanel::Consumer do
46
46
  expect(WebMock).to have_requested(:post, 'https://api.mixpanel.com/track').
47
47
  with(:body => {'data' => 'IlRFU1QgRVZFTlQgTUVTU0FHRSI=', 'verbose' => '1' })
48
48
  end
49
+
50
+ it 'should raise server error if response body is empty' do
51
+ stub_request(:any, 'https://api.mixpanel.com/track').to_return({:body => ''})
52
+ expect { subject.send!(:event, {'data' => 'TEST EVENT MESSAGE'}.to_json) }.to raise_exception(Mixpanel::ServerError, /Could not interpret Mixpanel server response: ''/)
53
+ expect(WebMock).to have_requested(:post, 'https://api.mixpanel.com/track').
54
+ with(:body => {'data' => 'IlRFU1QgRVZFTlQgTUVTU0FHRSI=', 'verbose' => '1' })
55
+ end
56
+
57
+ it 'should raise server error when verbose is disabled' do
58
+ stub_request(:any, 'https://api.mixpanel.com/track').to_return({:body => '0'})
59
+ expect { subject.send!(:event, {'data' => 'TEST EVENT MESSAGE'}.to_json) }.to raise_exception(Mixpanel::ServerError, /Could not interpret Mixpanel server response: '0'/)
60
+ expect(WebMock).to have_requested(:post, 'https://api.mixpanel.com/track').
61
+ with(:body => {'data' => 'IlRFU1QgRVZFTlQgTUVTU0FHRSI=', 'verbose' => '1' })
62
+ end
49
63
  end
50
64
 
51
65
  context 'raw consumer' do
@@ -50,5 +50,26 @@ describe Mixpanel::Events do
50
50
  }
51
51
  } ]])
52
52
  end
53
- end
54
53
 
54
+ it 'should allow users to pass timestamp for import' do
55
+ older_time = Time.parse('Jun 6 1971, 16:23:04')
56
+ @events.import('API_KEY', 'TEST ID', 'Test Event', {
57
+ 'Circumstances' => 'During a test',
58
+ 'time' => older_time.to_i,
59
+ })
60
+ expect(@log).to eq([[:import, {
61
+ 'api_key' => 'API_KEY',
62
+ 'data' => {
63
+ 'event' => 'Test Event',
64
+ 'properties' => {
65
+ 'Circumstances' => 'During a test',
66
+ 'distinct_id' => 'TEST ID',
67
+ 'mp_lib' => 'ruby',
68
+ '$lib_version' => Mixpanel::VERSION,
69
+ 'token' => 'TEST TOKEN',
70
+ 'time' => older_time.to_i,
71
+ }
72
+ }
73
+ } ]])
74
+ end
75
+ end
@@ -2,6 +2,7 @@ require 'mixpanel-ruby'
2
2
  require 'base64'
3
3
  require 'json'
4
4
  require 'uri'
5
+ require 'cgi'
5
6
 
6
7
  describe Mixpanel::Tracker do
7
8
  before(:each) do
@@ -19,6 +20,34 @@ describe Mixpanel::Tracker do
19
20
  with(:body => {:data => 'eyJldmVudCI6IiRjcmVhdGVfYWxpYXMiLCJwcm9wZXJ0aWVzIjp7ImRpc3RpbmN0X2lkIjoiVEVTVCBJRCIsImFsaWFzIjoiVEVTVCBBTElBUyIsInRva2VuIjoiVEVTVCBUT0tFTiJ9fQ==', 'verbose' => '1'})
20
21
  end
21
22
 
23
+ it 'should generate pixel tracking urls correctly' do
24
+ mixpanel = Mixpanel::Tracker.new('TEST TOKEN')
25
+ event = 'TEST EVENT'
26
+ properties = {'Circumstances' => 'During test'}
27
+ default_properties = {
28
+ 'distinct_id' => 'TEST_ID',
29
+ 'mp_lib' => 'ruby',
30
+ '$lib_version' => Mixpanel::VERSION,
31
+ 'token' => 'TEST TOKEN',
32
+ 'time' => @time_now.to_i
33
+ }
34
+ expected_data = {'event' => event, 'properties' => properties.merge(default_properties)}
35
+
36
+ url_string = mixpanel.generate_tracking_url('TEST_ID', event, properties)
37
+
38
+ url = URI(url_string)
39
+ expect(url.scheme).to eq('https')
40
+ expect(url.host).to eq('api.mixpanel.com')
41
+ expect(url.path).to eq('/track/')
42
+
43
+ parsed_query = CGI.parse(url.query)
44
+ expect(parsed_query['ip'][0]).to eq('1')
45
+ expect(parsed_query['img'][0]).to eq('1')
46
+
47
+ data = JSON.parse(Base64.urlsafe_decode64(parsed_query['data'][0]))
48
+ expect(data).to eq(expected_data)
49
+ end
50
+
22
51
  it 'should send a request to the track api with the default consumer' do
23
52
  WebMock.reset!
24
53
  stub_request(:any, 'https://api.mixpanel.com/track').to_return({:body => '{"status": 1, "error": null}'})
metadata CHANGED
@@ -1,27 +1,27 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mixpanel-ruby
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.1
4
+ version: 2.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mixpanel
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-03-12 00:00:00.000000000 Z
11
+ date: 2015-04-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - ">="
17
+ - - "~>"
18
18
  - !ruby/object:Gem::Version
19
19
  version: '0'
20
20
  type: :development
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - ">="
24
+ - - "~>"
25
25
  - !ruby/object:Gem::Version
26
26
  version: '0'
27
27
  - !ruby/object:Gem::Dependency
@@ -30,28 +30,28 @@ dependencies:
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: 3.0.0
33
+ version: '3.0'
34
34
  type: :development
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: 3.0.0
40
+ version: '3.0'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: webmock
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
45
  - - "~>"
46
46
  - !ruby/object:Gem::Version
47
- version: 1.18.0
47
+ version: '1.18'
48
48
  type: :development
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
52
  - - "~>"
53
53
  - !ruby/object:Gem::Version
54
- version: 1.18.0
54
+ version: '1.18'
55
55
  description: The official Mixpanel tracking library for ruby
56
56
  email: support@mixpanel.com
57
57
  executables: []