leanplum_api 1.3.6 → 1.4.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: ce4fe4f8ab0087d81620500bfbb5b8772fc5fce0
4
- data.tar.gz: e9b7b9754428c7e7271dc02ad6902400d1ad06f8
3
+ metadata.gz: 0619bb8636e6cd600ef0f1256b668b7370eb2b47
4
+ data.tar.gz: 1aaee928b8b46c2618c06f7e03ea6af46054754e
5
5
  SHA512:
6
- metadata.gz: db56dbc6b349e76245c5ff6f02442088dd4d0f0e84b4018bbb49e05921a6590d3e8a3d3a75b88d2b33f2091f6918552716e860c411328350f3340f01122e6d99
7
- data.tar.gz: 4287a74432cce7921da7e0a8c601ad649d855aab79fcb89bdbfe78f93cb34fcbbeec5b981f1d4e0e58eb1eac74e42ec796096e369c3911fa5eb7da01ed96e68f
6
+ metadata.gz: 695bd8b8fef4735fdda61caf33a878407c2f41faf7e1ef873238ef29a208757bbd47215e6c8cc3d3c223219367b3720ec7f5f1a05428f3bc028462576d48f80a
7
+ data.tar.gz: 0ebb4861712ec2afe496a506036dd72f60635b3a5d914fb9274ea9cbc7bfdbe978e6c68b80d032e2a8abf0f195cab214d0c95593cbe04169cee3ef3a1681840d
data/README.md CHANGED
@@ -57,19 +57,19 @@ attribute_hash = {
57
57
  first_name: 'Mike',
58
58
  last_name: 'Jones',
59
59
  gender: 'm',
60
- birthday: Date.today, # Dates and times in user attributes will be formatted as strings; Leanplum doesn't support date or time types
60
+ birthday: Date.today, # Dates/times only sort of supported in user attributes
61
61
  email: 'still_tippin@test.com'
62
62
  }
63
63
  api.set_user_attributes(attribute_hash)
64
64
 
65
- # You must also provide the :event property for event tracking
65
+ # You must also provide the :event property for event tracking.
66
+ # You can optionally provide a :time property; if it is not set Leanplum will timestamp the event "now".
67
+ # All other key/values besides :user_id, :device_id, :event, and :time will be sent as event params/properties.
66
68
  event = {
67
69
  user_id: 12345,
68
70
  event: 'purchase',
69
71
  time: Time.now.utc, # Event timestamps will be converted to epoch seconds by the gem.
70
- params: {
71
- 'some_event_property' => 'boss_hog_on_candy'
72
- }
72
+ some_event_property: 'boss_hog_on_candy'
73
73
  }
74
74
  api.track_events(event)
75
75
 
@@ -83,19 +83,21 @@ api.reset_anomalous_users([12345, 23456])
83
83
  api.track_events(event, force_anomalous_override: true)
84
84
  ```
85
85
 
86
- Data export:
86
+ API based data export:
87
87
  ```ruby
88
88
  api = LeanplumApi::API.new
89
89
  job_id = api.export_data(start_time, end_time)
90
90
  response = wait_for_job(job_id)
