mailchimp-rest-api 0.2.0 → 0.3.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
  SHA256:
3
- metadata.gz: cd8e4ac41f0ff072d449fab1c0466bed09d533def2a97db463a0dd76e47aaef2
4
- data.tar.gz: 24fccb0d0eb4175d77055bdd5ce4e935789cbd5b6ed700d17f7d98ab86ada034
3
+ metadata.gz: 428009c6c680a7c4bc6ec3b80fe5e4c1485df70e358928655fefabbf0b76637c
4
+ data.tar.gz: bd8307d56a558d64a4d7a7551a21cacf9dfe1e44036882191421c359c1b2682a
5
5
  SHA512:
6
- metadata.gz: 8cc1fa18308afd486cb4418317f8809d9e2758df9a1ea4087aaea57ba66db3570ae91fc99faccd8472a4663f22800151519b5c4c350f750f275a484c147544fe
7
- data.tar.gz: 0df6d93f8742d35b73372a5b7ce139723102261f046243e77bcb30f90937fa519a93e0c1fd4e267bc67bb5a38c9932907d5a2373a0f27ac49f81d763bd4465f5
6
+ metadata.gz: c3f2cc4b7561902a8ba1991b8acb68be65714a506854adea22cd3d0f1a7fa449aae6cea82267cb55d4b45a9ea7f11f6c4ba41b5e602d8a75ecb6f6f4df8a3102
7
+ data.tar.gz: f4bb0e6175805b8363ed59df417c4f103ee6b70c5bc40dd6003e7f8ac7eaef3ac5ac992a251b055d224981ab6142f9c460e2a0924ce7691bfbf0cc560e922f7f
data/README.md CHANGED
@@ -149,25 +149,19 @@ client = MailchimpAPI::Client.new(
149
149
 
150
150
  ## Pagination
151
151
 
152
- We have two specific methods:
153
-
154
- - `MailchimpAPI#each_page(response)` - iterates over current and each next page
155
- response
156
- - `MailchimpAPI#each_page_item(response, items: :members)` - iterates over
157
- each item (each member in this case)
158
-
159
- Example:
152
+ All REST resources have `#each` method. Example:
160
153
 
161
154
  ```ruby
162
- first_page = MailchimpAPI.audience_members.list(list_id, query: { count: 100 }
155
+ MailchimpAPI.audience_members.each(list_id) { |member| ... }
156
+ MailchimpAPI.audience_member_tags.each(list_id, member_id) { |tag| ... }
157
+ ```
163
158
 
164
- MailchimpAPI.each_page(first_page) do |response|
165
- puts response.body
166
- end
159
+ `Each` method accepts `query`, `body` and `headers` as any other API.
160
+ By default it requests 1000 items on each page, but it is configurable through
161
+ `query` parameter. Example:
167
162
 
168
- MailchimpAPI.each_page_item(first_page, items: :members) do |item|
169
- puts item[:email_address]
170
- end
163
+ ```ruby
164
+ MailchimpAPI.audience_members.each(list_id, query: { count: 100 }) { |member| ... }
171
165
  ```
172
166
 
173
167
  ## Request
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.2.0
1
+ 0.3.0
@@ -6,7 +6,6 @@ module MailchimpAPI
6
6
 
7
7
  include APIMethods
8
8
  include BatchMethods
9
- include PaginationMethods
10
9
 
11
10
  attr_reader :api_key, :api_url, :api_version, :authorization_token, :config
12
11
 
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ module MailchimpAPI
4
+ module Pagination
5
+ module ListEachItemHelper
6
+ private
7
+
8
+ def list_each_item(items_field, *args, query: nil, body: nil, headers: nil, &block)
9
+ return enum_for(:list_each_item, items_field, *args, query: query, body: body, headers: headers) unless block
10
+
11
+ query = PrepareQueryParams.call(query, items_field: items_field)
12
+
13
+ loop do
14
+ response = list(*args, query: query, body: body, headers: headers)
15
+ response.body.fetch(items_field).each(&block)
16
+
17
+ total_received_items_count = query.fetch(:offset) + query.fetch(:count)
18
+ break if total_received_items_count >= response.body.fetch(:total_items)
19
+
20
+ query[:offset] = total_received_items_count
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,45 @@
1
+ # frozen_string_literal: true
2
+
3
+ module MailchimpAPI
4
+ module Pagination
5
+ class PrepareQueryParams
6
+ class << self
7
+ def call(query, items_field:)
8
+ query ||= {}
9
+ query = query.transform_keys(&:to_sym)
10
+
11
+ prepare_offset(query)
12
+ prepare_count(query)
13
+
14
+ ensure_fields_included(query, items_field: items_field, total_field: "total_items")
15
+ ensure_fields_not_excluded(query, items_field: items_field, total_field: "total_items")
16
+ query
17
+ end
18
+
19
+ private
20
+
21
+ def prepare_offset(query)
22
+ query[:offset] = query[:offset].to_i
23
+ end
24
+
25
+ def prepare_count(query)
26
+ query[:count] = query[:count].to_i
27
+ query[:count] = 1000 if query[:count] == 0
28
+ end
29
+
30
+ def ensure_fields_included(query, items_field:, total_field:)
31
+ fields = query[:fields] || ""
32
+ query[:fields] = (fields.split(",") + [items_field.to_s, total_field]).uniq.join(",")
33
+ end
34
+
35
+ def ensure_fields_not_excluded(query, items_field:, total_field:)
36
+ excluded_fields = query[:excluded_fields]
37
+ return unless excluded_fields
38
+
39
+ excluded_fields = (excluded_fields.split(",") - [items_field.to_s, total_field]).join(",")
40
+ excluded_fields.empty? ? query.delete(:excluded_fields) : query[:excluded_fields] = excluded_fields
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
@@ -4,6 +4,8 @@ module MailchimpAPI
4
4
  module Audience
5
5
  class InterestCategories < Resource
6
6
  module APIs
7
+ include Pagination::ListEachItemHelper
8
+
7
9
  def list(list_id, query: nil, body: nil, headers: nil)
8
10
  path = "/lists/#{list_id}/interest-categories"
9
11
  client.get(path, query: query, body: body, headers: headers)
@@ -28,6 +30,10 @@ module MailchimpAPI
28
30
  path = "/lists/#{list_id}/interest-categories/#{interest_category_id}"
29
31
  client.patch(path, query: query, body: body, headers: headers)
30
32
  end
33
+
34
+ def each(list_id, query: nil, body: nil, headers: nil, &block)
35
+ list_each_item(:categories, list_id, query: query, body: body, headers: headers, &block)
36
+ end
31
37
  end
32
38
 
33
39
  include APIs
@@ -4,6 +4,8 @@ module MailchimpAPI
4
4
  module Audience
5
5
  class Interests < Resource
6
6
  module APIs
7
+ include Pagination::ListEachItemHelper
8
+
7
9
  def list(list_id, interest_category_id, query: nil, body: nil, headers: nil)
8
10
  path = "/lists/#{list_id}/interest-categories/#{interest_category_id}/interests"
9
11
  client.get(path, query: query, body: body, headers: headers)
@@ -28,6 +30,10 @@ module MailchimpAPI
28
30
  path = "/lists/#{list_id}/interest-categories/#{interest_category_id}/interests/#{interest_id}"
29
31
  client.patch(path, query: query, body: body, headers: headers)
30
32
  end
33
+
34
+ def each(list_id, interest_category_id, query: nil, body: nil, headers: nil, &block)
35
+ list_each_item(:interests, list_id, interest_category_id, query: query, body: body, headers: headers, &block)
36
+ end
31
37
  end
32
38
 
33
39
  include APIs
@@ -4,6 +4,8 @@ module MailchimpAPI
4
4
  module Audience
5
5
  class MemberTags < Resource
6
6
  module APIs
7
+ include Pagination::ListEachItemHelper
8
+
7
9
  def list(list_id, email, query: nil, body: nil, headers: nil)
8
10
  path = "/lists/#{list_id}/members/#{subscriber_hash(email)}/tags"
9
11
  client.get(path, query: query, body: body, headers: headers)
@@ -13,6 +15,10 @@ module MailchimpAPI
13
15
  path = "/lists/#{list_id}/members/#{subscriber_hash(email)}/tags"
14
16
  client.post(path, query: query, body: body, headers: headers)
15
17
  end
18
+
19
+ def each(list_id, email, query: nil, body: nil, headers: nil, &block)
20
+ list_each_item(:tags, list_id, email, query: query, body: body, headers: headers, &block)
21
+ end
16
22
  end
17
23
 
18
24
  include MailchimpAPI::Audience::Utils
@@ -4,6 +4,8 @@ module MailchimpAPI
4
4
  module Audience
5
5
  class Members < Resource
6
6
  module APIs
7
+ include Pagination::ListEachItemHelper
8
+
7
9
  def list(list_id, query: nil, body: nil, headers: nil)
8
10
  path = "/lists/#{list_id}/members"
9
11
  client.get(path, query: query, body: body, headers: headers)
@@ -38,6 +40,10 @@ module MailchimpAPI
38
40
  path = "/lists/#{list_id}/members/#{subscriber_hash(email)}/actions/delete-permanent"
39
41
  client.post(path, query: query, body: body, headers: headers)
40
42
  end
43
+
44
+ def each(list_id, query: nil, body: nil, headers: nil, &block)
45
+ list_each_item(:members, list_id, query: query, body: body, headers: headers, &block)
46
+ end
41
47
  end
42
48
 
43
49
  include MailchimpAPI::Audience::Utils
@@ -4,6 +4,8 @@ module MailchimpAPI
4
4
  module Audience
5
5
  class Webhooks < Resource
6
6
  module APIs
7
+ include Pagination::ListEachItemHelper
8
+
7
9
  def list(list_id, query: nil, body: nil, headers: nil)
8
10
  path = "/lists/#{list_id}/webhooks"
9
11
  client.get(path, query: query, body: body, headers: headers)
@@ -28,6 +30,10 @@ module MailchimpAPI
28
30
  path = "/lists/#{list_id}/webhooks/#{webhook_id}"
29
31
  client.patch(path, query: query, body: body, headers: headers)
30
32
  end
33
+
34
+ def each(list_id, query: nil, body: nil, headers: nil, &block)
35
+ list_each_item(:webhooks, list_id, query: query, body: body, headers: headers, &block)
36
+ end
31
37
  end
32
38
 
33
39
  include APIs
data/lib/mailchimp-api.rb CHANGED
@@ -49,6 +49,8 @@ module MailchimpAPI
49
49
  end
50
50
  end
51
51
 
52
+ require_relative "mailchimp-api/pagination/list_each_item_helper"
53
+ require_relative "mailchimp-api/pagination/prepare_query_params"
52
54
  require_relative "mailchimp-api/resource"
53
55
  require_relative "mailchimp-api/resources/audience/utils/subscriber_hash"
54
56
  require_relative "mailchimp-api/resources/audience/interest_categories"
@@ -59,7 +61,6 @@ require_relative "mailchimp-api/resources/audience/webhooks"
59
61
  require_relative "mailchimp-api/batch_request"
60
62
  require_relative "mailchimp-api/client/api_methods"
61
63
  require_relative "mailchimp-api/client/batch_methods"
62
- require_relative "mailchimp-api/client/pagination_methods"
63
64
  require_relative "mailchimp-api/client"
64
65
  require_relative "mailchimp-api/config"
65
66
  require_relative "mailchimp-api/error"
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mailchimp-rest-api
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andrey Glushkov
8
8
  bindir: bin
9
9
  cert_chain: []
10
- date: 2025-04-28 00:00:00.000000000 Z
10
+ date: 1980-01-02 00:00:00.000000000 Z
11
11
  dependencies: []
12
12
  description: Marketing Mailchimp REST API with no dependencies.
13
13
  email:
@@ -23,11 +23,12 @@ files:
23
23
  - lib/mailchimp-api/client.rb
24
24
  - lib/mailchimp-api/client/api_methods.rb
25
25
  - lib/mailchimp-api/client/batch_methods.rb
26
- - lib/mailchimp-api/client/pagination_methods.rb
27
26
  - lib/mailchimp-api/config.rb
28
27
  - lib/mailchimp-api/error.rb
29
28
  - lib/mailchimp-api/failed_request_error_builder.rb
30
29
  - lib/mailchimp-api/network_error_builder.rb
30
+ - lib/mailchimp-api/pagination/list_each_item_helper.rb
31
+ - lib/mailchimp-api/pagination/prepare_query_params.rb
31
32
  - lib/mailchimp-api/request.rb
32
33
  - lib/mailchimp-api/request_executor.rb
33
34
  - lib/mailchimp-api/resource.rb
@@ -62,7 +63,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
62
63
  - !ruby/object:Gem::Version
63
64
  version: '0'
64
65
  requirements: []
65
- rubygems_version: 3.6.2
66
+ rubygems_version: 3.6.8
66
67
  specification_version: 4
67
68
  summary: Mailchimp REST API (Marketing)
68
69
  test_files: []
@@ -1,51 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module MailchimpAPI
4
- class Client
5
- module PaginationMethods
6
- # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
7
- def next_page(response)
8
- unless response.body.key?(:total_items)
9
- raise Error, "Please ensure `total_items` field is not excluded from response"
10
- end
11
-
12
- request = response.request
13
- query = request.query
14
-
15
- count = query.key?(:count) ? query[:count].to_i : 10
16
- offset = query.key?(:offset) ? query[:offset].to_i : 0
17
-
18
- body = response.body
19
- total_items = body[:total_items].to_i
20
- is_final_page = ((offset + count) >= total_items)
21
- return if is_final_page
22
-
23
- new_query = query.merge(offset: offset + count, count: count)
24
-
25
- get(
26
- request.path,
27
- query: new_query,
28
- body: request.body,
29
- headers: request.headers
30
- )
31
- end
32
- # rubocop:enable Metrics/AbcSize, Metrics/MethodLength
33
-
34
- def each_page(response, &block)
35
- return enum_for(:each_page, response) unless block
36
-
37
- page = response
38
- yield(page)
39
- yield(page) while (page = next_page(page))
40
- end
41
-
42
- def each_page_item(response, items:, &block)
43
- return enum_for(:each_page_item, response, items: items) unless block
44
-
45
- each_page(response) do |page|
46
- page.body.fetch(items).each(&block)
47
- end
48
- end
49
- end
50
- end
51
- end