parallel588-klaviyo 0.7.0 → 0.8.0

Sign up to get free protection for your applications and to get access to all the features.
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