klaviyo_api 1.4.0 → 1.5.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
  SHA256:
3
- metadata.gz: fa973ac50c2f9d84ffea184bbe4ca030c7ff1ffc99fd1a76f0ab51f845140487
4
- data.tar.gz: ac7b1cf169a606910eb51aa5736d92e926c60e5862b710027bdd3fa468af4bed
3
+ metadata.gz: 7f85a155aaaffcfefa023339aabee06627eedd5aafe4aa3bd5585ae5a42ca85e
4
+ data.tar.gz: a83d88200ca420c62c24c53a1b57b4857f7b519bb2954cae6a24022680806e3b
5
5
  SHA512:
6
- metadata.gz: 2776400dcc29ef86aac04acb8c49a64d383e302ade62602666c6bb02d69573bde894ea785e61c045329c234c64d242f60182a043d3cc74729bf84ea35e67863c
7
- data.tar.gz: 6b9b855da870f2de53a3090dcae65269986cb9bc87c5373873fff684fb57e4bb46f585a6ea3955f66d3b38b0b4b5d373a0dea650d8eb510fab36b40729e904a3
6
+ metadata.gz: 9754d0c6d89a3fe4bb128295e45226223b7062afc5eeb2e1a0f4ac2ad51aba410b45d1a2d8b8645c18e1064b67331e425178b60e8105efa530ebfa9adaa5364f
7
+ data.tar.gz: f3dca57bea500ad7289bccef655e2a36272ee64a0865548311aff3cb1b50d791730ab7e982cbd36775cdd08957a9487ae169a0ced35b9c948f5bddf4275e1b42
@@ -1,5 +1,16 @@
1
1
  # CHANGELOG
2
2
 
3
+ ## [1.5.0]
4
+
5
+ ### Added
6
+
7
+ - Support `/v2/list<id>/exclusions/all`
8
+ - MarkerCollections can now return the next page of results
9
+
10
+ ### Changed
11
+
12
+ - `List#members` has been replaced with `ListMember#all_members` and now returns a regular collection instead of an Enumerator
13
+
3
14
  ## [1.4.0]
4
15
 
5
16
  ### Added
@@ -4,7 +4,6 @@ $LOAD_PATH.unshift File.dirname(__FILE__)
4
4
 
5
5
  # gem requires
6
6
  require 'activeresource'
7
- require 'caching_enumerator'
8
7
 
9
8
  # gem extensions
10
9
  require 'active_resource/connection_ext'
@@ -1,3 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'klaviyo_api/collections/paginated_collection'
4
+ require 'klaviyo_api/collections/marker_collection'
5
+
3
6
  Dir.glob("#{File.dirname(__FILE__)}/collections/*").each { |file| require file if file.end_with? '.rb' }
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ module KlaviyoAPI::Collections
4
+ class EventCollection < MarkerCollection
5
+ def next_page_marker_name
6
+ 'since'
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ module KlaviyoAPI::Collections
4
+ class ListExclusionCollection < MarkerCollection
5
+ def next_page_marker_name
6
+ 'marker'
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ module KlaviyoAPI::Collections
4
+ # ListMembershipCollection, as opposed to ListMemberCollection.
5
+ # This is a collection of ListMembers, but _specifically_ in the
6
+ # context of the Group Memberships endpoint of a List.
7
+ # (https://www.klaviyo.com/docs/api/v2/lists#get-members-all)
8
+ class ListMembershipCollection < MarkerCollection
9
+ def next_page
10
+ # Return empty collection if no other pages
11
+ return self.class.new unless more_pages?
12
+
13
+ KlaviyoAPI::ListMember.all_members params: { **first.prefix_options, **original_params, "#{next_page_marker_name}": marker }
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ module KlaviyoAPI::Collections
4
+ # This collection is used for item types that rely on
5
+ # markers to provide pagination.
6
+ class MarkerCollection < ActiveResource::Collection
7
+ attr_accessor :count, :marker, :next
8
+
9
+ def initialize(response = {})
10
+ # May not exist
11
+ @count = response.delete 'count'
12
+
13
+ @next = response['next'] || response['marker']
14
+ @marker = @next
15
+
16
+ @elements = response['data'] || response['records'] || []
17
+ end
18
+
19
+ def next_page_marker_name
20
+ 'marker'
21
+ end
22
+
23
+ def more_pages?
24
+ !@next.nil?
25
+ end
26
+
27
+ def next_page
28
+ # Return empty collection if no other pages
29
+ return self.class.new unless more_pages?
30
+
31
+ first.class.all params: { **first.prefix_options, **original_params, "#{next_page_marker_name}": marker }
32
+ end
33
+ end
34
+ end
@@ -5,14 +5,14 @@ module KlaviyoAPI::Collections
5
5
  # provide `page`, `page_size`, etc.
6
6
  class PaginatedCollection < ActiveResource::Collection
7
7
  attr_accessor :total, :page, :page_size, :start, :end
