leanplum_api 1.3.6 → 1.4.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 +4 -4
- data/README.md +11 -9
- data/lib/leanplum_api/api.rb +24 -40
- data/lib/leanplum_api/version.rb +1 -1
- data/spec/api_spec.rb +19 -14
- data/spec/fixtures/vcr/track_events.yml +3 -3
- data/spec/fixtures/vcr/track_events_and_attributes.yml +3 -3
- data/spec/fixtures/vcr/track_events_anomaly_overrider.yml +4 -4
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0619bb8636e6cd600ef0f1256b668b7370eb2b47
|
4
|
+
data.tar.gz: 1aaee928b8b46c2618c06f7e03ea6af46054754e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
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
|
-
|
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
|
-
|
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
|
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
|
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.
|
data/lib/leanplum_api/api.rb
CHANGED
@@ -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.
|
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
|
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
|
-
|
173
|
-
|
174
|
-
|
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
|
-
|
184
|
-
|
185
|
-
|
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
|
-
|
192
|
-
|
193
|
-
|
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
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
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
|
data/lib/leanplum_api/version.rb
CHANGED
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
|
-
|
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
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
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":[{"
|
9
|
-
01:02:03"}}
|
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"}},{"
|
9
|
-
01:02:03"}}
|
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":[{"
|
9
|
-
01:02:03"}}
|
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.
|
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-
|
11
|
+
date: 2016-01-19 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|