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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: ca42f71d0ad66aa987267caa2a80c6211277bd24
4
- data.tar.gz: 3d3334697ff2b0130f90252f7996506cfc601037
3
+ metadata.gz: f20c322826f6e2c97eeb107ed11482d783c30555
4
+ data.tar.gz: ed8f644a6be432c04c74d9c5b7eac502ad2b13b5
5
5
  SHA512:
6
- metadata.gz: e8a4f80d8ad00dc698732e2eae1558cbcb017c93cd43f2eeae88798d4a61090a8ecbdbd34232683f4de73ec1681bce4722ee3e22ff8ea05b42ee06d7a4df7c59
7
- data.tar.gz: 2db5c4d013e7d6b183820ac04bcca622d282d70ff1118113346456646177329d8675e215c0c1bdd45c56c1ed0a91939a6f7aae697ac7a11ce72b594da61c52db
6
+ metadata.gz: a26848c0c3885b018fdd7f9a5455bc6d3ddeae71d43a3d526285e9c18800d44e1107ca34afd88a09683a1e5d686f42e39ad6accc649db2f10e898bb454db1a83
7
+ data.tar.gz: 41a2cc7c7b3ae68dcd40a3f93c6aa60243f179bea8c64d8fc11b2a9e7b097072c75e811ff6a251938998ea2682b92a35bc58a8bc5a131cd8b1764e30771b3bed
@@ -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 |b|
13
- b.headers['Accept'] = 'application/json'
14
- b.request :url_encoded
15
- b.response :logger
16
- b.response :json, content_type: 'application/json'
17
- b.adapter Faraday.default_adapter
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(class_name.to_s.gsub(/\/(.?)/) { "::#{$1.upcase}" }.gsub(/(?:^|_)(.)/) { $1.upcase })
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
- Collection.new(
11
- client.conn.get(
12
- '/api/v1/lists',
13
- api_key: client.api_key,
14
- page: page, count: per
15
- ).body)
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
- Entry.new(
20
- client.conn.get(
21
- "/api/v1/list/#{id}", api_key: client.api_key
22
- ).body)
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
- res = client.conn.post(
27
- '/api/v1/lists',
28
- api_key: client.api_key,
29
- name: name,
30
- list_type: list_type
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
- res = client.conn.put(
37
- "/api/v1/list/#{id}",
38
- api_key: client.api_key,
39
- name: name
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
- res = client.conn.delete(
46
- "/api/v1/list/#{id}",
47
- api_key: client.api_key
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
- client.conn.get(
54
- "/api/v1/list/#{id}/members",
55
- api_key: client.api_key,
56
- email: email
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
- client.conn.get(
62
- "/api/v1/segment/#{segment_id}/members",
63
- api_key: client.api_key,
64
- email: email
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
- client.conn.post(
73
- "/api/v1/list/#{id}/members",
74
- api_key: client.api_key,
75
- email: email,
76
- properties: properties,
77
- confirm_optin: confirm_optin
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
- client.conn.post(
83
- "/api/v1/list/#{id}/members/exclude",
84
- api_key: client.api_key,
85
- email: email,
86
- timestamp: ts
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
@@ -1,5 +1,4 @@
1
1
  require_relative 'lists/api_operations'
2
- require_relative 'lists/collection'
3
2
 
4
3
  module Klaviyo
5
4
  module Lists
@@ -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
- res = client.conn.get(
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
- res = client.conn.get("/api/v1/person/#{id}", api_key: client.api_key)
64
- if res.success?
65
- Person.new(res.body)
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
- client.conn.put(
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
- client.conn.get('/api/v1/email-templates', api_key: client.api_key)
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:)
@@ -1,3 +1,3 @@
1
1
  module Klaviyo
2
- VERSION = "0.7.0"
2
+ VERSION = "0.8.0"
3
3
  end
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.7.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-08 00:00:00.000000000 Z
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
@@ -1,12 +0,0 @@
1
- module Klaviyo
2
- module Lists
3
-
4
- class Entry
5
- attr_reader :data
6
-
7
- def initialize(data)
8
- @data = data
9
- end
10
- end
11
- end
12
- end