8
-
8
+
9
9
  def initialize(response = {})
10
- @total = response.delete 'total'
10
+ @total = response.delete 'total'
11
11
  @page = response.delete 'page'
12
12
  @page_size = response.delete 'page_size'
13
13
  @start = response.delete 'start'
14
14
  @end = response.delete 'end'
15
-
15
+
16
16
  @elements = response['data'] || []
17
17
  end
18
18
  end
@@ -9,7 +9,7 @@ module KlaviyoAPI
9
9
 
10
10
  self.element_name = 'timeline'
11
11
  self.collection_name = 'timeline'
12
- self.collection_parser = KlaviyoAPI::Collections::NextMarkerCollection
12
+ self.collection_parser = KlaviyoAPI::Collections::EventCollection
13
13
 
14
14
  class << self
15
15
  def find_single(scope, options)
@@ -5,9 +5,11 @@ module KlaviyoAPI
5
5
  self.prefix += 'v2/'
6
6
  self.primary_key = :list_id
7
7
 
8
+ has_many :exclusions, class_name: 'KlaviyoAPI::ListExclusion'
9
+
8
10
  class << self
9
11
  # Override this from ActiveResource#base in order to inject the id into the response
10
- # because its not returned
12
+ # because it's not returned
11
13
  def find_single(scope, options)
12
14
  super.tap { |record| record.id = scope }
13
15
  end
@@ -20,24 +22,7 @@ module KlaviyoAPI
20
22
  #
21
23
  # https://www.klaviyo.com/docs/api/v2/lists#get-members-all
22
24
  def members(options = {})
23
- CachingEnumerator.new do |yielder|
24
- marker = nil
25
-
26
- loop do
27
- path = "#{self.class.prefix}group/#{id}/members/all"
28
- path += "?marker=#{marker}" if marker
29
-
30
- response = JSON.parse(connection.get(path, self.class.headers).body)
31
- marker = response['marker']
32
- list_members = response['records']
33
-
34
- list_members.each do |list_member|
35
- yielder.yield KlaviyoAPI::ListMember.new list_member
36
- end
37
-
38
- break if marker.nil?
39
- end
40
- end
25
+ KlaviyoAPI::ListMember.all_members params: { list_id: id, **options }
41
26
  end
42
27
  end
43
28
  end
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ module KlaviyoAPI
4
+ class ListExclusion < Base
5
+ self.prefix += 'v2/list/:list_id/'
6
+ self.element_name = 'exclusions/all'
7
+ self.collection_name = 'exclusions/all'
8
+
9
+ self.collection_parser = KlaviyoAPI::Collections::ListExclusionCollection
10
+
11
+ class << self
12
+ def find_single(_scope, _options)
13
+ raise KlaviyoAPI::InvalidOperation, 'Cannot get single Exclusion via API. Please use KlaviyoAPI::ListExclusion#all.'
14
+ end
15
+ end
16
+
17
+ def destroy
18
+ raise KlaviyoAPI::InvalidOperation, 'Cannot delete ListExclusions via API.'
19
+ end
20
+
21
+ def create
22
+ raise KlaviyoAPI::InvalidOperation, 'Cannot create ListExclusions via API.'
23
+ end
24
+
25
+ def update
26
+ raise KlaviyoAPI::InvalidOperation, 'Cannot update ListExclusions via API.'
27
+ end
28
+ end
29
+ end
@@ -2,7 +2,9 @@
2
2
 
3
3
  module KlaviyoAPI
4
4
  class ListMember < Base
5
- self.prefix += 'v2/list/:list_id/'
5
+ ORIGINAL_PREFIX = '/api/v2/list/:list_id/'
6
+ self.prefix = ORIGINAL_PREFIX
7
+
6
8
  self.primary_key = :id
7
9
 
8
10
  # This is always plural
@@ -16,7 +18,7 @@ module KlaviyoAPI
16
18
  #
17
19
  # https://www.klaviyo.com/docs/api/v2/lists#delete-members
18
20
  def delete(email, options = {})
19
- options = options.merge({emails: email})
21
+ options = options.merge emails: email
20
22
  connection.delete(element_path('', options), headers)
21
23
  end
22
24
 
@@ -36,6 +38,31 @@ module KlaviyoAPI
36
38
  end
37
39
  saved_list_members
38
40
  end
41
+
42
+ # As opposed to #all, which hits and requires a list of emails to check for membership,
43
+ # this method hits https://www.klaviyo.com/docs/api/v2/lists#get-members-all and gets all
44
+ # ListMembers for a List.
45
+ def all_members(options)
46
+ # The rest becomes much easier if we temporarily modify the prefix.
47
+ # We set it back later, have no fear.
48
+ self.prefix = '/api/v2/group/:list_id/members/all'
49
+
50
+ prefix_options, query_options = split_options(options[:params])
51
+ path = "#{prefix(prefix_options)}#{format_extension}#{query_string(query_options)}"
52
+
53
+ # Very heavily inspired by `find_every`
54
+ response = format.decode(connection.get(path, headers).body) || []
55
+ collection = KlaviyoAPI::Collections::ListMembershipCollection.new(response).tap do |parser|
56
+ parser.resource_class = self
57
+ parser.original_params = query_options
58
+ end
59
+
60
+ collection.collect! { |record| instantiate_record(record, prefix_options) }
61
+
62
+ self.prefix = ORIGINAL_PREFIX
63
+
64
+ collection
65
+ end
39
66
  end