91
91
  ```
92
92
 
93
+ Note well that Leanplum officially recommends use of the automated S3 export instead of API based export. According to a Leanplum engineer these two data export methodologies are completely independent data paths and in our experience we have found API based data export to be missing 10-15% of the data that is eventually returned by the automated export.
94
+
93
95
  ## Specs
94
96
 
95
- To run specs, you must set the LEANPLUM_PRODUCTION_KEY, LEANPLUM_APP_ID, LEANPLUM_CONTENT_READ_ONLY_KEY, LEANPLUM_DEVELOPMENT_KEY, and LEANPLUM_DATA_EXPORT_KEY environment variables (preferably to some development only keys) to something and then run rspec.
97
+ To run specs, you must set the `LEANPLUM_PRODUCTION_KEY`, `LEANPLUM_APP_ID`, `LEANPLUM_CONTENT_READ_ONLY_KEY`, `LEANPLUM_DEVELOPMENT_KEY`, and `LEANPLUM_DATA_EXPORT_KEY` environment variables (preferably to some development only keys) to something and then run rspec.
96
98
  Because of the nature of VCR/Webmock, you can set them to anything (including invalid keys) as long as you are not changing anything substantive or writing new specs. If you want to make substantive changes/add new specs, VCR will need to be able to generate fixture data so you will need to use a real set of Leanplum keys.
97
99
 
98
- > BE AWARE THAT IF YOU WRITE A NEW SPEC OR DELETE A VCR FILE, IT'S POSSIBLE THAT REAL DATA WILL BE WRITTEN TO THE LEANPLUM_APP_ID YOU CONFIGURE! Certainly a real request will be made to rebuild the VCR file, and while specs run with ```devMode=true```, it's usually a good idea to create a fake app for testing/running specs against.
100
+ > BE AWARE THAT IF YOU WRITE A NEW SPEC OR DELETE A VCR FILE, IT'S POSSIBLE THAT REAL DATA WILL BE WRITTEN TO THE `LEANPLUM_APP_ID` YOU CONFIGURE! Certainly a real request will be made to rebuild the VCR file, and while specs run with ```devMode=true```, it's usually a good idea to create a fake app for testing/running specs against.
99
101
 
100
102
  ```bash
101
103
  export LEANPLUM_PRODUCTION_KEY=dev_somethingsomeg123456
@@ -117,4 +119,4 @@ export LEANPLUM_API_DEBUG=true
117
119
  bundle exec rails whatever
