greenfinch-ruby 0.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 +7 -0
- data/.gitignore +5 -0
- data/.idea/.gitignore +8 -0
- data/.idea/greenfinch-ruby.iml +16 -0
- data/.idea/inspectionProfiles/Project_Default.xml +6 -0
- data/.idea/misc.xml +4 -0
- data/.idea/modules.xml +8 -0
- data/.idea/vcs.xml +6 -0
- data/.rspec +2 -0
- data/.travis.yml +8 -0
- data/Gemfile +2 -0
- data/LICENSE +190 -0
- data/README.md +124 -0
- data/Rakefile +13 -0
- data/Readme.rdoc +109 -0
- data/demo/faraday_consumer.rb +40 -0
- data/demo/out_of_process_consumer.rb +71 -0
- data/demo/simple_messages.rb +9 -0
- data/greenfinch-ruby.gemspec +21 -0
- data/lib/greenfinch-ruby.rb +3 -0
- data/lib/greenfinch-ruby/consumer.rb +271 -0
- data/lib/greenfinch-ruby/error.rb +46 -0
- data/lib/greenfinch-ruby/events.rb +140 -0
- data/lib/greenfinch-ruby/groups.rb +201 -0
- data/lib/greenfinch-ruby/people.rb +254 -0
- data/lib/greenfinch-ruby/tracker.rb +184 -0
- data/lib/greenfinch-ruby/version.rb +3 -0
- data/spec/mixpanel-ruby/consumer_spec.rb +208 -0
- data/spec/mixpanel-ruby/error_spec.rb +76 -0
- data/spec/mixpanel-ruby/events_spec.rb +76 -0
- data/spec/mixpanel-ruby/groups_spec.rb +159 -0
- data/spec/mixpanel-ruby/people_spec.rb +220 -0
- data/spec/mixpanel-ruby/tracker_spec.rb +134 -0
- data/spec/spec_helper.rb +15 -0
- metadata +132 -0
@@ -0,0 +1,140 @@
|
|
1
|
+
require 'time'
|
2
|
+
|
3
|
+
require 'greenfinch-ruby/consumer'
|
4
|
+
require 'greenfinch-ruby/error'
|
5
|
+
|
6
|
+
module Greenfinch
|
7
|
+
|
8
|
+
# Handles formatting Greenfinch event tracking messages
|
9
|
+
# and sending them to the consumer. Greenfinch::Tracker
|
10
|
+
# is a subclass of this class, and the best way to
|
11
|
+
# track events is to instantiate a Greenfinch::Tracker
|
12
|
+
#
|
13
|
+
# tracker = Greenfinch::Tracker.new(YOUR_GREENFINCH_TOKEN) # Has all of the methods of Greenfinch::Event
|
14
|
+
# tracker.track(...)
|
15
|
+
#
|
16
|
+
class Events
|
17
|
+
|
18
|
+
# You likely won't need to instantiate an instance of
|
19
|
+
# Greenfinch::Events directly. The best way to get an instance
|
20
|
+
# is to use Greenfinch::Tracker
|
21
|
+
#
|
22
|
+
# # tracker has all of the methods of Greenfinch::Events
|
23
|
+
# tracker = Greenfinch::Tracker.new(YOUR_GREENFINCH_TOKEN)
|
24
|
+
#
|
25
|
+
def initialize(token, service_name, debug, error_handler=nil, &block)
|
26
|
+
@token = token
|
27
|
+
@service_name = service_name
|
28
|
+
@debug = debug
|
29
|
+
@error_handler = error_handler || ErrorHandler.new
|
30
|
+
|
31
|
+
if block
|
32
|
+
@sink = block
|
33
|
+
else
|
34
|
+
consumer = Consumer.new
|
35
|
+
@sink = consumer.method(:send!)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
# Notes that an event has occurred, along with a distinct_id
|
40
|
+
# representing the source of that event (for example, a user id),
|
41
|
+
# an event name describing the event and a set of properties
|
42
|
+
# describing that event. Properties are provided as a Hash with
|
43
|
+
# string keys and strings, numbers or booleans as values.
|
44
|
+
#
|
45
|
+
# tracker = Greenfinch::Tracker.new(YOUR_GREENFINCH_TOKEN)
|
46
|
+
#
|
47
|
+
# # Track that user "12345"'s credit card was declined
|
48
|
+
# tracker.track("12345", "Credit Card Declined")
|
49
|
+
#
|
50
|
+
# # Properties describe the circumstances of the event,
|
51
|
+
# # or aspects of the source or user associated with the event
|
52
|
+
# tracker.track("12345", "Welcome Email Sent", {
|
53
|
+
# 'Email Template' => 'Pretty Pink Welcome',
|
54
|
+
# 'User Sign-up Cohort' => 'July 2013'
|
55
|
+
# })
|
56
|
+
def track(distinct_id, event, properties={}, ip=nil)
|
57
|
+
properties = {
|
58
|
+
'user_id' => distinct_id,
|
59
|
+
'time' => Time.now.to_i,
|
60
|
+
'mp_lib' => 'ruby',
|
61
|
+
'$lib_version' => Greenfinch::VERSION,
|
62
|
+
}.merge(properties)
|
63
|
+
properties['ip'] = ip if ip
|
64
|
+
|
65
|
+
data = {
|
66
|
+
'event' => event,
|
67
|
+
'prop' => properties,
|
68
|
+
}
|
69
|
+
|
70
|
+
message = {
|
71
|
+
'data' => data,
|
72
|
+
'jwt_token' => @token,
|
73
|
+
'service_name' => @service_name,
|
74
|
+
'debug' => @debug
|
75
|
+
}
|
76
|
+
|
77
|
+
ret = true
|
78
|
+
|
79
|
+
begin
|
80
|
+
@sink.call(:event, message.to_json)
|
81
|
+
rescue GreenfinchError => e
|
82
|
+
@error_handler.handle(e)
|
83
|
+
ret = false
|
84
|
+
end
|
85
|
+
|
86
|
+
ret
|
87
|
+
end
|
88
|
+
|
89
|
+
# Imports an event that has occurred in the past, along with a distinct_id
|
90
|
+
# representing the source of that event (for example, a user id),
|
91
|
+
# an event name describing the event and a set of properties
|
92
|
+
# describing that event. Properties are provided as a Hash with
|
93
|
+
# string keys and strings, numbers or booleans as values. By default,
|
94
|
+
# we pass the time of the method call as the time the event occured, if you
|
95
|
+
# wish to override this pass a timestamp in the properties hash.
|
96
|
+
#
|
97
|
+
# tracker = Greenfinch::Tracker.new(YOUR_GREENFINCH_TOKEN)
|
98
|
+
#
|
99
|
+
# # Track that user "12345"'s credit card was declined
|
100
|
+
# tracker.import("API_KEY", "12345", "Credit Card Declined")
|
101
|
+
#
|
102
|
+
# # Properties describe the circumstances of the event,
|
103
|
+
# # or aspects of the source or user associated with the event
|
104
|
+
# tracker.import("API_KEY", "12345", "Welcome Email Sent", {
|
105
|
+
# 'Email Template' => 'Pretty Pink Welcome',
|
106
|
+
# 'User Sign-up Cohort' => 'July 2013',
|
107
|
+
# 'time' => 1369353600,
|
108
|
+
# })
|
109
|
+
def import(api_key, distinct_id, event, properties={}, ip=nil)
|
110
|
+
properties = {
|
111
|
+
'distinct_id' => distinct_id,
|
112
|
+
'token' => @token,
|
113
|
+
'time' => Time.now.to_i,
|
114
|
+
'mp_lib' => 'ruby',
|
115
|
+
'$lib_version' => Greenfinch::VERSION,
|
116
|
+
}.merge(properties)
|
117
|
+
properties['ip'] = ip if ip
|
118
|
+
|
119
|
+
data = {
|
120
|
+
'event' => event,
|
121
|
+
'properties' => properties,
|
122
|
+
}
|
123
|
+
|
124
|
+
message = {
|
125
|
+
'data' => data,
|
126
|
+
'api_key' => api_key,
|
127
|
+
}
|
128
|
+
|
129
|
+
ret = true
|
130
|
+
begin
|
131
|
+
@sink.call(:import, message.to_json)
|
132
|
+
rescue GreenfinchError => e
|
133
|
+
@error_handler.handle(e)
|
134
|
+
ret = false
|
135
|
+
end
|
136
|
+
|
137
|
+
ret
|
138
|
+
end
|
139
|
+
end
|
140
|
+
end
|
@@ -0,0 +1,201 @@
|
|
1
|
+
require 'date'
|
2
|
+
require 'json'
|
3
|
+
require 'time'
|
4
|
+
|
5
|
+
require 'greenfinch-ruby/consumer'
|
6
|
+
require 'greenfinch-ruby/error'
|
7
|
+
|
8
|
+
module Greenfinch
|
9
|
+
|
10
|
+
# Handles formatting Greenfinch group updates and
|
11
|
+
# sending them to the consumer. You will rarely need
|
12
|
+
# to instantiate this class directly- to send
|
13
|
+
# group updates, use Greenfinch::Tracker#groups
|
14
|
+
#
|
15
|
+
# tracker = Greenfinch::Tracker.new(YOUR_GREENFINCH_TOKEN)
|
16
|
+
# tracker.groups.set(...) or .set_once(..), or .delete(...) etc.
|
17
|
+
class Groups
|
18
|
+
|
19
|
+
# You likely won't need to instantiate instances of Greenfinch::Groups
|
20
|
+
# directly. The best way to get an instance of Greenfinch::Groups is
|
21
|
+
#
|
22
|
+
# tracker = Greenfinch::Tracker.new(YOUR_GREENFINCH_TOKEN)
|
23
|
+
# tracker.groups # An instance of Greenfinch::Groups
|
24
|
+
#
|
25
|
+
def initialize(token, error_handler=nil, &block)
|
26
|
+
@token = token
|
27
|
+
@error_handler = error_handler || ErrorHandler.new
|
28
|
+
|
29
|
+
if block
|
30
|
+
@sink = block
|
31
|
+
else
|
32
|
+
consumer = Consumer.new
|
33
|
+
@sink = consumer.method(:send!)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
# Sets properties on a group record. Takes a Hash with string
|
38
|
+
# keys, and values that are strings, numbers, booleans, or
|
39
|
+
# DateTimes
|
40
|
+
#
|
41
|
+
# tracker = Greenfinch::Tracker.new(YOUR_GREENFINCH_TOKEN)
|
42
|
+
# # Sets properties on group with id "1234"
|
43
|
+
# tracker.groups.set("GROUP KEY", "1234", {
|
44
|
+
# 'company' => 'Acme',
|
45
|
+
# 'plan' => 'Premium',
|
46
|
+
# 'Sign-Up Date' => DateTime.now
|
47
|
+
# });
|
48
|
+
#
|
49
|
+
# If you provide an ip argument, \Greenfinch will use that
|
50
|
+
# ip address for geolocation (rather than the ip of your server)
|
51
|
+
def set(group_key, group_id, properties, ip=nil, optional_params={})
|
52
|
+
properties = fix_property_dates(properties)
|
53
|
+
message = {
|
54
|
+
'$group_key' => group_key,
|
55
|
+
'$group_id' => group_id,
|
56
|
+
'$set' => properties,
|
57
|
+
}.merge(optional_params)
|
58
|
+
message['$ip'] = ip if ip
|
59
|
+
|
60
|
+
update(message)
|
61
|
+
end
|
62
|
+
|
63
|
+
# set_once works just like #set, but will only change the
|
64
|
+
# value of properties if they are not already present
|
65
|
+
# in the group. That means you can call set_once many times
|
66
|
+
# without changing an original value.
|
67
|
+
#
|
68
|
+
# tracker = Greenfinch::Tracker.new(YOUR_GREENFINCH_TOKEN)
|
69
|
+
# tracker.groups.set_once("GROUP KEY", "1234", {
|
70
|
+
# 'First Login Date': DateTime.now
|
71
|
+
# });
|
72
|
+
#
|
73
|
+
def set_once(group_key, group_id, properties, ip=nil, optional_params={})
|
74
|
+
properties = fix_property_dates(properties)
|
75
|
+
message = {
|
76
|
+
'$group_key' => group_key,
|
77
|
+
'$group_id' => group_id,
|
78
|
+
'$set_once' => properties,
|
79
|
+
}.merge(optional_params)
|
80
|
+
message['$ip'] = ip if ip
|
81
|
+
|
82
|
+
update(message)
|
83
|
+
end
|
84
|
+
|
85
|
+
# Removes a specific value in a list property
|
86
|
+
#
|
87
|
+
# tracker = Greenfinch::Tracker.new(YOUR_GREENFINCH_TOKEN)
|
88
|
+
#
|
89
|
+
# # removes "socks" from the "Items purchased" list property
|
90
|
+
# # for the specified group
|
91
|
+
# tracker.groups.remove("GROUP KEY", "1234", { 'Items purchased' => 'socks' })
|
92
|
+
#
|
93
|
+
def remove(group_key, group_id, properties, ip=nil, optional_params={})
|
94
|
+
properties = fix_property_dates(properties)
|
95
|
+
message = {
|
96
|
+
'$group_key' => group_key,
|
97
|
+
'$group_id' => group_id,
|
98
|
+
'$remove' => properties,
|
99
|
+
}.merge(optional_params)
|
100
|
+
message['$ip'] = ip if ip
|
101
|
+
|
102
|
+
update(message)
|
103
|
+
end
|
104
|
+
|
105
|
+
# Set union on list valued properties.
|
106
|
+
# Associates a list containing all elements of a given list,
|
107
|
+
# and all elements currently in a list associated with the given
|
108
|
+
# property. After a union, every element in the list associated
|
109
|
+
# with a property will be unique.
|
110
|
+
#
|
111
|
+
# tracker = Greenfinch::Tracker.new(YOUR_GREENFINCH_TOKEN)
|
112
|
+
# tracker.groups.union("GROUP KEY", "1234", {
|
113
|
+
# 'Levels Completed' => ['Suffragette City']
|
114
|
+
# });
|
115
|
+
#
|
116
|
+
def union(group_key, group_id, properties, ip=nil, optional_params={})
|
117
|
+
properties = fix_property_dates(properties)
|
118
|
+
message = {
|
119
|
+
'$group_key' => group_key,
|
120
|
+
'$group_id' => group_id,
|
121
|
+
'$union' => properties,
|
122
|
+
}.merge(optional_params)
|
123
|
+
message['$ip'] = ip if ip
|
124
|
+
|
125
|
+
update(message)
|
126
|
+
end
|
127
|
+
|
128
|
+
# Removes properties and their values from a group.
|
129
|
+
#
|
130
|
+
# tracker = Greenfinch::Tracker.new(YOUR_GREENFINCH_TOKEN)
|
131
|
+
#
|
132
|
+
# # removes a single property and its value from a group
|
133
|
+
# tracker.groups.unset("GROUP KEY", "1234", "Overdue Since")
|
134
|
+
#
|
135
|
+
# # removes multiple properties and their values from a group
|
136
|
+
# tracker.groups.unset("GROUP KEY",
|
137
|
+
# "1234",
|
138
|
+
# ["Overdue Since", "Paid Date"])
|
139
|
+
#
|
140
|
+
def unset(group_key, group_id, properties, ip=nil, optional_params={})
|
141
|
+
properties = [properties] unless properties.is_a?(Array)
|
142
|
+
message = {
|
143
|
+
'$group_key' => group_key,
|
144
|
+
'$group_id' => group_id,
|
145
|
+
'$unset' => properties,
|
146
|
+
}.merge(optional_params)
|
147
|
+
message['$ip'] = ip if ip
|
148
|
+
|
149
|
+
update(message)
|
150
|
+
end
|
151
|
+
|
152
|
+
# Permanently delete a group from \Greenfinch groups analytics (all group
|
153
|
+
# properties on events stay)
|
154
|
+
def delete_group(group_key, group_id, optional_params={})
|
155
|
+
update({
|
156
|
+
'$group_key' => group_key,
|
157
|
+
'$group_id' => group_id,
|
158
|
+
'$delete' => '',
|
159
|
+
}.merge(optional_params))
|
160
|
+
end
|
161
|
+
|
162
|
+
# Send a generic update to \Greenfinch groups analytics.
|
163
|
+
# Caller is responsible for formatting the update message, as
|
164
|
+
# documented in the \Greenfinch HTTP specification, and passing
|
165
|
+
# the message as a dict to #update. This
|
166
|
+
# method might be useful if you want to use very new
|
167
|
+
# or experimental features of groups analytics from Ruby
|
168
|
+
# The \Greenfinch HTTP tracking API is documented at
|
169
|
+
# https://greenfinch.com/help/reference/http
|
170
|
+
def update(message)
|
171
|
+
data = {
|
172
|
+
'$token' => @token,
|
173
|
+
'$time' => ((Time.now.to_f) * 1000.0).to_i,
|
174
|
+
}.merge(message)
|
175
|
+
|
176
|
+
message = {'data' => data}
|
177
|
+
|
178
|
+
ret = true
|
179
|
+
begin
|
180
|
+
@sink.call(:group_update, message.to_json)
|
181
|
+
rescue GreenfinchError => e
|
182
|
+
@error_handler.handle(e)
|
183
|
+
ret = false
|
184
|
+
end
|
185
|
+
|
186
|
+
ret
|
187
|
+
end
|
188
|
+
|
189
|
+
private
|
190
|
+
|
191
|
+
def fix_property_dates(properties)
|
192
|
+
properties.inject({}) do |ret, (key, value)|
|
193
|
+
value = value.respond_to?(:new_offset) ? value.new_offset('0') : value
|
194
|
+
value = value.respond_to?(:utc) ? value.utc : value # Handle ActiveSupport::TimeWithZone
|
195
|
+
|
196
|
+
ret[key] = value.respond_to?(:strftime) ? value.strftime('%Y-%m-%dT%H:%M:%S') : value
|
197
|
+
ret
|
198
|
+
end
|
199
|
+
end
|
200
|
+
end
|
201
|
+
end
|
@@ -0,0 +1,254 @@
|
|
1
|
+
require 'date'
|
2
|
+
require 'json'
|
3
|
+
require 'time'
|
4
|
+
|
5
|
+
require 'greenfinch-ruby/consumer'
|
6
|
+
require 'greenfinch-ruby/error'
|
7
|
+
|
8
|
+
module Greenfinch
|
9
|
+
|
10
|
+
# Handles formatting Greenfinch profile updates and
|
11
|
+
# sending them to the consumer. You will rarely need
|
12
|
+
# to instantiate this class directly- to send
|
13
|
+
# profile updates, use Greenfinch::Tracker#people
|
14
|
+
#
|
15
|
+
# tracker = Greenfinch::Tracker.new(YOUR_GREENFINCH_TOKEN)
|
16
|
+
# tracker.people.set(...) # Or .append(..), or track_charge(...) etc.
|
17
|
+
class People
|
18
|
+
|
19
|
+
# You likely won't need to instantiate instances of Greenfinch::People
|
20
|
+
# directly. The best way to get an instance of Greenfinch::People is
|
21
|
+
#
|
22
|
+
# tracker = Greenfinch::Tracker.new(YOUR_GREENFINCH_TOKEN)
|
23
|
+
# tracker.people # An instance of Greenfinch::People
|
24
|
+
#
|
25
|
+
def initialize(token, error_handler=nil, &block)
|
26
|
+
@token = token
|
27
|
+
@error_handler = error_handler || ErrorHandler.new
|
28
|
+
|
29
|
+
if block
|
30
|
+
@sink = block
|
31
|
+
else
|
32
|
+
consumer = Consumer.new
|
33
|
+
@sink = consumer.method(:send!)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
# Sets properties on a user record. Takes a Hash with string
|
38
|
+
# keys, and values that are strings, numbers, booleans, or
|
39
|
+
# DateTimes
|
40
|
+
#
|
41
|
+
# tracker = Greenfinch::Tracker.new(YOUR_GREENFINCH_TOKEN)
|
42
|
+
# # Sets properties on profile with id "1234"
|
43
|
+
# tracker.people.set("1234", {
|
44
|
+
# 'company' => 'Acme',
|
45
|
+
# 'plan' => 'Premium',
|
46
|
+
# 'Sign-Up Date' => DateTime.now
|
47
|
+
# });
|
48
|
+
#
|
49
|
+
# If you provide an ip argument, \Greenfinch will use that
|
50
|
+
# ip address for geolocation (rather than the ip of your server)
|
51
|
+
def set(distinct_id, properties, ip=nil, optional_params={})
|
52
|
+
properties = fix_property_dates(properties)
|
53
|
+
message = {
|
54
|
+
'$distinct_id' => distinct_id,
|
55
|
+
'$set' => properties,
|
56
|
+
}.merge(optional_params)
|
57
|
+
message['$ip'] = ip if ip
|
58
|
+
|
59
|
+
update(message)
|
60
|
+
end
|
61
|
+
|
62
|
+
# set_once works just like #set, but will only change the
|
63
|
+
# value of properties if they are not already present
|
64
|
+
# in the profile. That means you can call set_once many times
|
65
|
+
# without changing an original value.
|
66
|
+
#
|
67
|
+
# tracker = Greenfinch::Tracker.new(YOUR_GREENFINCH_TOKEN)
|
68
|
+
# tracker.people.set_once("12345", {
|
69
|
+
# 'First Login Date': DateTime.now
|
70
|
+
# });
|
71
|
+
#
|
72
|
+
def set_once(distinct_id, properties, ip=nil, optional_params={})
|
73
|
+
properties = fix_property_dates(properties)
|
74
|
+
message = {
|
75
|
+
'$distinct_id' => distinct_id,
|
76
|
+
'$set_once' => properties,
|
77
|
+
}.merge(optional_params)
|
78
|
+
message['$ip'] = ip if ip
|
79
|
+
|
80
|
+
update(message)
|
81
|
+
end
|
82
|
+
|
83
|
+
# Changes the value of properties by a numeric amount. Takes a
|
84
|
+
# hash with string keys and numeric properties. \Greenfinch will add
|
85
|
+
# the given amount to whatever value is currently assigned to the
|
86
|
+
# property. If no property exists with a given name, the value
|
87
|
+
# will be added to zero.
|
88
|
+
#
|
89
|
+
# tracker = Greenfinch::Tracker.new(YOUR_GREENFINCH_TOKEN)
|
90
|
+
# tracker.people.increment("12345", {
|
91
|
+
# 'Coins Spent' => 7,
|
92
|
+
# 'Coins Earned' => -7, # Use a negative number to subtract
|
93
|
+
# });
|
94
|
+
#
|
95
|
+
def increment(distinct_id, properties, ip=nil, optional_params={})
|
96
|
+
properties = fix_property_dates(properties)
|
97
|
+
message = {
|
98
|
+
'$distinct_id' => distinct_id,
|
99
|
+
'$add' => properties,
|
100
|
+
}.merge(optional_params)
|
101
|
+
message['$ip'] = ip if ip
|
102
|
+
|
103
|
+
update(message)
|
104
|
+
end
|
105
|
+
|
106
|
+
# Convenience method- increases the value of a numeric property
|
107
|
+
# by one. Calling #plus_one(distinct_id, property_name) is the same as calling
|
108
|
+
# #increment(distinct_id, {property_name => 1})
|
109
|
+
#
|
110
|
+
# tracker = Greenfinch::Tracker.new(YOUR_GREENFINCH_TOKEN)
|
111
|
+
# tracker.people.plus_one("12345", "Albums Released")
|
112
|
+
#
|
113
|
+
def plus_one(distinct_id, property_name, ip=nil, optional_params={})
|
114
|
+
increment(distinct_id, {property_name => 1}, ip, optional_params)
|
115
|
+
end
|
116
|
+
|
117
|
+
# Appends a values to the end of list-valued properties.
|
118
|
+
# If the given properties don't exist, a new list-valued
|
119
|
+
# property will be created.
|
120
|
+
#
|
121
|
+
# tracker = Greenfinch::Tracker.new(YOUR_GREENFINCH_TOKEN)
|
122
|
+
# tracker.people.append("12345", {
|
123
|
+
# 'Login Dates' => DateTime.now,
|
124
|
+
# 'Alter Ego Names' => 'Ziggy Stardust'
|
125
|
+
# });
|
126
|
+
#
|
127
|
+
def append(distinct_id, properties, ip=nil, optional_params={})
|
128
|
+
properties = fix_property_dates(properties)
|
129
|
+
message = {
|
130
|
+
'$distinct_id' => distinct_id,
|
131
|
+
'$append' => properties,
|
132
|
+
}.merge(optional_params)
|
133
|
+
message['$ip'] = ip if ip
|
134
|
+
|
135
|
+
update(message)
|
136
|
+
end
|
137
|
+
|
138
|
+
# Set union on list valued properties.
|
139
|
+
# Associates a list containing all elements of a given list,
|
140
|
+
# and all elements currently in a list associated with the given
|
141
|
+
# property. After a union, every element in the list associated
|
142
|
+
# with a property will be unique.
|
143
|
+
#
|
144
|
+
# tracker = Greenfinch::Tracker.new(YOUR_GREENFINCH_TOKEN)
|
145
|
+
# tracker.people.union("12345", {
|
146
|
+
# 'Levels Completed' => ['Suffragette City']
|
147
|
+
# });
|
148
|
+
#
|
149
|
+
def union(distinct_id, properties, ip=nil, optional_params={})
|
150
|
+
properties = fix_property_dates(properties)
|
151
|
+
message = {
|
152
|
+
'$distinct_id' => distinct_id,
|
153
|
+
'$union' => properties,
|
154
|
+
}.merge(optional_params)
|
155
|
+
message['$ip'] = ip if ip
|
156
|
+
|
157
|
+
update(message)
|
158
|
+
end
|
159
|
+
|
160
|
+
# Removes properties and their values from a profile.
|
161
|
+
#
|
162
|
+
# tracker = Greenfinch::Tracker.new(YOUR_GREENFINCH_TOKEN)
|
163
|
+
#
|
164
|
+
# # removes a single property and its value from a profile
|
165
|
+
# tracker.people.unset("12345", "Overdue Since")
|
166
|
+
#
|
167
|
+
# # removes multiple properties and their values from a profile
|
168
|
+
# tracker.people.unset("12345", ["Overdue Since", "Paid Date"])
|
169
|
+
#
|
170
|
+
def unset(distinct_id, properties, ip=nil, optional_params={})
|
171
|
+
properties = [properties] unless properties.is_a?(Array)
|
172
|
+
message = {
|
173
|
+
'$distinct_id' => distinct_id,
|
174
|
+
'$unset' => properties,
|
175
|
+
}.merge(optional_params)
|
176
|
+
message['$ip'] = ip if ip
|
177
|
+
|
178
|
+
update(message)
|
179
|
+
end
|
180
|
+
|
181
|
+
# Records a payment to you to a profile. Charges recorded with
|
182
|
+
# #track_charge will appear in the \Greenfinch revenue report.
|
183
|
+
#
|
184
|
+
# tracker = Greenfinch::Tracker.new(YOUR_GREENFINCH_TOKEN)
|
185
|
+
#
|
186
|
+
# # records a charge of $25.32 from user 12345
|
187
|
+
# tracker.people.track_charge("12345", 25.32)
|
188
|
+
#
|
189
|
+
# # records a charge of $30.50 on the 2nd of January,
|
190
|
+
# greenfinch.people.track_charge("12345", 30.50, {
|
191
|
+
# '$time' => DateTime.parse("Jan 2 2013")
|
192
|
+
# })
|
193
|
+
#
|
194
|
+
def track_charge(distinct_id, amount, properties={}, ip=nil, optional_params={})
|
195
|
+
properties = fix_property_dates(properties)
|
196
|
+
charge_properties = properties.merge({'$amount' => amount})
|
197
|
+
append(distinct_id, {'$transactions' => charge_properties}, ip, optional_params)
|
198
|
+
end
|
199
|
+
|
200
|
+
# Clear all charges from a \Greenfinch people profile
|
201
|
+
def clear_charges(distinct_id, ip=nil, optional_params={})
|
202
|
+
unset(distinct_id, '$transactions', ip, optional_params)
|
203
|
+
end
|
204
|
+
|
205
|
+
# Permanently delete a profile from \Greenfinch people analytics
|
206
|
+
# To delete a user and ignore alias pass into optional params
|
207
|
+
# {"$ignore_alias"=>true}
|
208
|
+
def delete_user(distinct_id, optional_params={})
|
209
|
+
update({
|
210
|
+
'$distinct_id' => distinct_id,
|
211
|
+
'$delete' => '',
|
212
|
+
}.merge(optional_params))
|
213
|
+
end
|
214
|
+
|
215
|
+
# Send a generic update to \Greenfinch people analytics.
|
216
|
+
# Caller is responsible for formatting the update message, as
|
217
|
+
# documented in the \Greenfinch HTTP specification, and passing
|
218
|
+
# the message as a dict to #update. This
|
219
|
+
# method might be useful if you want to use very new
|
220
|
+
# or experimental features of people analytics from Ruby
|
221
|
+
# The \Greenfinch HTTP tracking API is documented at
|
222
|
+
# https://greenfinch.com/help/reference/http
|
223
|
+
def update(message)
|
224
|
+
data = {
|
225
|
+
'$token' => @token,
|
226
|
+
'$time' => ((Time.now.to_f) * 1000.0).to_i,
|
227
|
+
}.merge(message)
|
228
|
+
|
229
|
+
message = {'data' => data}
|
230
|
+
|
231
|
+
ret = true
|
232
|
+
begin
|
233
|
+
@sink.call(:profile_update, message.to_json)
|
234
|
+
rescue GreenfinchError => e
|
235
|
+
@error_handler.handle(e)
|
236
|
+
ret = false
|
237
|
+
end
|
238
|
+
|
239
|
+
ret
|
240
|
+
end
|
241
|
+
|
242
|
+
private
|
243
|
+
|
244
|
+
def fix_property_dates(properties)
|
245
|
+
properties.inject({}) do |ret, (key, value)|
|
246
|
+
value = value.respond_to?(:new_offset) ? value.new_offset('0') : value
|
247
|
+
value = value.respond_to?(:utc) ? value.utc : value # Handle ActiveSupport::TimeWithZone
|
248
|
+
|
249
|
+
ret[key] = value.respond_to?(:strftime) ? value.strftime('%Y-%m-%dT%H:%M:%S') : value
|
250
|
+
ret
|
251
|
+
end
|
252
|
+
end
|
253
|
+
end
|
254
|
+
end
|