parallel588-klaviyo 0.7.0 → 0.8.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/lib/klaviyo/client.rb +44 -7
- data/lib/klaviyo/client_dsl.rb +29 -0
- data/lib/klaviyo/errors.rb +38 -0
- data/lib/klaviyo/lists/api_operations.rb +49 -46
- data/lib/klaviyo/lists.rb +0 -1
- data/lib/klaviyo/people/api_operations.rb +8 -33
- data/lib/klaviyo/resource.rb +62 -0
- data/lib/klaviyo/templates/api_operations.rb +5 -1
- data/lib/klaviyo/version.rb +1 -1
- data/lib/klaviyo.rb +9 -5
- metadata +5 -4
- data/lib/klaviyo/lists/collection.rb +0 -21
- data/lib/klaviyo/lists/entry.rb +0 -12
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f20c322826f6e2c97eeb107ed11482d783c30555
|
4
|
+
data.tar.gz: ed8f644a6be432c04c74d9c5b7eac502ad2b13b5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a26848c0c3885b018fdd7f9a5455bc6d3ddeae71d43a3d526285e9c18800d44e1107ca34afd88a09683a1e5d686f42e39ad6accc649db2f10e898bb454db1a83
|
7
|
+
data.tar.gz: 41a2cc7c7b3ae68dcd40a3f93c6aa60243f179bea8c64d8fc11b2a9e7b097072c75e811ff6a251938998ea2682b92a35bc58a8bc5a131cd8b1764e30771b3bed
|
data/lib/klaviyo/client.rb
CHANGED
@@ -1,7 +1,11 @@
|
|
1
|
+
require_relative 'client_dsl'
|
2
|
+
require_relative 'errors'
|
1
3
|
module Klaviyo
|
2
4
|
API_ENDPOINT = 'https://a.klaviyo.com'
|
3
5
|
|
4
6
|
class Client
|
7
|
+
extend ClientDSL
|
8
|
+
|
5
9
|
attr_reader :api_key, :conn, :token
|
6
10
|
def initialize(api_key, token)
|
7
11
|
@api_key = api_key
|
@@ -9,12 +13,13 @@ module Klaviyo
|
|
9
13
|
@conn = Faraday.new(
|
10
14
|
url: API_ENDPOINT,
|
11
15
|
ssl: { ca_path: Klaviyo::DEFAULT_CA_BUNDLE_PATH }
|
12
|
-
) do |
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
16
|
+
) do |f|
|
17
|
+
f.headers['Accept'] = 'application/json'
|
18
|
+
f.request :url_encoded
|
19
|
+
f.response :logger
|
20
|
+
f.response :json, content_type: 'application/json'
|
21
|
+
f.adapter Faraday.default_adapter
|
22
|
+
f.use Errors::RequestError
|
18
23
|
end
|
19
24
|
end
|
20
25
|
|
@@ -36,10 +41,42 @@ module Klaviyo
|
|
36
41
|
)
|
37
42
|
end
|
38
43
|
|
44
|
+
define_api_method resource: :people, action: :identify
|
45
|
+
define_api_method resource: :people, action: :find
|
46
|
+
define_api_method resource: :people, action: :exclusions
|
47
|
+
define_api_method resource: :people, action: :exclude
|
48
|
+
define_api_method resource: :people, action: :update
|
49
|
+
define_api_method resource: :people, action: :events
|
50
|
+
define_api_method resource: :people, action: :metric_events
|
51
|
+
|
52
|
+
define_api_method resource: :lists, action: :all
|
53
|
+
define_api_method resource: :lists, action: :find
|
54
|
+
define_api_method resource: :lists, action: :create
|
55
|
+
define_api_method resource: :lists, action: :update
|
56
|
+
define_api_method resource: :lists, action: :delete
|
57
|
+
define_api_method resource: :lists, action: :include_member_in_list?
|
58
|
+
define_api_method resource: :lists, action: :include_member_in_segment?
|
59
|
+
define_api_method resource: :lists, action: :subscribe
|
60
|
+
define_api_method resource: :lists, action: :unsubscribe
|
61
|
+
define_api_method resource: :lists, action: :batch_subscribe
|
62
|
+
define_api_method resource: :lists, action: :unsubscribes
|
63
|
+
|
64
|
+
define_api_method resource: :templates, action: :all
|
65
|
+
define_api_method resource: :templates, action: :create
|
66
|
+
define_api_method resource: :templates, action: :update
|
67
|
+
define_api_method resource: :templates, action: :delete
|
68
|
+
define_api_method resource: :templates, action: :clone
|
69
|
+
define_api_method resource: :templates, action: :render
|
70
|
+
define_api_method resource: :templates, action: :render_and_send
|
71
|
+
|
39
72
|
private
|
40
73
|
|
41
74
|
def constantize(class_name)
|
42
|
-
Object.module_eval(
|
75
|
+
Object.module_eval(
|
76
|
+
class_name.to_s.gsub(/\/(.?)/) {
|
77
|
+
"::#{$1.upcase}"
|
78
|
+
}.gsub(/(?:^|_)(.)/) { $1.upcase }
|
79
|
+
)
|
43
80
|
end
|
44
81
|
end
|
45
82
|
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module Klaviyo
|
2
|
+
module ClientDSL
|
3
|
+
def define_api_method(resource:, action:)
|
4
|
+
@@resources ||= {}
|
5
|
+
|
6
|
+
@@resources[resource] ||
|
7
|
+
begin
|
8
|
+
@@resources[resource] = Class.new do
|
9
|
+
class << self
|
10
|
+
attr_accessor :client
|
11
|
+
|
12
|
+
def define_action(resource, action)
|
13
|
+
define_singleton_method action do |*args|
|
14
|
+
client.invoke(resource, action, *args)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
define_method resource do
|
21
|
+
@@resources[resource].client = self
|
22
|
+
@@resources[resource]
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
@@resources[resource].define_action(resource, action)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
module Klaviyo
|
2
|
+
module Errors
|
3
|
+
class KlaviyoError < ::StandardError; end
|
4
|
+
class NotFound < KlaviyoError; end
|
5
|
+
class UnprocessableEntity < KlaviyoError; end
|
6
|
+
class InternalServerError < KlaviyoError; end
|
7
|
+
class NotAuthorized < KlaviyoError; end
|
8
|
+
|
9
|
+
class RequestError < Faraday::Response::Middleware
|
10
|
+
|
11
|
+
def on_complete(env)
|
12
|
+
|
13
|
+
# Ignore any non-error response codes
|
14
|
+
return if (status = env[:status]) < 400
|
15
|
+
case status
|
16
|
+
when 404
|
17
|
+
raise Errors::NotFound, env[:body]
|
18
|
+
when 422
|
19
|
+
raise Errors::UnprocessableEntity, env[:body]
|
20
|
+
when 401
|
21
|
+
raise Errors::NotAuthorized, env[:body]
|
22
|
+
when 407
|
23
|
+
# mimic the behavior that we get with proxy requests with HTTPS
|
24
|
+
raise Faraday::Error::ConnectionFailed, %{407 "Proxy Authentication Required "}
|
25
|
+
else
|
26
|
+
raise Errors::InternalServerError, env[:body] # Treat any other errors as 500
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
#400 Bad request - Request is missing or has a bad parameter.
|
36
|
+
#401 Not Authorized - Request is missing or has an invalid API key.
|
37
|
+
#404 Not Found - The requested resource doesn't exist.
|
38
|
+
#500 Server errors - Something is wrong on Klaviyo's end.
|
@@ -1,5 +1,3 @@
|
|
1
|
-
require_relative 'collection'
|
2
|
-
require_relative 'entry'
|
3
1
|
module Klaviyo
|
4
2
|
module Lists
|
5
3
|
# https://www.klaviyo.com/docs/api/lists
|
@@ -7,61 +5,64 @@ module Klaviyo
|
|
7
5
|
module ApiOperations
|
8
6
|
|
9
7
|
def all(client:, page: 0, per: 50)
|
10
|
-
|
11
|
-
client.conn.get(
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
)
|
8
|
+
Klaviyo::Resource.build_collection(
|
9
|
+
client.conn.get('/api/v1/lists',
|
10
|
+
api_key: client.api_key,
|
11
|
+
page: page, count: per
|
12
|
+
).body
|
13
|
+
)
|
16
14
|
end
|
17
15
|
|
18
16
|
def find(client:, id:)
|
19
|
-
|
20
|
-
client.conn.get(
|
21
|
-
|
22
|
-
|
17
|
+
Klaviyo::Resource.build(
|
18
|
+
client.conn.get("/api/v1/list/#{id}",
|
19
|
+
api_key: client.api_key
|
20
|
+
).body
|
21
|
+
)
|
23
22
|
end
|
24
23
|
|
25
24
|
def create(client:, name:, list_type: 'standart')
|
26
|
-
|
27
|
-
'/api/v1/lists',
|
28
|
-
|
29
|
-
|
30
|
-
|
25
|
+
Klaviyo::Resource.build(
|
26
|
+
client.conn.post('/api/v1/lists',
|
27
|
+
api_key: client.api_key,
|
28
|
+
name: name,
|
29
|
+
list_type: list_type
|
30
|
+
).body
|
31
31
|
)
|
32
|
-
Entry(res.body)
|
33
32
|
end
|
34
33
|
|
35
34
|
def update(client:, id:, name:)
|
36
|
-
|
37
|
-
"/api/v1/list/#{id}",
|
38
|
-
|
39
|
-
|
35
|
+
Klaviyo::Resource.build(
|
36
|
+
client.conn.put("/api/v1/list/#{id}",
|
37
|
+
api_key: client.api_key,
|
38
|
+
name: name
|
39
|
+
).body
|
40
40
|
)
|
41
|
-
Entry.new(res.body)
|
42
41
|
end
|
43
42
|
|
44
43
|
def delete(client:, id:)
|
45
|
-
|
46
|
-
"/api/v1/list/#{id}",
|
47
|
-
|
44
|
+
Klaviyo::Resource.build(
|
45
|
+
client.conn.delete("/api/v1/list/#{id}",
|
46
|
+
api_key: client.api_key
|
47
|
+
).body
|
48
48
|
)
|
49
|
-
Entry.new(res.body)
|
50
49
|
end
|
51
50
|
|
52
51
|
def include_member_in_list?(client:, id:, email:)
|
53
|
-
|
54
|
-
"/api/v1/list/#{id}/members",
|
55
|
-
|
56
|
-
|
52
|
+
Klaviyo::Resource.build_collection(
|
53
|
+
client.conn.get("/api/v1/list/#{id}/members",
|
54
|
+
api_key: client.api_key,
|
55
|
+
email: email
|
56
|
+
).body
|
57
57
|
)
|
58
58
|
end
|
59
59
|
|
60
60
|
def include_member_in_segment?(client:, segment_id:, email:)
|
61
|
-
|
62
|
-
"/api/v1/segment/#{segment_id}/members",
|
63
|
-
|
64
|
-
|
61
|
+
Klaviyo::Resource.build_collection(
|
62
|
+
client.conn.get("/api/v1/segment/#{segment_id}/members",
|
63
|
+
api_key: client.api_key,
|
64
|
+
email: email
|
65
|
+
).body
|
65
66
|
)
|
66
67
|
end
|
67
68
|
|
@@ -69,21 +70,23 @@ module Klaviyo
|
|
69
70
|
# @id - list id
|
70
71
|
#
|
71
72
|
def subscribe(client:, id:, email:, properties: {}, confirm_optin: true)
|
72
|
-
|
73
|
-
"/api/v1/list/#{id}/members",
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
73
|
+
Klaviyo::Resource.build(
|
74
|
+
client.conn.post("/api/v1/list/#{id}/members",
|
75
|
+
api_key: client.api_key,
|
76
|
+
email: email,
|
77
|
+
properties: properties,
|
78
|
+
confirm_optin: confirm_optin
|
79
|
+
).body
|
78
80
|
)
|
79
81
|
end
|
80
82
|
|
81
83
|
def unsubscribe(client:, id:, email:, ts: Time.now.to_i)
|
82
|
-
|
83
|
-
"/api/v1/list/#{id}/members/exclude",
|
84
|
-
|
85
|
-
|
86
|
-
|
84
|
+
Klaviyo::Resource.build(
|
85
|
+
client.conn.post("/api/v1/list/#{id}/members/exclude",
|
86
|
+
api_key: client.api_key,
|
87
|
+
email: email,
|
88
|
+
timestamp: ts
|
89
|
+
).body
|
87
90
|
)
|
88
91
|
end
|
89
92
|
|
data/lib/klaviyo/lists.rb
CHANGED
@@ -3,38 +3,15 @@ module Klaviyo
|
|
3
3
|
# https://www.klaviyo.com/docs/api/people
|
4
4
|
#
|
5
5
|
module ApiOperations
|
6
|
-
Result = Struct.new(:response) do
|
7
|
-
def success?
|
8
|
-
response.to_s == '1'
|
9
|
-
end
|
10
|
-
end
|
11
|
-
ErrorResult = Struct.new(:response) do
|
12
|
-
def success?; false; end
|
13
|
-
def status; response['status']; end
|
14
|
-
def message; response['message']; end
|
15
|
-
end
|
16
|
-
|
17
|
-
Person = Struct.new(:attrs) do
|
18
|
-
def method_missing(method_name, *arguments, &block)
|
19
|
-
if attrs.key?(method_name.to_s)
|
20
|
-
attrs[method_name.to_s]
|
21
|
-
elsif attrs.key?("$#{method_name}")
|
22
|
-
attrs["$#{method_name}"]
|
23
|
-
else
|
24
|
-
super
|
25
|
-
end
|
26
|
-
end
|
27
|
-
end
|
28
6
|
|
29
7
|
# https://www.klaviyo.com/docs/http-api#people
|
30
8
|
# invoke(:people, :identify, properties: { '$email': 'useremail@ua.com' })
|
31
9
|
#
|
32
10
|
def identify(client:, properties: {})
|
33
|
-
|
11
|
+
client.conn.get(
|
34
12
|
'/api/identify',
|
35
13
|
client.build_params(properties: properties)
|
36
|
-
)
|
37
|
-
Result.new(res.body)
|
14
|
+
).body.to_s == '1'
|
38
15
|
end
|
39
16
|
|
40
17
|
#
|
@@ -60,19 +37,17 @@ module Klaviyo
|
|
60
37
|
end
|
61
38
|
|
62
39
|
def find(client:, id:)
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
else
|
67
|
-
ErrorResult.new(res.body)
|
68
|
-
end
|
40
|
+
Klaviyo::Resource.build(
|
41
|
+
client.conn.get("/api/v1/person/#{id}", api_key: client.api_key).body
|
42
|
+
)
|
69
43
|
end
|
70
44
|
|
71
45
|
def update(client:, id:, attrs: {})
|
72
|
-
|
46
|
+
Klaviyo::Resource.build(
|
47
|
+
client.conn.put(
|
73
48
|
"/api/v1/person/#{id}",
|
74
49
|
{ api_key: client.api_key }.merge(attrs)
|
75
|
-
)
|
50
|
+
).body)
|
76
51
|
end
|
77
52
|
|
78
53
|
def events(client:, id:, sort: 'desc', per: 100, since: Time.now.to_i)
|
@@ -0,0 +1,62 @@
|
|
1
|
+
module Klaviyo
|
2
|
+
module Resource
|
3
|
+
KlaviyoObject = Struct.new(:attrs) do
|
4
|
+
def method_missing(method_name, *arguments, &block)
|
5
|
+
if attrs.key?(method_name.to_s) || attrs.key?("$#{method_name}")
|
6
|
+
attr_value = attrs[method_name.to_s] || attrs["$#{method_name}"]
|
7
|
+
if attr_value.is_a?(Hash) &&
|
8
|
+
attr_value.key?('object') && attr_value.key?('id')
|
9
|
+
attrs[method_name.to_s] = Klaviyo::Resource.build(attr_value)
|
10
|
+
else
|
11
|
+
attr_value
|
12
|
+
end
|
13
|
+
else
|
14
|
+
super
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
class KlaviyoCollection
|
20
|
+
include Enumerable
|
21
|
+
|
22
|
+
attr_reader :meta, :items
|
23
|
+
|
24
|
+
def initialize(data)
|
25
|
+
@items = data.delete('data').map { |attrs| Klaviyo::Resource.build(attrs) }
|
26
|
+
@meta = data
|
27
|
+
end
|
28
|
+
|
29
|
+
def each(&blk)
|
30
|
+
item.each(&blk)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
class Person < KlaviyoObject; end
|
35
|
+
class List < KlaviyoObject; end
|
36
|
+
class Folder < KlaviyoObject; end
|
37
|
+
class Membership < KlaviyoObject; end
|
38
|
+
|
39
|
+
def self.build(attrs)
|
40
|
+
|
41
|
+
object = attrs.delete('object')
|
42
|
+
case object.to_s
|
43
|
+
when 'person'
|
44
|
+
Person.new(attrs)
|
45
|
+
when 'list'
|
46
|
+
List.new(attrs)
|
47
|
+
when 'folder'
|
48
|
+
Folder.new(attrs)
|
49
|
+
when 'membership'
|
50
|
+
Membership.new(attrs)
|
51
|
+
else
|
52
|
+
KlaviyoObject.new(attrs)
|
53
|
+
end
|
54
|
+
|
55
|
+
end
|
56
|
+
|
57
|
+
def self.build_collection(data)
|
58
|
+
KlaviyoCollection.new(data)
|
59
|
+
end
|
60
|
+
|
61
|
+
end
|
62
|
+
end
|
@@ -5,7 +5,11 @@ module Klaviyo
|
|
5
5
|
module ApiOperations
|
6
6
|
|
7
7
|
def all(client:)
|
8
|
-
|
8
|
+
Klaviyo::Resource.build_collection(
|
9
|
+
client.conn.get('/api/v1/email-templates',
|
10
|
+
api_key: client.api_key
|
11
|
+
).body
|
12
|
+
)
|
9
13
|
end
|
10
14
|
|
11
15
|
def create(client:, name:, html:)
|
data/lib/klaviyo/version.rb
CHANGED
data/lib/klaviyo.rb
CHANGED
@@ -1,9 +1,4 @@
|
|
1
1
|
require 'klaviyo/version'
|
2
|
-
require 'klaviyo/client'
|
3
|
-
require 'klaviyo/templates'
|
4
|
-
require 'klaviyo/lists'
|
5
|
-
require 'klaviyo/event'
|
6
|
-
require 'klaviyo/people'
|
7
2
|
|
8
3
|
require 'active_support'
|
9
4
|
require 'active_support/core_ext'
|
@@ -12,6 +7,15 @@ require 'faraday_middleware'
|
|
12
7
|
require 'json'
|
13
8
|
require 'virtus'
|
14
9
|
|
10
|
+
require 'klaviyo/client'
|
11
|
+
require 'klaviyo/errors'
|
12
|
+
require 'klaviyo/resource'
|
13
|
+
require 'klaviyo/templates'
|
14
|
+
require 'klaviyo/lists'
|
15
|
+
require 'klaviyo/event'
|
16
|
+
require 'klaviyo/people'
|
17
|
+
|
18
|
+
|
15
19
|
|
16
20
|
module Klaviyo
|
17
21
|
DEFAULT_CA_BUNDLE_PATH = File.dirname(__FILE__) + '/data'
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: parallel588-klaviyo
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.8.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Maxim Pechnikov
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-04-
|
11
|
+
date: 2016-04-09 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: virtus
|
@@ -168,13 +168,14 @@ files:
|
|
168
168
|
- lib/data/ca-certificates.crt
|
169
169
|
- lib/klaviyo.rb
|
170
170
|
- lib/klaviyo/client.rb
|
171
|
+
- lib/klaviyo/client_dsl.rb
|
172
|
+
- lib/klaviyo/errors.rb
|
171
173
|
- lib/klaviyo/event.rb
|
172
174
|
- lib/klaviyo/lists.rb
|
173
175
|
- lib/klaviyo/lists/api_operations.rb
|
174
|
-
- lib/klaviyo/lists/collection.rb
|
175
|
-
- lib/klaviyo/lists/entry.rb
|
176
176
|
- lib/klaviyo/people.rb
|
177
177
|
- lib/klaviyo/people/api_operations.rb
|
178
|
+
- lib/klaviyo/resource.rb
|
178
179
|
- lib/klaviyo/templates.rb
|
179
180
|
- lib/klaviyo/templates/api_operations.rb
|
180
181
|
- lib/klaviyo/version.rb
|
@@ -1,21 +0,0 @@
|
|
1
|
-
require_relative 'entry'
|
2
|
-
module Klaviyo
|
3
|
-
module Lists
|
4
|
-
|
5
|
-
class Collection
|
6
|
-
attr_reader :data
|
7
|
-
|
8
|
-
def initialize(data)
|
9
|
-
@data = data
|
10
|
-
end
|
11
|
-
|
12
|
-
def items
|
13
|
-
@items ||= data.fetch('data') { [] }.map { |j| Entry.new(j) }
|
14
|
-
end
|
15
|
-
|
16
|
-
def meta
|
17
|
-
@meta ||= data.except('data')
|
18
|
-
end
|
19
|
-
end
|
20
|
-
end
|
21
|
-
end
|