118
120
  ```
119
121
 
120
- You can also configure "developer mode". This will use the "devMode=true" parameter on all requests, which sends them to a separate queue (and probably means actions logged as development tests don't count towards your bill).
122
+ You can also configure "developer mode". This will use the "devMode=true" parameter on some requests, which seems to sends them to a separate queue which might not count towards Leanplum's usage billing.
@@ -39,12 +39,12 @@ module LeanplumApi
39
39
  # user_ids_to_reset << request_data[i]['userId']
40
40
 
41
41
  # This is what it has to be:
42
- user_ids_to_reset = events.map { |e| e[:user_id] }
42
+ user_ids_to_reset = events.map { |e| e[:user_id] }.uniq
43
43
  end
44
44
  end
45
45
 
46
46
  unless user_ids_to_reset.empty?
47
- LeanplumApi.configuration.logger.info("Resetting anomalous user ids: #{user_ids_to_reset}")
47
+ LeanplumApi.configuration.logger.debug("Resetting anomalous user ids: #{user_ids_to_reset}")
48
48
  reset_anomalous_users(user_ids_to_reset)
49
49
  end
50
50
  end
@@ -143,8 +143,8 @@ module LeanplumApi
143
143
  @http.get(action: 'getVars', userId: user_id).body['response'].first['vars']
144
144
  end
145
145
 
146
- # If you pass old events OR users with old date attributes (i.e. create_date for an old users), leanplum will mark them 'anomalous'
147
- # and exclude them from your data set.
146
+ # If you pass old events OR users with old date attributes (i.e. create_date for an old users), leanplum will mark
147
+ # them 'anomalous' and exclude them from your data set.
148
148
  # Calling this method after you pass old events will fix that for all events for the specified user_id
149
149
  # For some reason this API feature requires the developer key
150
150
  def reset_anomalous_users(user_ids)
@@ -169,9 +169,10 @@ module LeanplumApi
169
169
  @development ||= LeanplumApi::Development.new
170
170
  end
171
171
 
172
- def extract_user_id_or_device_id_hash(hash)
173
- user_id = hash['user_id'] || hash[:user_id]
174
- device_id = hash['device_id'] || hash[:device_id]
172
+ # Deletes the user_id and device_id key/value pairs from the hash parameter.
173
+ def extract_user_id_or_device_id_hash!(hash)
174
+ user_id = hash.delete(:user_id)
175
+ device_id = hash.delete(:device_id)
175
176
  fail "No device_id or user_id in hash #{hash}" unless user_id || device_id
176
177
 
177
178
  user_id ? { 'userId' => user_id } : { 'deviceId' => device_id }
@@ -180,44 +181,27 @@ module LeanplumApi
180
181
  # Action can be any command that takes a userAttributes param. "start" (a session) is the other command that most
181
182
  # obviously takes userAttributes.
182
183
  def build_user_attributes_hash(user_hash, action = 'setUserAttributes')
183
- extract_user_id_or_device_id_hash(user_hash).merge(
184
- 'action' => action,
185
- 'userAttributes' => turn_date_and_time_values_to_strings(user_hash).reject { |k,v| k.to_s =~ /^(user_id|device_id)$/ }
186
- )
184
+ user_hash = HashWithIndifferentAccess.new(user_hash)
185
+
186
+ # As of 2015-10 Leanplum supports ISO8601 date strings as user attributes. Support for times is as yet unavailable.
187
+ user_hash.each do |k,v|
188
+ user_hash[k] = v.iso8601 if v.is_a?(Date) || v.is_a?(Time) || v.is_a?(DateTime)
189
+ end
190
+
191
+ extract_user_id_or_device_id_hash!(user_hash).merge('action' => action, 'userAttributes' => user_hash)
187
192
  end
188
193
 
189
194
  # Events have a :user_id or :device id, a name (:event) and an optional time (:time)
190
195
  def build_event_attributes_hash(event_hash)
191
- fail "No event name provided in #{event_hash}" unless event_hash[:event] || event_hash['event']
192
-
193
- time = event_hash[:time] || event_hash['time']
194
- time_hash = time ? { 'time' => time.strftime('%s') } : {}
195
-
196
- event = extract_user_id_or_device_id_hash(event_hash).merge(time_hash).merge(
197
- 'action' => 'track',
198
- 'event' => event_hash[:event] || event_hash['event']
199
- )
200
- event_params = event_hash.reject { |k,v| k.to_s =~ /^(user_id|device_id|event|time)$/ }
201
- if event_params.keys.size > 0
202
- event.merge('params' => event_params )
203
- else
204
- event
205
- end
206
- end
196
+ event_hash = HashWithIndifferentAccess.new(event_hash)
197
+ event_name = event_hash.delete(:event)
198
+ fail "Event name or timestamp not provided in #{event_hash}" unless event_name
207
199
 
208
- # Leanplum does not support dates and times as of 2015-08-11
209
- def turn_date_and_time_values_to_strings(hash)
210
- new_hash = {}
211
- hash.each do |k,v|
212
- if v.is_a?(Time) || v.is_a?(DateTime)
213
- new_hash[k] = v.strftime('%Y-%m-%d %H:%M:%S')
214
- elsif v.is_a?(Date)
215
- new_hash[k] = v.strftime('%Y-%m-%d')
216
- else
217
- new_hash[k] = v
218
- end
219
- end
220
- new_hash
200
+ event = { 'action' => 'track', 'event' => event_name }.merge(extract_user_id_or_device_id_hash!(event_hash))
201
+ time = event_hash.delete(:time)
202
+ event.merge!('time' => time.strftime('%s')) if time
203
+
204
+ event_hash.keys.size > 0 ? event.merge('params' => event_hash ) : event
221
205
  end
222
206
  end
223
207
  end
@@ -1,3 +1,3 @@
1
1
  module LeanplumApi
2
- VERSION = '1.3.6'
2
+ VERSION = '1.4.0'
3
3
  end
data/spec/api_spec.rb CHANGED
@@ -19,13 +19,13 @@ describe LeanplumApi::API do
19
19
  expect(api.send(:build_user_attributes_hash, users.first)).to eq({
20
20
  'userId' => 123456,
21
21
  'action' => 'setUserAttributes',
22
- 'userAttributes' => {
22
+ 'userAttributes' => HashWithIndifferentAccess.new(
23
23
  first_name: 'Mike',
24
24
  last_name: 'Jones',
25
25
  gender: 'm',
26
26
  email: 'still_tippin@test.com',
27
27
  create_date: '2010-01-01'
28
- }
28
+ )
29
29
  })
30
30
  end
31
31
 
@@ -78,32 +78,37 @@ describe LeanplumApi::API do
78
78
  end
79
79
 
80
80
  context 'events' do
81
+ let(:timestamp) { '2015-05-01 01:02:03' }
81
82
  let(:events) do
82
83
  [
83
84
  {
84
85
  user_id: 12345,
85
86
  event: 'purchase',
86
87
  time: Time.now.utc,
87
- params: {
88
- 'some_timestamp' => '2015-05-01 01:02:03'
89
- }
88
+ some_timestamp: timestamp
90
89
  },
91
90
  {
92
91
  user_id: 54321,
93
92
  event: 'purchase_page_view',
94
- time: Time.now.utc - 10.minutes,
93
+ time: Time.now.utc - 10.minutes
95
94
  }
96
95
  ]
97
96
  end
98
97
 
99
- it 'build_event_attributes_hash' do
100
- expect(api.send(:build_event_attributes_hash, events.first)).to eq({
101
- 'userId' => 12345,
102
- 'time' => Time.now.utc.strftime('%s'),
103
- 'action' => 'track',
104
- 'event' => 'purchase',
105
- 'params' => { params: { 'some_timestamp'=>'2015-05-01 01:02:03' } }
106
- })
98
+ context '#build_event_attributes_hash' do
99
+ let(:event_hash) do
100
+ {
101
+ 'userId' => 12345,
102
+ 'time' => Time.now.utc.strftime('%s'),
103
+ 'action' => 'track',
104
+ 'event' => 'purchase',
105
+ 'params' => { 'some_timestamp' => timestamp }
106
+ }
107
+ end
108
+
109
+ it 'builds the events format' do
110
+ expect(api.send(:build_event_attributes_hash, events.first)).to eq(event_hash)
111
+ end
107
112
  end
108
113
 
109
114
  context 'without user attributes' do
@@ -5,8 +5,8 @@ http_interactions:
5
5
  uri: https://www.leanplum.com/api?action=multi&apiVersion=1.0.6&appId=<LEANPLUM_APP_ID>&clientKey=<LEANPLUM_PRODUCTION_KEY>&devMode=false&time=1439337600
6
6
  body:
7
7
  encoding: UTF-8
8
- string: '{"data":[{"userId":12345,"time":"1439337600","action":"track","event":"purchase","params":{"params":{"some_timestamp":"2015-05-01
9
- 01:02:03"}}},{"userId":54321,"time":"1439337000","action":"track","event":"purchase_page_view"}]}'
8
+ string: '{"data":[{"action":"track","event":"purchase","userId":12345,"time":"1439337600","params":{"some_timestamp":"2015-05-01
9
+ 01:02:03"}},{"action":"track","event":"purchase_page_view","userId":54321,"time":"1439337000"}]}'
10
10
  headers:
11
11
  User-Agent:
12
12
  - Faraday v0.9.2
@@ -40,6 +40,6 @@ http_interactions:
40
40
  string: '{"response":[{"isOffline":true,"success":true,"warning":{"message":"Anomaly
41
41
  detected: time skew. User will be excluded from analytics."}},{"success":true,"warning":{"message":"Anomaly
42
42
  detected: time skew. User will be excluded from analytics."}}]}'
43
- http_version:
43
+ http_version:
44
44
  recorded_at: Wed, 12 Aug 2015 00:00:00 GMT
45
45
  recorded_with: VCR 2.9.3
@@ -5,8 +5,8 @@ http_interactions:
5
5
  uri: https://www.leanplum.com/api?action=multi&apiVersion=1.0.6&appId=<LEANPLUM_APP_ID>&clientKey=<LEANPLUM_PRODUCTION_KEY>&devMode=false&time=1439337600
6
6
  body:
7
7
  encoding: UTF-8
8
- string: '{"data":[{"userId":123456,"action":"setUserAttributes","userAttributes":{"first_name":"Mike","last_name":"Jones","gender":"m","email":"still_tippin@test.com","create_date":"2010-01-01"}},{"userId":12345,"time":"1439337600","action":"track","event":"purchase","params":{"params":{"some_timestamp":"2015-05-01
9
- 01:02:03"}}},{"userId":54321,"time":"1439337000","action":"track","event":"purchase_page_view"}]}'
8
+ string: '{"data":[{"userId":123456,"action":"setUserAttributes","userAttributes":{"first_name":"Mike","last_name":"Jones","gender":"m","email":"still_tippin@test.com","create_date":"2010-01-01"}},{"action":"track","event":"purchase","userId":12345,"time":"1439337600","params":{"some_timestamp":"2015-05-01
9
+ 01:02:03"}},{"action":"track","event":"purchase_page_view","userId":54321,"time":"1439337000"}]}'
10
10
  headers:
11
11
  User-Agent:
12
12
  - Faraday v0.9.2
@@ -41,6 +41,6 @@ http_interactions:
41
41
  detected: time skew. User will be excluded from analytics."}},{"success":true,"warning":{"message":"Anomaly
42
42
  detected: time skew. User will be excluded from analytics."}},{"success":true,"warning":{"message":"Anomaly
43
43
  detected: time skew. User will be excluded from analytics."}}]}'
44
- http_version:
44
+ http_version:
45
45
  recorded_at: Wed, 12 Aug 2015 00:00:00 GMT
46
46
  recorded_with: VCR 2.9.3
@@ -5,8 +5,8 @@ http_interactions:
5
5
  uri: https://www.leanplum.com/api?action=multi&apiVersion=1.0.6&appId=<LEANPLUM_APP_ID>&clientKey=<LEANPLUM_PRODUCTION_KEY>&devMode=false&time=1439337600
6
6
  body:
7
7
  encoding: UTF-8
8
- string: '{"data":[{"userId":12345,"time":"1439337600","action":"track","event":"purchase","params":{"params":{"some_timestamp":"2015-05-01
9
- 01:02:03"}}},{"userId":54321,"time":"1439337000","action":"track","event":"purchase_page_view"}]}'
8
+ string: '{"data":[{"action":"track","event":"purchase","userId":12345,"time":"1439337600","params":{"some_timestamp":"2015-05-01
9
+ 01:02:03"}},{"action":"track","event":"purchase_page_view","userId":54321,"time":"1439337000"}]}'
10
10
  headers:
11
11
  User-Agent:
12
12
  - Faraday v0.9.2
@@ -40,7 +40,7 @@ http_interactions:
40
40
  string: '{"response":[{"isOffline":true,"success":true,"warning":{"message":"Anomaly
41
41
  detected: time skew. User will be excluded from analytics."}},{"success":true,"warning":{"message":"Anomaly
42
42
  detected: time skew. User will be excluded from analytics."}}]}'
43
- http_version:
43
+ http_version:
44
44
  recorded_at: Wed, 12 Aug 2015 00:00:00 GMT
45
45
  - request:
46
46
  method: post
@@ -81,6 +81,6 @@ http_interactions:
81
81
  string: '{"response":[{"success":true,"warning":{"message":"Anomaly detected:
82
82
  time skew. User will be excluded from analytics."}},{"success":true,"warning":{"message":"Anomaly
83
83
  detected: time skew. User will be excluded from analytics."}}]}'
84
- http_version:
84
+ http_version:
85
85
  recorded_at: Wed, 12 Aug 2015 00:00:00 GMT
86
86
  recorded_with: VCR 2.9.3
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: leanplum_api
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.3.6
4
+ version: 1.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Lumos Labs, Inc.
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-01-04 00:00:00.000000000 Z
11
+ date: 2016-01-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport