mailgun-ruby 1.4.5 → 1.4.6

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.
Files changed (120) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +17 -1
  3. data/README.md +3 -1
  4. data/lib/mailgun/api_keys/api_keys.rb +2 -2
  5. data/lib/mailgun/client.rb +1 -1
  6. data/lib/mailgun/domains/domain_keys.rb +5 -5
  7. data/lib/mailgun/domains/domains.rb +12 -9
  8. data/lib/mailgun/events/events.rb +1 -1
  9. data/lib/mailgun/helpers/api_version_checker.rb +23 -12
  10. data/lib/mailgun/helpers/deprecation.rb +32 -0
  11. data/lib/mailgun/lists/mailing_lists.rb +250 -0
  12. data/lib/mailgun/messages/message_builder.rb +17 -7
  13. data/lib/mailgun/response.rb +1 -1
  14. data/lib/mailgun/routes/routes.rb +98 -0
  15. data/lib/mailgun/tags/analytics_tags.rb +2 -2
  16. data/lib/mailgun/tags/tags.rb +16 -8
  17. data/lib/mailgun/version.rb +1 -1
  18. data/lib/mailgun/webhooks/account_webhooks.rb +2 -2
  19. data/lib/mailgun/webhooks/webhooks.rb +17 -9
  20. data/lib/mailgun.rb +1 -0
  21. metadata +6 -326
  22. data/.github/workflows/ci.yml +0 -49
  23. data/.github_changelog_generator +0 -1
  24. data/.gitignore +0 -24
  25. data/.rubocop.yml +0 -68
  26. data/.ruby-env.yml.example +0 -13
  27. data/Gemfile +0 -9
  28. data/Rakefile +0 -32
  29. data/docs/AccountWebhooks.md +0 -55
  30. data/docs/AnalyticsTags.md +0 -63
  31. data/docs/ApiKeys.md +0 -65
  32. data/docs/DomainKeys.md +0 -49
  33. data/docs/Domains.md +0 -82
  34. data/docs/EmailValidation.md +0 -34
  35. data/docs/Events.md +0 -48
  36. data/docs/Logs.md +0 -67
  37. data/docs/MessageBuilder.md +0 -120
  38. data/docs/Metrics.md +0 -108
  39. data/docs/OptInHandler.md +0 -103
  40. data/docs/Snippets.md +0 -519
  41. data/docs/Subaccounts.md +0 -68
  42. data/docs/Suppressions.md +0 -92
  43. data/docs/Templates.md +0 -92
  44. data/docs/Webhooks.md +0 -65
  45. data/docs/railgun/EmailValidation.md +0 -34
  46. data/docs/railgun/Overview.md +0 -11
  47. data/docs/railgun/Parameters.md +0 -83
  48. data/mailgun.gemspec +0 -47
  49. data/spec/integration/account_webhooks_spec.rb +0 -57
  50. data/spec/integration/analytics_tags_spec.rb +0 -54
  51. data/spec/integration/api_keys_spec.rb +0 -50
  52. data/spec/integration/bounces_spec.rb +0 -45
  53. data/spec/integration/campaign_spec.rb +0 -62
  54. data/spec/integration/complaints_spec.rb +0 -40
  55. data/spec/integration/domain_keys_spec.rb +0 -124
  56. data/spec/integration/domains_spec.rb +0 -201
  57. data/spec/integration/email_validation_spec.rb +0 -73
  58. data/spec/integration/events_spec.rb +0 -28
  59. data/spec/integration/list_members_spec.rb +0 -64
  60. data/spec/integration/list_spec.rb +0 -59
  61. data/spec/integration/logs_spec.rb +0 -105
  62. data/spec/integration/mailer_spec.rb +0 -65
  63. data/spec/integration/mailgun_spec.rb +0 -198
  64. data/spec/integration/messages/sample_data/mime.txt +0 -38
  65. data/spec/integration/metrics_spec.rb +0 -224
  66. data/spec/integration/routes_spec.rb +0 -91
  67. data/spec/integration/stats_spec.rb +0 -17
  68. data/spec/integration/subaccounts_spec.rb +0 -57
  69. data/spec/integration/suppressions_spec.rb +0 -320
  70. data/spec/integration/templates_spec.rb +0 -137
  71. data/spec/integration/unsubscribes_spec.rb +0 -44
  72. data/spec/integration/webhook_spec.rb +0 -79
  73. data/spec/spec_helper.rb +0 -53
  74. data/spec/unit/client_spec.rb +0 -448
  75. data/spec/unit/connection/test_client.rb +0 -169
  76. data/spec/unit/events/events_spec.rb +0 -88
  77. data/spec/unit/exceptions/exceptions_spec.rb +0 -31
  78. data/spec/unit/helpers/api_version_checker_spec.rb +0 -206
  79. data/spec/unit/lists/opt_in_handler_spec.rb +0 -28
  80. data/spec/unit/mailgun_spec.rb +0 -171
  81. data/spec/unit/messages/batch_message_spec.rb +0 -148
  82. data/spec/unit/messages/message_builder_spec.rb +0 -745
  83. data/spec/unit/messages/sample_data/mailgun_icon.png +0 -0
  84. data/spec/unit/messages/sample_data/mime.txt +0 -38
  85. data/spec/unit/messages/sample_data/rackspace_logo.jpg +0 -0
  86. data/spec/unit/messages/sample_data/unknown.type +0 -0
  87. data/spec/unit/railgun/content_type_spec.rb +0 -89
  88. data/spec/unit/railgun/mailer_spec.rb +0 -391
  89. data/spec/unit/response_spec.rb +0 -225
  90. data/spec/unit/webhooks_spec.rb +0 -121
  91. data/vcr_cassettes/For_the_suppressions_handling_class/creates_a_single_bounce.yml +0 -55
  92. data/vcr_cassettes/account_webhooks.yml +0 -269
  93. data/vcr_cassettes/analytics_tags.yml +0 -187
  94. data/vcr_cassettes/api_keys.yml +0 -212
  95. data/vcr_cassettes/bounces.yml +0 -136
  96. data/vcr_cassettes/complaints.yml +0 -315
  97. data/vcr_cassettes/domains.todo.yml +0 -42
  98. data/vcr_cassettes/domains.yml +0 -1243
  99. data/vcr_cassettes/email_validation.yml +0 -152
  100. data/vcr_cassettes/events.yml +0 -69
  101. data/vcr_cassettes/exceptions-invalid-api-key.yml +0 -52
  102. data/vcr_cassettes/exceptions-invalid-data.yml +0 -52
  103. data/vcr_cassettes/exceptions-not-allowed.yml +0 -54
  104. data/vcr_cassettes/exceptions.yml +0 -92
  105. data/vcr_cassettes/list_members.yml +0 -328
  106. data/vcr_cassettes/logs.yml +0 -53
  107. data/vcr_cassettes/mailer_invalid_domain.yml +0 -109
  108. data/vcr_cassettes/mailing_list.todo.yml +0 -43
  109. data/vcr_cassettes/mailing_list.yml +0 -682
  110. data/vcr_cassettes/message_deliver.yml +0 -149
  111. data/vcr_cassettes/metrics.yml +0 -116
  112. data/vcr_cassettes/routes.yml +0 -359
  113. data/vcr_cassettes/send_message.yml +0 -158
  114. data/vcr_cassettes/stats.yml +0 -48
  115. data/vcr_cassettes/subaccounts.yml +0 -270
  116. data/vcr_cassettes/suppressions.yml +0 -1392
  117. data/vcr_cassettes/templates.yml +0 -1065
  118. data/vcr_cassettes/unsubscribes.yml +0 -401
  119. data/vcr_cassettes/webhooks.yml +0 -246
  120. data/vcr_cassettes/webhooks_v4.yml +0 -275
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 330cf1e1b42d9cfeb06505375a0467c462b8d8270ba9c1156b5793063aba4d22
4
- data.tar.gz: ee750bf59f4e0c1ba63d73aa0cd08b68e7f837f4f0ff84acba81c078a190bef4
3
+ metadata.gz: b32ba39f8e6d20a75cc9e870057edaf087efd9fabfcf0f73c5c30c389ff4c879
4
+ data.tar.gz: fb73166343d70aa79ec9dcaf4df73f2389abac47eedf63fcdcee8d62a7d5547c
5
5
  SHA512:
6
- metadata.gz: 68d52c33e4703cc5b63ba256a7aef53b66cd9838477957b913c35741810fda047c1deb7ee33d381e48a717b5f1eae5184f2b871afb4d9ce03956e92ded7d3bd1
7
- data.tar.gz: d78b0ea0f67ebb0413f197702673b33788c3a81a29120eb323bf95a52af59d0fb3e9ff5b4db46af0e7fb547859bca2c0958e14da827b97dab2bbf2e3b43d9078
6
+ metadata.gz: 3ac8f9977486740e5c4770d3e12c68be15bb47a7195d7681a09cf57f9cca8d0f13f278d29a908feea605f16581ed7145ea120289fee8cbd80c5c1b3ccc1bbc1b
7
+ data.tar.gz: 7d9ae8fd11a0db5c1e6a1b4a0d7ab0f15bcf98cae2ddf82940227cf4666498e8f0c03ebcadefa1803fc40738f0a1bf9a52586c9159bb538ad0671feed5d50293
data/CHANGELOG.md CHANGED
@@ -1,5 +1,19 @@
1
1
  # Changelog
2
2
 
3
+ ## [v1.4.6](https://github.com/mailgun/mailgun-ruby/tree/v1.4.6) (2026-10-20)
4
+
5
+ [Full Changelog](https://github.com/mailgun/mailgun-ruby/compare/v1.4.5...v1.4.6)
6
+
7
+ **Merged pull requests:**
8
+
9
+ - Deprecations - Warn on Domains\#get\_domain\_stats and use one warning format [\#405](https://github.com/mailgun/mailgun-ruby/pull/405) ([alex-leb](https://github.com/alex-leb))
10
+ - ApiVersionChecker - Allow declarations before the methods [\#404](https://github.com/mailgun/mailgun-ruby/pull/404) ([alex-leb](https://github.com/alex-leb))
11
+ - Specs - Scrub X-Mailgun-Key-Id from VCR cassettes [\#403](https://github.com/mailgun/mailgun-ruby/pull/403) ([alex-leb](https://github.com/alex-leb))
12
+ - Routes - Add Mailgun::Routes wrapper [\#402](https://github.com/mailgun/mailgun-ruby/pull/402) ([alex-leb](https://github.com/alex-leb))
13
+ - Mailing Lists - Add Mailgun::MailingLists wrapper [\#401](https://github.com/mailgun/mailgun-ruby/pull/401) ([alex-leb](https://github.com/alex-leb))
14
+ - CI: skip the coverage check on fork PRs, don't fail fast [\#400](https://github.com/mailgun/mailgun-ruby/pull/400) ([alex-leb](https://github.com/alex-leb))
15
+ - Various improvements [\#387](https://github.com/mailgun/mailgun-ruby/pull/387) ([n-rodriguez](https://github.com/n-rodriguez))
16
+
3
17
  ## [v1.4.5](https://github.com/mailgun/mailgun-ruby/tree/v1.4.5) (2026-09-29)
4
18
 
5
19
  [Full Changelog](https://github.com/mailgun/mailgun-ruby/compare/v1.4.4...v1.4.5)
@@ -7,15 +21,17 @@
7
21
  **Closed issues:**
8
22
 
9
23
  - Testmode not correctly initialized from global setting [\#394](https://github.com/mailgun/mailgun-ruby/issues/394)
24
+ - Unable to make use of Postbin [\#337](https://github.com/mailgun/mailgun-ruby/issues/337)
25
+ - events abstraction issues [\#319](https://github.com/mailgun/mailgun-ruby/issues/319)
10
26
 
11
27
  **Merged pull requests:**
12
28
 
13
29
  - DE-10765: Client - Fix global test\_mode enabled when set to false [\#399](https://github.com/mailgun/mailgun-ruby/pull/399) ([alex-leb](https://github.com/alex-leb))
14
30
  - DE-1856: API Keys - Add docs and list filters [\#398](https://github.com/mailgun/mailgun-ruby/pull/398) ([alex-leb](https://github.com/alex-leb))
15
31
  - DE-1772: Domain Webhooks - Add v4 create, update and remove endpoints [\#397](https://github.com/mailgun/mailgun-ruby/pull/397) ([alex-leb](https://github.com/alex-leb))
16
- - fix\(webhooks\): re-introduce url parameter [\#393](https://github.com/mailgun/mailgun-ruby/pull/393) ([markokajzer](https://github.com/markokajzer))
17
32
  - DE-1786: Add github-changelog-generator gem [\#396](https://github.com/mailgun/mailgun-ruby/pull/396) ([alex-leb](https://github.com/alex-leb))
18
33
  - DE-1854: Add ApiKeys support [\#395](https://github.com/mailgun/mailgun-ruby/pull/395) ([alex-leb](https://github.com/alex-leb))
34
+ - fix\(webhooks\): re-introduce url parameter [\#393](https://github.com/mailgun/mailgun-ruby/pull/393) ([markokajzer](https://github.com/markokajzer))
19
35
 
20
36
  ## [v1.4.4](https://github.com/mailgun/mailgun-ruby/tree/v1.4.4) (2026-05-26)
21
37
 
data/README.md CHANGED
@@ -19,7 +19,7 @@ gem install mailgun-ruby
19
19
  Gemfile:
20
20
 
21
21
  ```ruby
22
- gem 'mailgun-ruby', '~>1.4.5'
22
+ gem 'mailgun-ruby', '~>1.4.6'
23
23
  ```
24
24
 
25
25
  Usage
@@ -184,6 +184,8 @@ This SDK includes the following components:
184
184
  - [Message Builder](docs/MessageBuilder.md)
185
185
  - [Batch Message](docs/MessageBuilder.md#usage---batch-message)
186
186
  - [Opt-In Handler](docs/OptInHandler.md)
187
+ - [Mailing Lists](docs/MailingLists.md)
188
+ - [Routes](docs/Routes.md)
187
189
  - [Domains](docs/Domains.md)
188
190
  - [Webhooks](docs/Webhooks.md)
189
191
  - [Account Webhooks](docs/AccountWebhooks.md)
@@ -6,6 +6,8 @@ module Mailgun
6
6
  class ApiKeys
7
7
  include ApiVersionChecker
8
8
 
9
+ enforces_api_version 'v1', :list, :create, :remove, :regenerate
10
+
9
11
  # Public creates a new Mailgun::ApiKeys instance.
10
12
  # Defaults to Mailgun::Client
11
13
  def initialize(client = Mailgun::Client.new(Mailgun.api_key, Mailgun.api_host || 'api.mailgun.net', 'v1'))
@@ -59,7 +61,5 @@ module Mailgun
59
61
  res = @client.post('keys/public', {})
60
62
  res.to_h['key']
61
63
  end
62
-
63
- enforces_api_version 'v1', :list, :create, :remove, :regenerate
64
64
  end
65
65
  end
@@ -27,7 +27,7 @@ module Mailgun
27
27
  'Accept' => '*/*'
28
28
  }
29
29
  }
30
- request_options.merge!(request: { timeout: timeout }) if timeout
30
+ request_options[:request] = { timeout: timeout } if timeout
31
31
 
32
32
  @http_client = build_http_client(api_key, request_options)
33
33
 
@@ -6,6 +6,11 @@ module Mailgun
6
6
  class DomainKeys
7
7
  include ApiVersionChecker
8
8
 
9
+ enforces_api_version 'v1', :list_domain_keys, :create_domain_key, :delete_domain_key
10
+ enforces_api_version 'v3', :update_domain_dkim_authority, :update_domain_dkim_selector
11
+ enforces_api_version 'v4', :activate_domain_key, :deactivate_domain_key
12
+ enforces_api_version 'v4', :get_domain_keys
13
+
9
14
  def initialize(client = Mailgun::Client.new)
10
15
  @client = client
11
16
  end
@@ -98,10 +103,5 @@ module Mailgun
98
103
  def update_domain_dkim_selector(domain, options = {})
99
104
  @client.put("domains/#{domain}/dkim_selector", options).to_h
100
105
  end
101
-
102
- enforces_api_version 'v1', :list_domain_keys, :create_domain_key, :delete_domain_key
103
- enforces_api_version 'v3', :update_domain_dkim_authority, :update_domain_dkim_selector
104
- enforces_api_version 'v4', :activate_domain_key, :deactivate_domain_key
105
- enforces_api_version 'v4', :get_domain_keys
106
106
  end
107
107
  end
@@ -6,6 +6,15 @@ module Mailgun
6
6
  class Domains
7
7
  include ApiVersionChecker
8
8
 
9
+ enforces_api_version 'v1', :dkim_rotation, :dkim_rotate
10
+ enforces_api_version 'v2', :get_domain_tracking_certificate, :regenerate_domain_tracking_certificate,
11
+ :generate_domain_tracking_certificate
12
+ enforces_api_version 'v3', :remove, :create_smtp_credentials, :update_smtp_credentials,
13
+ :delete_smtp_credentials, :get_domain_tracking_settings,
14
+ :update_domain_tracking_open_settings, :update_domain_tracking_click_settings,
15
+ :update_domain_tracking_unsubscribe_settings, :get_domain_stats
16
+ enforces_api_version 'v4', :list, :verify, :create, :update
17
+
9
18
  # Public: creates a new Mailgun::Domains instance.
10
19
  # Defaults to Mailgun::Client
11
20
  def initialize(client = Mailgun::Client.new)
@@ -234,6 +243,7 @@ module Mailgun
234
243
  # ==== Reporting::Stat methods ====
235
244
 
236
245
  # Public: Returns total stats for a given domains
246
+ # Deprecated: the Stats API is deprecated in favor of the Metrics API. Use Mailgun::Metrics#account_metrics instead.
237
247
  #
238
248
  # domain - [String] Name of the domain (ex. domain.com)
239
249
  # options - [Hash] of
@@ -245,20 +255,13 @@ module Mailgun
245
255
  #
246
256
  # Returns [Array] A list of domains (hash)
247
257
  def get_domain_stats(domain, options = {})
258
+ Deprecation.warn('Mailgun::Domains#get_domain_stats', 'Mailgun::Metrics#account_metrics',
259
+ reason: 'Mailgun deprecated the Stats API')
248
260
  raise(ParameterError, 'No domain given to list stats on Mailgun', caller) unless domain
249
261
 
250
262
  @client.get("#{domain}/stats/total", options).to_h
251
263
  end
252
264
 
253
265
  # ==== End of Reporting::Stats methods ====
254
-
255
- enforces_api_version 'v1', :dkim_rotation, :dkim_rotate
256
- enforces_api_version 'v2', :get_domain_tracking_certificate, :regenerate_domain_tracking_certificate,
257
- :generate_domain_tracking_certificate
258
- enforces_api_version 'v3', :remove, :create_smtp_credentials, :update_smtp_credentials,
259
- :delete_smtp_credentials, :get_domain_tracking_settings,
260
- :update_domain_tracking_open_settings, :update_domain_tracking_click_settings,
261
- :update_domain_tracking_unsubscribe_settings, :get_domain_stats
262
- enforces_api_version 'v4', :list, :verify, :create, :update
263
266
  end
264
267
  end
@@ -75,7 +75,7 @@ module Mailgun
75
75
  #
76
76
  # Returns a Mailgun.Response object.
77
77
  def get_events(params = {}, paging = nil)
78
- warn('WARN: This API is deprecated in favor of our Logs API')
78
+ Deprecation.warn('Mailgun::Events', 'Mailgun::Logs#account_logs', reason: 'Mailgun deprecated the Events API')
79
79
  response = @client.get(construct_url(paging), params)
80
80
  extract_paging(response)
81
81
  response
@@ -6,25 +6,36 @@ module Mailgun
6
6
  base.extend(ClassMethods)
7
7
  end
8
8
 
9
+ # Both declarations can be placed before or after the methods they name.
9
10
  module ClassMethods
10
11
  def requires_api_version(version, *method_names)
11
- method_names.each do |method_name|
12
- original_method = instance_method(method_name)
13
-
14
- define_method(method_name) do |*args, **kwargs, &block|
15
- warn_unless_api_version(version)
16
- original_method.bind(self).call(*args, **kwargs, &block)
17
- end
18
- end
12
+ wrap_with_api_version_check(method_names) { warn_unless_api_version(version) }
19
13
  end
20
14
 
21
15
  def enforces_api_version(version, *method_names)
22
- method_names.each do |method_name|
23
- original_method = instance_method(method_name)
16
+ wrap_with_api_version_check(method_names) { require_api_version(version) }
17
+ end
24
18
 
19
+ private
20
+
21
+ def wrap_with_api_version_check(method_names, &check)
22
+ prepend(Check.new(method_names, &check))
23
+ end
24
+ end
25
+
26
+ # The module a declaration prepends. Its methods run the check and then the class's
27
+ # own method through super, so the class methods don't have to exist yet.
28
+ class Check < Module
29
+ # The methods this check wraps
30
+ attr_reader :method_names
31
+
32
+ def initialize(method_names, &check)
33
+ super(&nil) # keep Module#initialize from running the check block as module code
34
+ @method_names = method_names
35
+ method_names.each do |method_name|
25
36
  define_method(method_name) do |*args, **kwargs, &block|
26
- require_api_version(version)
27
- original_method.bind(self).call(*args, **kwargs, &block)
37
+ instance_exec(&check)
38
+ super(*args, **kwargs, &block)
28
39
  end
29
40
  end
30
41
  end
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Mailgun
4
+ # Prints the gem's deprecation warnings in one format, e.g.
5
+ #
6
+ # app/jobs/report.rb:12: warning: DEPRECATION: "Mailgun::Tags#get_tag" is deprecated
7
+ # (Mailgun deprecated the Tags API) and will be removed in mailgun-ruby 1.5.
8
+ # Please use "Mailgun::AnalyticsTags#list" instead.
9
+ #
10
+ # The location is the first caller outside the gem, so it points at the code to change.
11
+ module Deprecation
12
+ GEM_LIB_DIR = "#{File.expand_path('../..', __dir__)}/".freeze
13
+
14
+ # Public: Warn that a method or class is deprecated
15
+ #
16
+ # name - [String] The deprecated method or class, e.g. "Mailgun::Tags#get_tag"
17
+ # replacement - [String] What to use instead, e.g. "Mailgun::AnalyticsTags#list"
18
+ # reason - [String] Why, when Mailgun deprecated the API it calls (optional)
19
+ # removal - [String] When it will be removed, e.g. "mailgun-ruby 1.5" (optional)
20
+ #
21
+ # Returns nil
22
+ def self.warn(name, replacement, reason: nil, removal: nil)
23
+ message = "DEPRECATION: \"#{name}\" is deprecated"
24
+ message += " (#{reason})" if reason
25
+ message += " and will be removed in #{removal}" if removal
26
+ message += ". Please use \"#{replacement}\" instead."
27
+
28
+ location = caller_locations.find { |loc| !(loc.absolute_path || loc.path).to_s.start_with?(GEM_LIB_DIR) }
29
+ Kernel.warn(location ? "#{location.path}:#{location.lineno}: warning: #{message}" : message)
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,250 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Mailgun
4
+ # A Mailgun::MailingLists object is a simple CRUD interface to Mailgun Mailing Lists
5
+ # and their members.
6
+ # Uses Mailgun
7
+ class MailingLists
8
+ include ApiVersionChecker
9
+
10
+ enforces_api_version 'v3', :list, :list_pages, :create, :get, :update, :remove,
11
+ :list_members, :list_members_pages, :get_member, :create_member,
12
+ :update_member, :remove_member, :create_members, :import_members
13
+
14
+ # Public: creates a new Mailgun::MailingLists instance.
15
+ # Defaults to Mailgun::Client
16
+ def initialize(client = Mailgun::Client.new)
17
+ @client = client
18
+ end
19
+
20
+ # Lists
21
+
22
+ # Public: Get mailing lists
23
+ #
24
+ # options - [Hash] of
25
+ # limit - [Integer] Maximum number of records to return. (100 by default)
26
+ # skip - [Integer] Number of records to skip. (0 by default)
27
+ # address - [String] Return only the list with this address
28
+ #
29
+ # Returns [Array] A list of mailing lists (hash)
30
+ def list(options = {})
31
+ @client.get('lists', options).to_h['items']
32
+ end
33
+
34
+ # Public: Get mailing lists by page
35
+ #
36
+ # options - [Hash] of
37
+ # limit - [Integer] Maximum number of records to return. (100 by default)
38
+ # page - [String] Page to retrieve: first, last, next or prev
39
+ # address - [String] Pivot list address the page starts from
40
+ #
41
+ # Returns [Hash] with the mailing lists in 'items' and page URLs in 'paging'
42
+ def list_pages(options = {})
43
+ @client.get('lists/pages', options).to_h
44
+ end
45
+
46
+ # Public: Create a mailing list
47
+ #
48
+ # address - [String] Email address of the list, e.g. developers@mg.example.com
49
+ # options - [Hash] of
50
+ # name - [String] List name
51
+ # description - [String] List description
52
+ # access_level - [String] Who can post: readonly, members or everyone. Defaults to readonly
53
+ # reply_preference - [String] Where replies go: list or sender. Defaults to list
54
+ #
55
+ # Returns [Hash] of the created list
56
+ def create(address, options = {})
57
+ require_address!(address, 'No address given to create the mailing list')
58
+
59
+ @client.post('lists', options.merge(address: address)).to_h
60
+ end
61
+
62
+ # Public: Get a mailing list
63
+ #
64
+ # address - [String] Email address of the list
65
+ #
66
+ # Returns [Hash] Information on the requested list
67
+ def get(address)
68
+ require_address!(address, 'No address given to find the mailing list')
69
+
70
+ @client.get("lists/#{escape(address)}").to_h!
71
+ end
72
+
73
+ # Public: Update a mailing list
74
+ #
75
+ # address - [String] Email address of the list
76
+ # options - [Hash] of
77
+ # address - [String] New email address of the list
78
+ # name - [String] List name
79
+ # description - [String] List description
80
+ # access_level - [String] Who can post: readonly, members or everyone
81
+ # reply_preference - [String] Where replies go: list or sender
82
+ #
83
+ # Returns [Hash] of the updated list
84
+ def update(address, options = {})
85
+ require_address!(address, 'No address given to update the mailing list')
86
+
87
+ @client.put("lists/#{escape(address)}", options).to_h
88
+ end
89
+
90
+ # Public: Delete a mailing list and all of its members
91
+ #
92
+ # address - [String] Email address of the list
93
+ #
94
+ # Returns [Boolean] if successful or not
95
+ def remove(address)
96
+ require_address!(address, 'No address given to remove the mailing list')
97
+
98
+ @client.delete("lists/#{escape(address)}").status == 200
99
+ end
100
+
101
+ # Members
102
+
103
+ # Public: Get the members of a mailing list
104
+ #
105
+ # list_address - [String] Email address of the list
106
+ # options - [Hash] of
107
+ # subscribed - [Boolean] Return only subscribed (true) or unsubscribed (false) members
108
+ # limit - [Integer] Maximum number of records to return. (100 by default)
109
+ # skip - [Integer] Number of records to skip. (0 by default)
110
+ # address - [String] Return only the member with this address
111
+ #
112
+ # Returns [Array] A list of members (hash)
113
+ def list_members(list_address, options = {})
114
+ require_address!(list_address, 'No list address given to list members of')
115
+
116
+ @client.get("lists/#{escape(list_address)}/members", options).to_h['items']
117
+ end
118
+
119
+ # Public: Get the members of a mailing list by page
120
+ #
121
+ # list_address - [String] Email address of the list
122
+ # options - [Hash] of
123
+ # subscribed - [Boolean] Return only subscribed (true) or unsubscribed (false) members
124
+ # limit - [Integer] Maximum number of records to return. (100 by default)
125
+ # page - [String] Page to retrieve: first, last, next or prev
126
+ # address - [String] Pivot member address the page starts from
127
+ #
128
+ # Returns [Hash] with the members in 'items' and page URLs in 'paging'
129
+ def list_members_pages(list_address, options = {})
130
+ require_address!(list_address, 'No list address given to list members of')
131
+
132
+ @client.get("lists/#{escape(list_address)}/members/pages", options).to_h
133
+ end
134
+
135
+ # Public: Get a mailing list member
136
+ #
137
+ # list_address - [String] Email address of the list
138
+ # member_address - [String] Email address of the member
139
+ #
140
+ # Returns [Hash] Information on the requested member
141
+ def get_member(list_address, member_address)
142
+ require_address!(list_address, 'No list address given to find the member on')
143
+ require_address!(member_address, 'No member address given to find')
144
+
145
+ @client.get("lists/#{escape(list_address)}/members/#{escape(member_address)}").to_h!
146
+ end
147
+
148
+ # Public: Add a member to a mailing list
149
+ #
150
+ # list_address - [String] Email address of the list
151
+ # member_address - [String] Email address of the member
152
+ # options - [Hash] of
153
+ # name - [String] Member name
154
+ # vars - [Hash, String] Custom member variables, a Hash or a JSON string
155
+ # subscribed - [Boolean] Whether the member is subscribed. Defaults to true
156
+ # upsert - [Boolean] Update the member if it already exists instead of failing. Defaults to false
157
+ #
158
+ # Returns [Hash] of the created member
159
+ def create_member(list_address, member_address, options = {})
160
+ require_address!(list_address, 'No list address given to add the member to')
161
+ require_address!(member_address, 'No member address given to add')
162
+
163
+ @client.post("lists/#{escape(list_address)}/members",
164
+ encode_vars(options).merge(address: member_address)).to_h
165
+ end
166
+
167
+ # Public: Update a mailing list member
168
+ #
169
+ # list_address - [String] Email address of the list
170
+ # member_address - [String] Email address of the member
171
+ # options - [Hash] of
172
+ # address - [String] New email address of the member
173
+ # name - [String] Member name
174
+ # vars - [Hash, String] Custom member variables, a Hash or a JSON string
175
+ # subscribed - [Boolean] Whether the member is subscribed
176
+ #
177
+ # Returns [Hash] of the updated member
178
+ def update_member(list_address, member_address, options = {})
179
+ require_address!(list_address, 'No list address given to update the member on')
180
+ require_address!(member_address, 'No member address given to update')
181
+
182
+ @client.put("lists/#{escape(list_address)}/members/#{escape(member_address)}", encode_vars(options)).to_h
183
+ end
184
+
185
+ # Public: Remove a member from a mailing list
186
+ #
187
+ # list_address - [String] Email address of the list
188
+ # member_address - [String] Email address of the member
189
+ #
190
+ # Returns [Boolean] if successful or not
191
+ def remove_member(list_address, member_address)
192
+ require_address!(list_address, 'No list address given to remove the member from')
193
+ require_address!(member_address, 'No member address given to remove')
194
+
195
+ @client.delete("lists/#{escape(list_address)}/members/#{escape(member_address)}").status == 200
196
+ end
197
+
198
+ # Public: Add up to 1,000 members to a mailing list in one call
199
+ #
200
+ # list_address - [String] Email address of the list
201
+ # members - [Array, String] Members as an Array of addresses or member hashes
202
+ # (address, name, vars, subscribed), or a JSON string of the same
203
+ # options - [Hash] of
204
+ # upsert - [Boolean] Update members that already exist instead of failing. Defaults to false
205
+ #
206
+ # Returns [Hash] with the list and a confirmation message
207
+ def create_members(list_address, members, options = {})
208
+ require_address!(list_address, 'No list address given to add members to')
209
+ raise(ParameterError, 'No members given to add', caller) if members.nil? || members.empty?
210
+
211
+ members = members.to_json unless members.is_a?(String)
212
+ @client.post("lists/#{escape(list_address)}/members.json", options.merge(members: members)).to_h
213
+ end
214
+
215
+ # Public: Add up to 1,000 members to a mailing list from a CSV file
216
+ #
217
+ # list_address - [String] Email address of the list
218
+ # csv - [String, IO] Path to the CSV file, or an IO with its contents
219
+ # options - [Hash] of
220
+ # subscribed - [Boolean] Subscription status for members without one in the file
221
+ # upsert - [Boolean] Update members that already exist instead of failing. Defaults to false
222
+ #
223
+ # Returns [Hash] with the list and a confirmation message
224
+ def import_members(list_address, csv, options = {})
225
+ require_address!(list_address, 'No list address given to import members to')
226
+ raise(ParameterError, 'No CSV file given to import members from', caller) if csv.nil? || csv == ''
227
+
228
+ file = Faraday::Multipart::FilePart.new(csv, 'text/csv', csv.is_a?(String) ? File.basename(csv) : 'members.csv')
229
+ @client.post("lists/#{escape(list_address)}/members.csv", options.merge(members: file)).to_h
230
+ end
231
+
232
+ private
233
+
234
+ def require_address!(address, message)
235
+ raise(ParameterError, message, caller) if address.nil? || address.to_s.empty?
236
+ end
237
+
238
+ # Percent-encodes the characters an email address may contain that would break a URL path,
239
+ # keeping '@' and '+' as they are.
240
+ def escape(address)
241
+ address.to_s.gsub(%r{[%/?#\s]}) { |char| format('%%%02X', char.ord) }
242
+ end
243
+
244
+ def encode_vars(options)
245
+ return options unless options[:vars].is_a?(Hash)
246
+
247
+ options.merge(vars: options[:vars].to_json)
248
+ end
249
+ end
250
+ end
@@ -30,7 +30,7 @@ module Mailgun
30
30
  # @return [void]
31
31
  def add_recipient(recipient_type, address, variables = nil)
32
32
  if recipient_type == 'h:reply-to'
33
- warn 'DEPRECATION: "add_recipient("h:reply-to", ...)" is deprecated. Please use "reply_to" instead.'
33
+ warn_deprecated('add_recipient("h:reply-to", ...)', :reply_to)
34
34
  return reply_to(address, variables)
35
35
  end
36
36
 
@@ -56,7 +56,7 @@ module Mailgun
56
56
 
57
57
  # Deprecated: please use 'from' instead.
58
58
  def set_from_address(address, variables = nil)
59
- warn 'DEPRECATION: "set_from_address" is deprecated. Please use "from" instead.'
59
+ warn_deprecated(__method__, :from)
60
60
  from(address, variables)
61
61
  end
62
62
 
@@ -83,7 +83,7 @@ module Mailgun
83
83
 
84
84
  # Deprecated: Please use "subject" instead.
85
85
  def set_subject(subj = nil)
86
- warn 'DEPRECATION: "set_subject" is deprecated. Please use "subject" instead.'
86
+ warn_deprecated(__method__, :subject)
87
87
  subject(subj)
88
88
  end
89
89
 
@@ -97,7 +97,7 @@ module Mailgun
97
97
 
98
98
  # Deprecated: Please use "body_text" instead.
99
99
  def set_text_body(text_body = nil)
100
- warn 'DEPRECATION: "set_text_body" is deprecated. Please use "body_text" instead.'
100
+ warn_deprecated(__method__, :body_text)
101
101
  body_text(text_body)
102
102
  end
103
103
 
@@ -111,7 +111,7 @@ module Mailgun
111
111
 
112
112
  # Deprecated: Please use "body_html" instead.
113
113
  def set_html_body(html_body = nil)
114
- warn 'DEPRECATION: "set_html_body" is deprecated. Please use "body_html" instead.'
114
+ warn_deprecated(__method__, :body_html)
115
115
  body_html(html_body)
116
116
  end
117
117
 
@@ -243,7 +243,7 @@ module Mailgun
243
243
 
244
244
  # Deprecated: 'set_custom_data' is deprecated. Please use 'header' instead.
245
245
  def set_custom_data(name, data)
246
- warn 'DEPRECATION: "set_custom_data" is deprecated. Please use "header" instead.'
246
+ warn_deprecated(__method__, :header)
247
247
  header name, data
248
248
  end
249
249
 
@@ -292,7 +292,7 @@ module Mailgun
292
292
 
293
293
  # Deprecated: 'set_message_id' is deprecated. Use 'message_id' instead.
294
294
  def set_message_id(data = nil)
295
- warn 'DEPRECATION: "set_message_id" is deprecated. Please use "message_id" instead.'
295
+ warn_deprecated(__method__, :message_id)
296
296
  message_id data
297
297
  end
298
298
 
@@ -464,5 +464,15 @@ module Mailgun
464
464
  end
465
465
  add_faraday_attachment(disposition, attachment, filename)
466
466
  end
467
+
468
+ # Warns that a MessageBuilder method is deprecated.
469
+ #
470
+ # @param [String|Symbol] method_name The deprecated method.
471
+ # @param [Symbol] replacement The method to use instead.
472
+ # @return [void]
473
+ def warn_deprecated(method_name, replacement)
474
+ Deprecation.warn("Mailgun::MessageBuilder##{method_name}", "Mailgun::MessageBuilder##{replacement}",
475
+ removal: 'a future version of mailgun-ruby')
476
+ end
467
477
  end
468
478
  end
@@ -65,7 +65,7 @@ module Mailgun
65
65
  #
66
66
  # @return [Boolean] A boolean that binarizes the response status result.
67
67
  def success?
68
- (200..299).include?(status)
68
+ (200..299).cover?(status)
69
69
  end
70
70
  end
71
71
  end