klaviyo 1.2.0 → 2.0.1
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 +5 -5
- data/klaviyo.gemspec +5 -5
- data/lib/klaviyo/apis/lists.rb +166 -0
- data/lib/klaviyo/apis/metrics.rb +82 -0
- data/lib/klaviyo/apis/profiles.rb +55 -0
- data/lib/klaviyo/apis/public.rb +74 -0
- data/lib/klaviyo/client.rb +72 -54
- data/lib/klaviyo/klaviyo_module.rb +23 -0
- data/lib/klaviyo.rb +1 -1
- data/lib/rack/klaviyo.rb +1 -0
- metadata +24 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: a6eaa11bdc826d37a755546d9cb771a469ff9039
|
4
|
+
data.tar.gz: 9f599d1c47bc281311a8adeb5f0c90e8467e4b65
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9a9ddabcb4a51a640a3f6b265d329a77934a5146803a4e4c67482fe4fbb7589e8dc722c193c55a7ae547ef917da6a61ad44e666442f7107f0963affdb8af7166
|
7
|
+
data.tar.gz: a04c3224f53c41f732e99f423b0e0e895772b3edd87b2824b179aec24f14c258f12f541631d035550fab32241f43558d04dd92b159fb9145e83d76737ee36d5b
|
data/klaviyo.gemspec
CHANGED
@@ -1,18 +1,18 @@
|
|
1
|
-
files = ['klaviyo.gemspec', '{lib}
|
1
|
+
files = ['klaviyo.gemspec', '{lib}/**/**/*'].map {|f| Dir[f]}.flatten
|
2
2
|
|
3
3
|
Gem::Specification.new do |s|
|
4
4
|
s.name = 'klaviyo'
|
5
|
-
s.version = '
|
6
|
-
s.date = '2020-
|
5
|
+
s.version = '2.0.1'
|
6
|
+
s.date = '2020-11-23'
|
7
7
|
s.summary = 'You heard us, a Ruby wrapper for the Klaviyo API'
|
8
8
|
s.description = 'Ruby wrapper for the Klaviyo API'
|
9
9
|
s.authors = ['Klaviyo Team']
|
10
|
-
s.email = '
|
10
|
+
s.email = 'libraries@klaviyo.com'
|
11
11
|
s.files = files
|
12
12
|
s.homepage = 'https://www.klaviyo.com/'
|
13
13
|
s.require_path = 'lib'
|
14
|
-
s.has_rdoc = false
|
15
14
|
s.add_dependency 'json'
|
16
15
|
s.add_dependency 'rack'
|
17
16
|
s.add_dependency 'escape'
|
17
|
+
s.add_dependency 'faraday'
|
18
18
|
end
|
@@ -0,0 +1,166 @@
|
|
1
|
+
module Klaviyo
|
2
|
+
class Lists < Client
|
3
|
+
EXCLUSIONS = 'exclusions'
|
4
|
+
GROUP = 'group'
|
5
|
+
LIST = 'list'
|
6
|
+
LISTS = 'lists'
|
7
|
+
MEMBERS = 'members'
|
8
|
+
SUBSCRIBE = 'subscribe'
|
9
|
+
|
10
|
+
# Creates a new list
|
11
|
+
# @param list_name [String] the list name
|
12
|
+
# @return will return with HTTP OK on success
|
13
|
+
def self.create_list(list_name)
|
14
|
+
body = {
|
15
|
+
:list_name => list_name
|
16
|
+
}
|
17
|
+
v2_request(HTTP_POST, LISTS, body)
|
18
|
+
end
|
19
|
+
|
20
|
+
# Retrieves all the lists in the Klaviyo account
|
21
|
+
# @return [List] a list of JSON objects of the name and id for each list
|
22
|
+
def self.get_lists()
|
23
|
+
v2_request(HTTP_GET, LISTS)
|
24
|
+
end
|
25
|
+
|
26
|
+
# Retrieves the details of the list
|
27
|
+
# @param list_id [String] the id of the list
|
28
|
+
# @return [JSON] a JSON object containing information about the list
|
29
|
+
def self.get_list_details(list_id)
|
30
|
+
path = "#{LIST}/#{list_id}"
|
31
|
+
v2_request(HTTP_GET, path)
|
32
|
+
end
|
33
|
+
|
34
|
+
# Updates the properties of a list
|
35
|
+
# @param list_id [String] the id of the list
|
36
|
+
# @param list_name [String] the new name of the list
|
37
|
+
# @return will return with HTTP OK on success
|
38
|
+
def self.update_list_details(list_id, list_name)
|
39
|
+
path = "#{LIST}/#{list_id}"
|
40
|
+
body = {
|
41
|
+
:list_name => list_name
|
42
|
+
}
|
43
|
+
v2_request(HTTP_PUT, path, body)
|
44
|
+
end
|
45
|
+
|
46
|
+
# Deletes a list
|
47
|
+
# @param list_id [String] the id of the list
|
48
|
+
# @return will return with HTTP OK on success
|
49
|
+
def self.delete_list(list_id)
|
50
|
+
path = "#{LIST}/#{list_id}"
|
51
|
+
v2_request(HTTP_DELETE, path)
|
52
|
+
end
|
53
|
+
|
54
|
+
# Check if profiles are in a list and not supressed
|
55
|
+
# @param list_id [String] the id of the list
|
56
|
+
# @param :emails [List] the emails of the profiles to check
|
57
|
+
# @param :phone_numbers [List] the phone numbers of the profiles to check
|
58
|
+
# @param :push_tokens [List] push tokens of the profiles to check
|
59
|
+
# @return A list of JSON objects of the profiles. Profiles that are
|
60
|
+
# supressed or not found are not included.
|
61
|
+
def self.check_list_subscriptions(list_id, emails: [], phone_numbers: [], push_tokens: [])
|
62
|
+
path = "#{LIST}/#{list_id}/#{SUBSCRIBE}"
|
63
|
+
params = {
|
64
|
+
:emails => emails,
|
65
|
+
:phone_numbers => phone_numbers,
|
66
|
+
:push_tokens => push_tokens
|
67
|
+
}
|
68
|
+
v2_request(HTTP_GET, path, params)
|
69
|
+
end
|
70
|
+
|
71
|
+
# Subscribe profiles to a list.
|
72
|
+
# @param list_id [String] the id of the list
|
73
|
+
# @param profiles [List] a list of JSON objects. Each object requires either
|
74
|
+
# an email or phone number key.
|
75
|
+
# @return will retun HTTP OK on success. If the list is single opt-in then a
|
76
|
+
# list of records containing the email address, phone number, push token,
|
77
|
+
# and the corresponding profile ID will also be included.
|
78
|
+
def self.add_subscribers_to_list(list_id, profiles: [])
|
79
|
+
path = "#{LIST}/#{list_id}/#{SUBSCRIBE}"
|
80
|
+
params = {
|
81
|
+
:profiles => profiles
|
82
|
+
}
|
83
|
+
v2_request(HTTP_POST, path, params)
|
84
|
+
end
|
85
|
+
|
86
|
+
# Unsubscribe and remove profiles from a list
|
87
|
+
# @param list_id [String] the id of the list
|
88
|
+
# @param :emails [List] the emails of the profiles to check
|
89
|
+
# @return will return with HTTP OK on success
|
90
|
+
def self.unsubscribe_from_list(list_id, emails: [])
|
91
|
+
path = "#{LIST}/#{list_id}/#{SUBSCRIBE}"
|
92
|
+
params = {
|
93
|
+
:emails => emails
|
94
|
+
}
|
95
|
+
v2_request(HTTP_DELETE, path, params)
|
96
|
+
end
|
97
|
+
|
98
|
+
# Add profiles to a list
|
99
|
+
# @param list_id [String] the id of the list
|
100
|
+
# @param :profiles [List] A list of JSON objects. Each object is a profile
|
101
|
+
# that will be added to the list
|
102
|
+
# @return will return with HTTP OK on success and a list of records of the
|
103
|
+
# corresponding profile id
|
104
|
+
def self.add_to_list(list_id, profiles: [])
|
105
|
+
path = "#{LIST}/#{list_id}/#{MEMBERS}"
|
106
|
+
params = {
|
107
|
+
:profiles => profiles
|
108
|
+
}
|
109
|
+
v2_request(HTTP_POST, path, params)
|
110
|
+
end
|
111
|
+
|
112
|
+
# Check if profiles are on a list
|
113
|
+
# @param list_id [String] the id of the list
|
114
|
+
# @param :emails [List] the emails of the profiles to check
|
115
|
+
# @param :phone_numbers [List] the phone numbers of the profiles to check
|
116
|
+
# @param :push_tokens [List] push tokens of the profiles to check
|
117
|
+
# @return A list of JSON objects of the profiles. Profiles that are
|
118
|
+
# supressed or not found are not included.
|
119
|
+
def self.check_list_memberships(list_id, emails: [], phone_numbers: [], push_tokens: [])
|
120
|
+
path = "#{LIST}/#{list_id}/#{MEMBERS}"
|
121
|
+
params = {
|
122
|
+
:emails => emails,
|
123
|
+
:phone_numbers => phone_numbers,
|
124
|
+
:push_tokens => push_tokens
|
125
|
+
}
|
126
|
+
v2_request(HTTP_GET, path, params)
|
127
|
+
end
|
128
|
+
|
129
|
+
# Remove profiles from a list
|
130
|
+
# @param list_id [String] the id of the list
|
131
|
+
# @param :emails [List] the emails of the profiles to check
|
132
|
+
# @param :phone_numbers [List] the phone numbers of the profiles to check
|
133
|
+
# @param :push_tokens [List] push tokens of the profiles to check
|
134
|
+
# @return will return with HTTP OK on success
|
135
|
+
def self.remove_from_list(list_id, emails: [], phone_numbers: [], push_tokens: [])
|
136
|
+
path = "#{LIST}/#{list_id}/#{MEMBERS}"
|
137
|
+
params = {
|
138
|
+
:emails => emails,
|
139
|
+
:phone_numbers => phone_numbers,
|
140
|
+
:push_tokens => push_tokens
|
141
|
+
}
|
142
|
+
v2_request(HTTP_DELETE, path, params)
|
143
|
+
end
|
144
|
+
|
145
|
+
# Get all emails, phone numbers, along with reasons for list exclusion
|
146
|
+
# @param list_id [String] the id of the list
|
147
|
+
# @param marker [Integer] a marker from a previous call to get the next batch
|
148
|
+
# @return [List] A list of JSON object for each profile with the reason for exclusion
|
149
|
+
def self.get_list_exclusions(list_id, marker: nil)
|
150
|
+
path = "#{LIST}/#{list_id}/#{EXCLUSIONS}/#{ALL}"
|
151
|
+
params = {
|
152
|
+
:marker => marker
|
153
|
+
}
|
154
|
+
v2_request(HTTP_GET, path, params)
|
155
|
+
end
|
156
|
+
|
157
|
+
# Get all of the emails, phone numbers, and push tokens for profiles in a given list or segment
|
158
|
+
# @param list_id [String] the id of the list
|
159
|
+
# @param marker [Integer] a marker from a previous call to get the next batch
|
160
|
+
# @return [List] A list of JSON objects for each profile with the id, email, phone number, and push token
|
161
|
+
def self.get_group_members(list_id)
|
162
|
+
path = "#{GROUP}/#{list_id}/#{MEMBERS}/#{ALL}"
|
163
|
+
v2_request(HTTP_GET, path)
|
164
|
+
end
|
165
|
+
end
|
166
|
+
end
|
@@ -0,0 +1,82 @@
|
|
1
|
+
module Klaviyo
|
2
|
+
class Metrics < Client
|
3
|
+
EXPORT = 'export'
|
4
|
+
METRIC = 'metric'
|
5
|
+
METRICS = 'metrics'
|
6
|
+
|
7
|
+
# Returns a list of all metrics in Klaviyo
|
8
|
+
# @param page [Integer] which page to return, default 0
|
9
|
+
# @param count [Integer] number of results to return, default 100
|
10
|
+
# @return a dictionary with a data property that contains an array of all the metrics
|
11
|
+
def self.get_metrics(page: DEFAULT_PAGE, count: DEFAULT_COUNT)
|
12
|
+
params = {
|
13
|
+
:page => page,
|
14
|
+
:count => count
|
15
|
+
}
|
16
|
+
v1_request(HTTP_GET, METRICS, params)
|
17
|
+
end
|
18
|
+
|
19
|
+
# Returns a batched timeline of all events in your Klaviyo account.
|
20
|
+
# @param since [Integer or String] either a Unix timestamp or the UUID from a previous request. Default is the current time.
|
21
|
+
# @param count [Integer] number of results to return, default 100
|
22
|
+
# @param sort [String] 'asc' or 'desc', sort order to apply to the timeline. Default is 'desc'.
|
23
|
+
# @return a dictionary with a data property that contains an array of the metrics
|
24
|
+
def self.get_metrics_timeline(since: nil, count: DEFAULT_COUNT, sort: DEFAULT_SORT_DESC)
|
25
|
+
path = "#{METRICS}/#{TIMELINE}"
|
26
|
+
params = {
|
27
|
+
:since => since,
|
28
|
+
:count => count,
|
29
|
+
:sort => sort
|
30
|
+
}
|
31
|
+
v1_request(HTTP_GET, path, params)
|
32
|
+
end
|
33
|
+
|
34
|
+
# Returns a batched timeline for one specific type of metric.
|
35
|
+
# @param metric_id [String] the id of the metric
|
36
|
+
# @param since [Integer or String] either a Unix timestamp or the UUID from a previous request. Default is the current time.
|
37
|
+
# @param count [Integer] number of results to return, default 100
|
38
|
+
# @param sort [String] 'asc' or 'desc', sort order to apply to the timeline. Default is 'desc'.
|
39
|
+
# @return a dictionary with a data property that contains information about what metric the event tracks
|
40
|
+
def self.get_metric_timeline(metric_id, since: nil, count: DEFAULT_COUNT, sort: DEFAULT_SORT_DESC)
|
41
|
+
path = "#{METRIC}/#{metric_id}/#{TIMELINE}"
|
42
|
+
params = {
|
43
|
+
:since => since,
|
44
|
+
:count => count,
|
45
|
+
:sort => sort
|
46
|
+
}
|
47
|
+
v1_request(HTTP_GET, path, params)
|
48
|
+
end
|
49
|
+
|
50
|
+
# Export event data, optionally filtering and segmented on available event properties
|
51
|
+
# @param metric_id [String] the id of the metric
|
52
|
+
# @param start_date [String] Beginning of the timeframe to pull event data for. Default is 1 month ago
|
53
|
+
# @param end_date [String] End of the timeframe to pull event data for. Default is the current day
|
54
|
+
# @param unit [String] Granularity to bucket data points into - one of ‘day’, ‘week’, or ‘month’. Defaults to ‘day’.
|
55
|
+
# @param measurement [String or JSON-encoded list] Type of metric to fetch
|
56
|
+
# @param where [JSON-encoded list] Conditions to use to filter the set of events. A max of 1 condition can be given.
|
57
|
+
# @param by [String] The name of a property to segment the event data on. Where and by parameters cannot be specified at the same time.
|
58
|
+
# @param count [Integer] Maximum number of segments to return. The default value is 25.
|
59
|
+
# @return A dictionary relecting the input request parameters as well as a results property
|
60
|
+
def self.get_metric_export(metric_id,
|
61
|
+
start_date: nil,
|
62
|
+
end_date: nil,
|
63
|
+
unit: nil,
|
64
|
+
measurement: nil,
|
65
|
+
where: nil,
|
66
|
+
by: nil,
|
67
|
+
count: nil
|
68
|
+
)
|
69
|
+
path = "#{METRIC}/#{metric_id}/#{EXPORT}"
|
70
|
+
params = {
|
71
|
+
:start_date => start_date,
|
72
|
+
:end_date => end_date,
|
73
|
+
:unit => unit,
|
74
|
+
:measurement => measurement,
|
75
|
+
:where => where,
|
76
|
+
:by => by,
|
77
|
+
:count => count
|
78
|
+
}
|
79
|
+
v1_request(HTTP_GET, path, params)
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
module Klaviyo
|
2
|
+
class Profiles < Client
|
3
|
+
PERSON = 'person'
|
4
|
+
|
5
|
+
# Retrieve all the data attributes for a Klaviyo Person ID.
|
6
|
+
# @param person_id [String] the id of the profile
|
7
|
+
# @return returns a person object
|
8
|
+
def self.get_person_attributes(person_id)
|
9
|
+
path = "#{PERSON}/#{person_id}"
|
10
|
+
v1_request(HTTP_GET, path)
|
11
|
+
end
|
12
|
+
|
13
|
+
# Add or update one more more attributes for a Person
|
14
|
+
# @param person_id [String] the id of the profile
|
15
|
+
# @param kwargs [Key/value pairs] attributes to add/update in the profile
|
16
|
+
# @return returns the updated person object
|
17
|
+
def self.update_person_attributes(person_id, kwargs = {})
|
18
|
+
path = "#{PERSON}/#{person_id}"
|
19
|
+
v1_request(HTTP_PUT, path, kwargs)
|
20
|
+
end
|
21
|
+
|
22
|
+
# Listing a person's event timeline
|
23
|
+
# @param person_id [String] the id of the profile
|
24
|
+
# @param since [Integer or String] either a Unix timestamp or the UUID from a previous request. Default is the current time.
|
25
|
+
# @param count [Integer] number of results to return, default 100
|
26
|
+
# @param sort [String] 'asc' or 'desc', sort order to apply to the timeline. Default is 'desc'.
|
27
|
+
# @return returns a dictionary containing a list of metric event objects
|
28
|
+
def self.get_person_metrics_timeline(person_id, since: nil, count: DEFAULT_COUNT, sort: DEFAULT_SORT_DESC)
|
29
|
+
path = "#{PERSON}/#{person_id}/#{METRICS}/#{TIMELINE}"
|
30
|
+
params = {
|
31
|
+
:since => since,
|
32
|
+
:count => count,
|
33
|
+
:sort => sort
|
34
|
+
}
|
35
|
+
v1_request(HTTP_GET, path, params)
|
36
|
+
end
|
37
|
+
|
38
|
+
# Listing a person's event timeline for a particular metric
|
39
|
+
# @param person_id [String] the id of the profile
|
40
|
+
# @param metric_id [String] the id of the metric
|
41
|
+
# @param since [Integer or String] either a Unix timestamp or the UUID from a previous request. Default is the current time.
|
42
|
+
# @param count [Integer] number of results to return, default 100
|
43
|
+
# @param sort [String] 'asc' or 'desc', sort order to apply to the timeline. Default is 'desc'.
|
44
|
+
# @return returns a dictionary containing a list of metric event objects
|
45
|
+
def self.get_person_metric_timeline(person_id, metric_id, since: nil, count: DEFAULT_COUNT, sort: DEFAULT_SORT_DESC)
|
46
|
+
path = "#{PERSON}/#{person_id}/#{METRIC}/#{metric_id}/#{TIMELINE}"
|
47
|
+
params = {
|
48
|
+
:since => since,
|
49
|
+
:count => count,
|
50
|
+
:sort => sort
|
51
|
+
}
|
52
|
+
v1_request(HTTP_GET, path, params)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,74 @@
|
|
1
|
+
module Klaviyo
|
2
|
+
class Public < Client
|
3
|
+
# Used for identifying customers and managing profile properties
|
4
|
+
#
|
5
|
+
# @kwarg :id [String] the customer or profile id
|
6
|
+
# @kwarg :email [String] the customer or profile email
|
7
|
+
# @kwarg :properties [Hash] properties of the profile to add or update
|
8
|
+
def self.identify(kwargs = {})
|
9
|
+
defaults = {:id => nil,
|
10
|
+
:email => nil,
|
11
|
+
:properties => {}
|
12
|
+
}
|
13
|
+
kwargs = defaults.merge(kwargs)
|
14
|
+
|
15
|
+
if !check_email_or_id_exists(kwargs)
|
16
|
+
return
|
17
|
+
end
|
18
|
+
|
19
|
+
properties = kwargs[:properties]
|
20
|
+
properties[:email] = kwargs[:email] unless kwargs[:email].to_s.empty?
|
21
|
+
properties[:id] = kwargs[:id] unless kwargs[:id].to_s.empty?
|
22
|
+
|
23
|
+
params = {
|
24
|
+
:token => Klaviyo.public_api_key,
|
25
|
+
:properties => properties
|
26
|
+
}
|
27
|
+
|
28
|
+
public_request(HTTP_GET, 'identify', params)
|
29
|
+
end
|
30
|
+
|
31
|
+
# Used for tracking events and customer behaviors
|
32
|
+
#
|
33
|
+
# @param event [String] the event to track
|
34
|
+
# @kwarg :id [String] the customer or profile id
|
35
|
+
# @kwarg :email [String] the customer or profile email
|
36
|
+
# @kwarg :properties [Hash] properties of the event
|
37
|
+
# @kwargs :customer_properties [Hash] properties of the customer or profile
|
38
|
+
# @kwargs :time [Integer] timestamp of the event
|
39
|
+
def self.track(event, kwargs = {})
|
40
|
+
defaults = {
|
41
|
+
:id => nil,
|
42
|
+
:email => nil,
|
43
|
+
:properties => {},
|
44
|
+
:customer_properties => {},
|
45
|
+
:time => nil
|
46
|
+
}
|
47
|
+
|
48
|
+
kwargs = defaults.merge(kwargs)
|
49
|
+
|
50
|
+
if !check_email_or_id_exists(kwargs)
|
51
|
+
return
|
52
|
+
end
|
53
|
+
|
54
|
+
customer_properties = kwargs[:customer_properties]
|
55
|
+
customer_properties[:email] = kwargs[:email] unless kwargs[:email].to_s.empty?
|
56
|
+
customer_properties[:id] = kwargs[:id] unless kwargs[:id].to_s.empty?
|
57
|
+
|
58
|
+
params = {
|
59
|
+
:token => Klaviyo.public_api_key,
|
60
|
+
:event => event,
|
61
|
+
:properties => kwargs[:properties],
|
62
|
+
:customer_properties => customer_properties
|
63
|
+
}
|
64
|
+
params[:time] = kwargs[:time].to_time.to_i if kwargs[:time]
|
65
|
+
|
66
|
+
public_request(HTTP_GET, 'track', params)
|
67
|
+
end
|
68
|
+
|
69
|
+
def self.track_once(event, kwargs = {})
|
70
|
+
kwargs.update('__track_once__' => true)
|
71
|
+
track(event, kwargs)
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
data/lib/klaviyo/client.rb
CHANGED
@@ -1,77 +1,95 @@
|
|
1
|
-
require 'open-uri'
|
2
|
-
require 'base64'
|
3
|
-
require 'json'
|
4
|
-
|
5
1
|
module Klaviyo
|
6
|
-
class KlaviyoError < StandardError; end
|
7
|
-
|
8
2
|
class Client
|
9
|
-
|
10
|
-
|
3
|
+
BASE_API_URL = 'https://a.klaviyo.com/api'
|
4
|
+
V1_API = 'v1'
|
5
|
+
V2_API = 'v2'
|
11
6
|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
7
|
+
HTTP_DELETE = 'delete'
|
8
|
+
HTTP_GET = 'get'
|
9
|
+
HTTP_POST = 'post'
|
10
|
+
HTTP_PUT = 'put'
|
16
11
|
|
17
|
-
|
18
|
-
|
19
|
-
kwargs = defaults.merge(kwargs)
|
12
|
+
ALL = 'all'
|
13
|
+
TIMELINE = 'timeline'
|
20
14
|
|
21
|
-
|
22
|
-
|
23
|
-
|
15
|
+
DEFAULT_COUNT = 100
|
16
|
+
DEFAULT_PAGE = 0
|
17
|
+
DEFAULT_SORT_DESC = 'desc'
|
24
18
|
|
25
|
-
|
26
|
-
customer_properties[:email] = kwargs[:email] unless kwargs[:email].to_s.empty?
|
27
|
-
customer_properties[:id] = kwargs[:id] unless kwargs[:id].to_s.empty?
|
19
|
+
private
|
28
20
|
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
:
|
34
|
-
:
|
35
|
-
|
36
|
-
|
21
|
+
def self.request(method, path, kwargs = {})
|
22
|
+
check_private_api_key_exists()
|
23
|
+
url = "#{BASE_API_URL}/#{path}"
|
24
|
+
connection = Faraday.new(
|
25
|
+
url: url,
|
26
|
+
headers: {
|
27
|
+
'Content-Type' => 'application/json'
|
28
|
+
})
|
29
|
+
response = connection.send(method) do |req|
|
30
|
+
req.body = kwargs[:body].to_json || nil
|
31
|
+
end
|
32
|
+
end
|
37
33
|
|
38
|
-
|
39
|
-
|
34
|
+
def self.public_request(method, path, kwargs = {})
|
35
|
+
check_public_api_key_exists()
|
36
|
+
params = build_params(kwargs)
|
37
|
+
url = "#{BASE_API_URL}/#{path}?#{params}"
|
38
|
+
res = Faraday.get(url).body
|
40
39
|
end
|
41
40
|
|
42
|
-
def
|
43
|
-
|
44
|
-
|
41
|
+
def self.v1_request(method, path, kwargs = {})
|
42
|
+
defaults = {:page => nil,
|
43
|
+
:count => nil,
|
44
|
+
:since => nil,
|
45
|
+
:sort => nil}
|
46
|
+
params = defaults.merge(kwargs)
|
47
|
+
query_params = encode_params(params)
|
48
|
+
full_url = "#{V1_API}/#{path}?api_key=#{Klaviyo.private_api_key}#{query_params}"
|
49
|
+
request(method, full_url)
|
45
50
|
end
|
46
51
|
|
47
|
-
def
|
48
|
-
|
49
|
-
|
52
|
+
def self.v2_request(method, path, kwargs = {})
|
53
|
+
path = "#{V2_API}/#{path}"
|
54
|
+
key = {
|
55
|
+
"api_key": "#{Klaviyo.private_api_key}"
|
56
|
+
}
|
57
|
+
data = {}
|
58
|
+
data[:body] = key.merge(kwargs)
|
59
|
+
request(method, path, data)
|
60
|
+
end
|
50
61
|
|
62
|
+
def self.build_params(params)
|
63
|
+
"data=#{Base64.encode64(JSON.generate(params)).gsub(/\n/,'')}"
|
64
|
+
end
|
65
|
+
|
66
|
+
def self.check_email_or_id_exists(kwargs)
|
51
67
|
if kwargs[:email].to_s.empty? and kwargs[:id].to_s.empty?
|
52
|
-
raise KlaviyoError.new(
|
68
|
+
raise Klaviyo::KlaviyoError.new(NO_ID_OR_EMAIL_ERROR)
|
69
|
+
else
|
70
|
+
return true
|
53
71
|
end
|
54
|
-
|
55
|
-
properties = kwargs[:properties]
|
56
|
-
properties[:email] = kwargs[:email] unless kwargs[:email].to_s.empty?
|
57
|
-
properties[:id] = kwargs[:id] unless kwargs[:id].to_s.empty?
|
58
|
-
|
59
|
-
params = build_params({
|
60
|
-
:token => @api_key,
|
61
|
-
:properties => properties
|
62
|
-
})
|
63
|
-
request('api/identify', params)
|
64
72
|
end
|
65
73
|
|
66
|
-
|
74
|
+
def self.check_private_api_key_exists()
|
75
|
+
if !Klaviyo.private_api_key
|
76
|
+
raise KlaviyoError.new(NO_PRIVATE_API_KEY_ERROR)
|
77
|
+
end
|
78
|
+
end
|
67
79
|
|
68
|
-
def
|
69
|
-
|
80
|
+
def self.check_public_api_key_exists()
|
81
|
+
if !Klaviyo.public_api_key
|
82
|
+
raise KlaviyoError.new(NO_PUBLIC_API_KEY_ERROR)
|
83
|
+
end
|
70
84
|
end
|
71
85
|
|
72
|
-
def
|
73
|
-
|
74
|
-
|
86
|
+
def self.encode_params(kwargs)
|
87
|
+
kwargs.select!{|k, v| v}
|
88
|
+
params = URI.encode_www_form(kwargs)
|
89
|
+
|
90
|
+
if !params.empty?
|
91
|
+
return "&#{params}"
|
92
|
+
end
|
75
93
|
end
|
76
94
|
end
|
77
95
|
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'open-uri'
|
2
|
+
require 'base64'
|
3
|
+
require 'json'
|
4
|
+
require 'faraday'
|
5
|
+
|
6
|
+
require_relative './client'
|
7
|
+
require_relative 'apis/public'
|
8
|
+
require_relative 'apis/lists'
|
9
|
+
require_relative 'apis/metrics'
|
10
|
+
require_relative 'apis/profiles'
|
11
|
+
|
12
|
+
module Klaviyo
|
13
|
+
class << self
|
14
|
+
attr_accessor :public_api_key
|
15
|
+
attr_accessor :private_api_key
|
16
|
+
end
|
17
|
+
|
18
|
+
class KlaviyoError < StandardError; end
|
19
|
+
|
20
|
+
NO_PRIVATE_API_KEY_ERROR = 'Please provide your Private API key for this request'
|
21
|
+
NO_PUBLIC_API_KEY_ERROR = 'Please provide your Public API key for this request'
|
22
|
+
NO_ID_OR_EMAIL_ERROR = 'You must identify a user by email or ID'
|
23
|
+
end
|
data/lib/klaviyo.rb
CHANGED
@@ -1 +1 @@
|
|
1
|
-
require 'klaviyo/
|
1
|
+
require 'klaviyo/klaviyo_module'
|
data/lib/rack/klaviyo.rb
CHANGED
@@ -55,6 +55,7 @@ module Rack
|
|
55
55
|
<script text="text/javascript">
|
56
56
|
var _learnq = _learnq || [];
|
57
57
|
_learnq.push(['account', '#{@api_key}']);
|
58
|
+
|
58
59
|
(function () {
|
59
60
|
var b = document.createElement('script'); b.type = 'text/javascript'; b.async = true;
|
60
61
|
b.src = ('https:' == document.location.protocol ? 'https://' : 'http://') + 'a.klaviyo.com/media/js/analytics/analytics.js';
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: klaviyo
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 2.0.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Klaviyo Team
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-
|
11
|
+
date: 2020-11-23 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: json
|
@@ -52,15 +52,34 @@ dependencies:
|
|
52
52
|
- - ">="
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: faraday
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :runtime
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
55
69
|
description: Ruby wrapper for the Klaviyo API
|
56
|
-
email:
|
70
|
+
email: libraries@klaviyo.com
|
57
71
|
executables: []
|
58
72
|
extensions: []
|
59
73
|
extra_rdoc_files: []
|
60
74
|
files:
|
61
75
|
- klaviyo.gemspec
|
62
76
|
- lib/klaviyo.rb
|
77
|
+
- lib/klaviyo/apis/lists.rb
|
78
|
+
- lib/klaviyo/apis/metrics.rb
|
79
|
+
- lib/klaviyo/apis/profiles.rb
|
80
|
+
- lib/klaviyo/apis/public.rb
|
63
81
|
- lib/klaviyo/client.rb
|
82
|
+
- lib/klaviyo/klaviyo_module.rb
|
64
83
|
- lib/rack/klaviyo.rb
|
65
84
|
homepage: https://www.klaviyo.com/
|
66
85
|
licenses: []
|
@@ -80,7 +99,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
80
99
|
- !ruby/object:Gem::Version
|
81
100
|
version: '0'
|
82
101
|
requirements: []
|
83
|
-
|
102
|
+
rubyforge_project:
|
103
|
+
rubygems_version: 2.5.1
|
84
104
|
signing_key:
|
85
105
|
specification_version: 4
|
86
106
|
summary: You heard us, a Ruby wrapper for the Klaviyo API
|