40
67
 
41
68
  # Adding a single Member to a List does not exist - they must be added as an
@@ -60,12 +87,12 @@ module KlaviyoAPI
60
87
  # https://www.klaviyo.com/docs/api/v2/lists#delete-members
61
88
  def destroy
62
89
  run_callbacks :destroy do
63
- KlaviyoAPI::ListMember.delete self.email, prefix_options
90
+ KlaviyoAPI::ListMember.delete email, prefix_options
64
91
  end
65
92
  end
66
93
 
67
94
  def update
68
- raise KlaviyoAPI::InvalidOperation.new 'Cannot update list members. You might be looking for delete and/or create.'
95
+ raise KlaviyoAPI::InvalidOperation, 'Cannot update list members. You might be looking for delete and/or create.'
69
96
  end
70
97
  end
71
98
  end
@@ -11,12 +11,12 @@ module KlaviyoAPI
11
11
  has_many :events, class_name: 'KlaviyoAPI::Event'
12
12
 
13
13
  class << self
14
- def find_single(scope, options)
14
+ def find_single(_scope, _options)
15
15
  raise KlaviyoAPI::InvalidOperation, 'Cannot get single Metric via API. Please use KlaviyoAPI::Metric#all.'
16
16
  end
17
17
 
18
18
  def collection_path(prefix_options = {}, query_options = {})
19
- super prefix_options, query_options.deep_merge({ api_key: headers['api-key'] })
19
+ super prefix_options, query_options.deep_merge(api_key: headers['api-key'])
20
20
  end
21
21
 
22
22
  # Get all Events for all Metrics
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module KlaviyoAPI
4
- VERSION = '1.4.0'
4
+ VERSION = '1.5.0'
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: klaviyo_api
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.4.0
4
+ version: 1.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - rewind.io
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-04-24 00:00:00.000000000 Z
11
+ date: 2019-04-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activeresource
@@ -24,20 +24,6 @@ dependencies:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
26
  version: 5.1.0
27
- - !ruby/object:Gem::Dependency
28
- name: caching_enumerator
29
- requirement: !ruby/object:Gem::Requirement
30
- requirements:
31
- - - "~>"
32
- - !ruby/object:Gem::Version
33
- version: 0.0.1
34
- type: :runtime
35
- prerelease: false
36
- version_requirements: !ruby/object:Gem::Requirement
37
- requirements:
38
- - - "~>"
39
- - !ruby/object:Gem::Version
40
- version: 0.0.1
41
27
  - !ruby/object:Gem::Dependency
42
28
  name: bundler
43
29
  requirement: !ruby/object:Gem::Requirement
@@ -205,7 +191,10 @@ files:
205
191
  - lib/active_resource/connection_ext.rb
206
192
  - lib/klaviyo_api.rb
207
193
  - lib/klaviyo_api/collections.rb
208
- - lib/klaviyo_api/collections/next_marker_collection.rb
194
+ - lib/klaviyo_api/collections/event_collection.rb
195
+ - lib/klaviyo_api/collections/list_exclusion_collection.rb
196
+ - lib/klaviyo_api/collections/list_membership_collection.rb
197
+ - lib/klaviyo_api/collections/marker_collection.rb
209
198
  - lib/klaviyo_api/collections/paginated_collection.rb
210
199
  - lib/klaviyo_api/configuration.rb
211
200
  - lib/klaviyo_api/connection.rb
@@ -216,6 +205,7 @@ files:
216
205
  - lib/klaviyo_api/resources/base.rb
217
206
  - lib/klaviyo_api/resources/event.rb
218
207
  - lib/klaviyo_api/resources/list.rb
208
+ - lib/klaviyo_api/resources/list_exclusion.rb
219
209
  - lib/klaviyo_api/resources/list_member.rb
220
210
  - lib/klaviyo_api/resources/metric.rb
221
211
  - lib/klaviyo_api/resources/profile.rb
@@ -1,16 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module KlaviyoAPI::Collections
4
- # This collection is used for item types that rely on
5
- # 'next' markers to provide pagination.
6
- class NextMarkerCollection < ActiveResource::Collection
7
- attr_accessor :next, :count
8
-
9
- def initialize(response = {})
10
- @count = response.delete 'count'
11
- @next = response.delete 'next'
12
-
13
- @elements = response['data'] || []
14
- end
15
- end
16
- end