mixpanel-ruby 2.0.1 → 2.1.0

Sign up to get free protection for your applications and to get access to all the features.
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: []