mailtrap 2.6.0 → 2.7.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: 38c84a79ba87b360caf02839703e51e1e1af2cb84092e03b995677805dd09c16
4
- data.tar.gz: 2a6e502ff5876367d35ecc5907d4aaa3fd32689f342d6e91c3f54dd189cdcaea
3
+ metadata.gz: a56e52ebde096ddaa019f4c16e15f63fe37ace69d91892f4c92044c0727b3c3f
4
+ data.tar.gz: 79a7aca8251526389c4faa2f643ca8f7e58182de4dcbada0af2d8f9a5afe6464
5
5
  SHA512:
6
- metadata.gz: 927ef7bb197ea1636462a5e926eb273d8703e383ddee5e66b578252cb6d51cc7cb1e2afba194c70186980d67d32488cf3115c529146a6fedb02a8a5b4f0ae699
7
- data.tar.gz: abcba3b12d50ae4b292c6fcdfd5e4b1786dafbfe02dfbe20528662dd3f2fc12b6fd2b14bd53b7ab09082a51a006e58003c9d8a989616cc5827d14ee89263c32f
6
+ metadata.gz: df5e86fd7a0d31a5b717e189ae9637f6e0f413dad2d4fd2c9adbc56e7be5197ef5a59a759dc6eee9ff19a98c9196c7d5f1a984b3ee5f75ef69a5ca0f376a5519
7
+ data.tar.gz: 516e66780366eaf9f76b07f0957092b345fdd0262cd15dd997dcde5887276b7b37ba9c5c29971c6e7e53082e74db4deb5575ba1b4e0ebab4341fae05d7accc98
data/.coderabbit.yaml ADDED
@@ -0,0 +1,10 @@
1
+ # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json
2
+ language: en
3
+ reviews:
4
+ path_instructions:
5
+ - path: "spec/fixtures/vcr_cassettes/**/*.yml"
6
+ instructions: |
7
+ Act as a data privacy officer. Carefully read all the vcr cassettes
8
+ with recorded HTTP interactions and try to identify sensitive data that
9
+ could potentially be recorded. It can be anything from PII to
10
+ credentials. Ignore obvious placeholder values and real IDs in URLs.
data/CHANGELOG.md CHANGED
@@ -1,3 +1,9 @@
1
+ ## [2.7.0] - 2026-02-24
2
+ - Add Sandbox Messages API
3
+ - Add Sending Domains API
4
+ - Add Sandbox Attachments API
5
+ - Add Accounts API
6
+
1
7
  ## [2.6.0] - 2026-01-27
2
8
  - Add Inboxes API
3
9
  - Add Projects API
data/Gemfile CHANGED
@@ -8,6 +8,8 @@ gem 'appraisal'
8
8
  gem 'irb'
9
9
  gem 'mail'
10
10
  gem 'net-smtp'
11
+ gem 'rack'
12
+ gem 'rackup'
11
13
  gem 'rake', '~> 13.3'
12
14
  gem 'rdoc', '~> 7.1.0'
13
15
  gem 'rspec', '~> 3'
@@ -17,4 +19,5 @@ gem 'rubocop-rake', require: false
17
19
  gem 'rubocop-rspec', require: false
18
20
  gem 'vcr'
19
21
  gem 'webmock'
22
+ gem 'webrick'
20
23
  gem 'yard', '~> 0.9'
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- mailtrap (2.6.0)
4
+ mailtrap (2.7.0)
5
5
  base64
6
6
 
7
7
  GEM
@@ -61,6 +61,9 @@ GEM
61
61
  stringio
62
62
  public_suffix (7.0.2)
63
63
  racc (1.8.1)
64
+ rack (3.2.4)
65
+ rackup (2.3.1)
66
+ rack (>= 3)
64
67
  rainbow (3.1.1)
65
68
  rake (13.3.1)
66
69
  rdoc (7.1.0)
@@ -120,6 +123,7 @@ GEM
120
123
  addressable (>= 2.8.0)
121
124
  crack (>= 0.3.2)
122
125
  hashdiff (>= 0.4.0, < 2.0.0)
126
+ webrick (1.9.2)
123
127
  yard (0.9.38)
124
128
 
125
129
  PLATFORMS
@@ -131,6 +135,8 @@ DEPENDENCIES
131
135
  mail
132
136
  mailtrap!
133
137
  net-smtp
138
+ rack
139
+ rackup
134
140
  rake (~> 13.3)
135
141
  rdoc (~> 7.1.0)
136
142
  rspec (~> 3)
@@ -140,6 +146,7 @@ DEPENDENCIES
140
146
  rubocop-rspec
141
147
  vcr
142
148
  webmock
149
+ webrick
143
150
  yard (~> 0.9)
144
151
 
145
152
  BUNDLED WITH
data/README.md CHANGED
@@ -173,24 +173,27 @@ mail(delivery_method: :mailtrap_bulk)
173
173
  Refer to the [`examples`](examples) folder for more examples:
174
174
 
175
175
  Email API:
176
- - Full email sending – [`full.rb`](examples/full.rb)
177
176
 
178
- - Batch sending – [`batch.rb`](examples/batch.rb)
177
+ - Full Email Sending – [`full.rb`](examples/full.rb)
178
+ - Batch Sending – [`batch.rb`](examples/batch.rb)
179
+ - Sending Domains API – [`sending_domains_api.rb`](examples/sending_domains_api.rb)
179
180
 
180
181
  Email Sandbox (Testing):
181
182
 
182
183
  - Projects CRUD – [`projects_api.rb`](examples/projects_api.rb)
183
184
  - Inboxes CRUD - [`inboxes_api.rb`](examples/inboxes_api.rb)
185
+ - Sandbox Messages CRUD - [`sandbox_messages_api.rb`](examples/sandbox_messages_api.rb)
186
+ - Sandbox Attachments API - [`sandbox_attachments_api.rb`](examples/sandbox_attachments_api.rb)
184
187
 
185
188
  Contact management:
186
189
 
187
- - Contacts CRUD & listing – [`contacts_api.rb`](examples/contacts_api.rb)
190
+ - Contacts CRUD & Listing – [`contacts_api.rb`](examples/contacts_api.rb)
188
191
 
189
- General API:
192
+ General:
190
193
 
191
194
  - Templates CRUD – [`email_templates_api.rb`](examples/email_templates_api.rb)
192
-
193
195
  - Action Mailer – [`action_mailer.rb`](examples/action_mailer.rb)
196
+ - Accounts API – [`accounts_api.rb`](examples/accounts_api.rb)
194
197
 
195
198
  ## Migration guide v1 → v2
196
199
 
@@ -204,15 +207,24 @@ Bug reports and pull requests are welcome on [GitHub](https://github.com/railswa
204
207
 
205
208
  ## Development
206
209
 
207
- After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
210
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run
211
+ `rake spec` to run the tests. You can also run `bin/console` for an interactive
212
+ prompt that will allow you to experiment.
208
213
 
209
214
  To install this gem onto your local machine, run `bundle exec rake install`.
210
215
 
211
- To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and the created tag, and push the `.gem` file to [rubygems.org](https://rubygems.org).
216
+ To release a new version, update the version number in `version.rb`, and then
217
+ run `bundle exec rake release`, which will create a git tag for the version,
218
+ push git commits and the created tag, and push the `.gem` file to
219
+ [rubygems.org](https://rubygems.org).
220
+
221
+ To run the documentation server, first generate the documentation with
222
+ `yard doc`, then run `yard server`.
212
223
 
213
224
  All contributions are required to have rspec tests covering its functionality.
214
225
 
215
- Please be sure to update [README](README.md) with new examples and features when applicable.
226
+ Please be sure to update [README](README.md) with new examples and features
227
+ when applicable.
216
228
 
217
229
  ## License
218
230
 
@@ -224,4 +236,4 @@ Everyone interacting in the Mailtrap project's codebases, issue trackers, chat r
224
236
 
225
237
  ## Compatibility with previous releases
226
238
 
227
- Versions of this package up to 2.0.2 were an [unofficial client](https://github.com/vchin/mailtrap-client) developed by [@vchin](https://github.com/vchin). Package version 3 is a completely new package.
239
+ Versions of this package up to 2.0.2 were an [unofficial client](https://github.com/vchin/mailtrap-client) developed by [@vchin](https://github.com/vchin). Package version 3 is a completely new package.
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Mailtrap
4
+ # Data Transfer Object for Account
5
+ # @see https://api-docs.mailtrap.io/docs/mailtrap-api-docs/d26921ca2a48f-get-all-accounts
6
+ # @attr_reader id [Integer] The account ID
7
+ # @attr_reader name [String] The account name
8
+ # @attr_reader access_levels [Array] The account access levels
9
+ #
10
+ Account = Struct.new(
11
+ :id,
12
+ :name,
13
+ :access_levels,
14
+ keyword_init: true
15
+ )
16
+ end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'base_api'
4
+ require_relative 'account'
5
+
6
+ module Mailtrap
7
+ class AccountsAPI
8
+ include BaseAPI
9
+
10
+ self.response_class = Account
11
+
12
+ attr_reader :client
13
+
14
+ # @param client [Mailtrap::Client] The client instance
15
+ # @raise [ArgumentError] If account_id is nil
16
+ def initialize(client = Mailtrap::Client.new)
17
+ @client = client
18
+ end
19
+
20
+ # Lists all accounts
21
+ # @return [Array<Account>] Array of accounts
22
+ # @!macro api_errors
23
+ def list
24
+ base_list
25
+ end
26
+
27
+ private
28
+
29
+ def base_path
30
+ '/api/accounts'
31
+ end
32
+ end
33
+ end
@@ -115,7 +115,7 @@ module Mailtrap
115
115
  # )
116
116
  # @param base [#to_json] The base email configuration for the batch.
117
117
  # @param requests [Array<#to_json>] Array of individual email requests.
118
- # @return [Hash] The JSON response from the API.
118
+ # @return [Hash, String, nil] JSON response or raw response body from the API.
119
119
  # @!macro api_errors
120
120
  # @raise [Mailtrap::MailSizeError] If the message is too large.
121
121
  def send_batch(base, requests)
@@ -153,7 +153,7 @@ module Mailtrap
153
153
  # text: 'Congrats for sending test email with Mailtrap!'
154
154
  # )
155
155
  # @param mail [#to_json] The email to send
156
- # @return [Hash] The JSON response
156
+ # @return [Hash, String, nil] JSON response or raw response body
157
157
  # @!macro api_errors
158
158
  # @raise [Mailtrap::MailSizeError] If the message is too large
159
159
  def send(mail)
@@ -168,7 +168,7 @@ module Mailtrap
168
168
  # Performs a GET request to the specified path
169
169
  # @param path [String] The request path
170
170
  # @param query_params [Hash] Query parameters to append to the URL (optional)
171
- # @return [Hash, nil] The JSON response
171
+ # @return [Hash, String, nil] JSON response or raw response body
172
172
  # @!macro api_errors
173
173
  def get(path, query_params = {})
174
174
  perform_request(
@@ -182,7 +182,7 @@ module Mailtrap
182
182
  # Performs a POST request to the specified path
183
183
  # @param path [String] The request path
184
184
  # @param body [Hash] The request body
185
- # @return [Hash, nil] The JSON response
185
+ # @return [Hash, String, nil] JSON response or raw response body
186
186
  # @!macro api_errors
187
187
  def post(path, body = nil)
188
188
  perform_request(
@@ -196,7 +196,7 @@ module Mailtrap
196
196
  # Performs a PATCH request to the specified path
197
197
  # @param path [String] The request path
198
198
  # @param body [Hash] The request body
199
- # @return [Hash, nil] The JSON response
199
+ # @return [Hash, String, nil] JSON response or raw response body
200
200
  # @!macro api_errors
201
201
  def patch(path, body = nil)
202
202
  perform_request(
@@ -209,7 +209,7 @@ module Mailtrap
209
209
 
210
210
  # Performs a DELETE request to the specified path
211
211
  # @param path [String] The request path
212
- # @return [Hash, nil] The JSON response
212
+ # @return [Hash, String, nil] JSON response or raw response body
213
213
  # @!macro api_errors
214
214
  def delete(path)
215
215
  perform_request(
@@ -221,8 +221,11 @@ module Mailtrap
221
221
 
222
222
  private
223
223
 
224
- def http_client_for(host)
225
- @http_clients[host] ||= Net::HTTP.new(host, api_port).tap { |client| client.use_ssl = true }
224
+ def validate_args!(api_key, api_port, bulk, sandbox, inbox_id)
225
+ raise ArgumentError, 'api_key is required' if api_key.nil?
226
+ raise ArgumentError, 'api_port is required' if api_port.nil?
227
+ raise ArgumentError, 'bulk stream is not applicable for sandbox API' if bulk && sandbox
228
+ raise ArgumentError, 'inbox_id is required for sandbox API' if sandbox && inbox_id.nil?
226
229
  end
227
230
 
228
231
  def select_api_host(bulk:, sandbox:)
@@ -235,14 +238,6 @@ module Mailtrap
235
238
  end
236
239
  end
237
240
 
238
- def send_path
239
- "/api/send#{"/#{inbox_id}" if sandbox}"
240
- end
241
-
242
- def batch_request_path
243
- "/api/batch#{"/#{inbox_id}" if sandbox}"
244
- end
245
-
246
241
  def perform_request(method:, host:, path:, query_params: {}, body: nil)
247
242
  http_client = http_client_for(host)
248
243
 
@@ -254,6 +249,10 @@ module Mailtrap
254
249
  handle_response(response)
255
250
  end
256
251
 
252
+ def http_client_for(host)
253
+ @http_clients[host] ||= Net::HTTP.new(host, api_port).tap { |client| client.use_ssl = true }
254
+ end
255
+
257
256
  def setup_request(method, uri_or_path, body = nil)
258
257
  request = case method
259
258
  when :get
@@ -279,17 +278,17 @@ module Mailtrap
279
278
  def handle_response(response) # rubocop:disable Metrics/CyclomaticComplexity, Metrics/MethodLength
280
279
  case response
281
280
  when Net::HTTPOK, Net::HTTPCreated
282
- json_response(response.body)
281
+ parse_response(response)
283
282
  when Net::HTTPNoContent
284
283
  nil
285
284
  when Net::HTTPBadRequest
286
285
  raise Mailtrap::Error, ['bad request'] if response.body.empty?
287
286
 
288
- raise Mailtrap::Error, response_errors(response.body)
287
+ raise Mailtrap::Error, response_errors(response)
289
288
  when Net::HTTPUnauthorized
290
- raise Mailtrap::AuthorizationError, response_errors(response.body)
289
+ raise Mailtrap::AuthorizationError, response_errors(response)
291
290
  when Net::HTTPForbidden
292
- raise Mailtrap::RejectionError, response_errors(response.body)
291
+ raise Mailtrap::RejectionError, response_errors(response)
293
292
  when Net::HTTPPayloadTooLarge
294
293
  raise Mailtrap::MailSizeError, ['message too large']
295
294
  when Net::HTTPTooManyRequests
@@ -303,20 +302,37 @@ module Mailtrap
303
302
  end
304
303
  end
305
304
 
306
- def response_errors(body)
307
- parsed_body = json_response(body)
308
- Array(parsed_body[:errors] || parsed_body[:error])
305
+ def parse_response(response)
306
+ if json_response?(response)
307
+ json_response(response.body)
308
+ else
309
+ response.body
310
+ end
311
+ end
312
+
313
+ def response_errors(response)
314
+ if json_response?(response)
315
+ parsed_body = json_response(response.body)
316
+ Array(parsed_body[:errors] || parsed_body[:error])
317
+ else
318
+ [response.body]
319
+ end
320
+ end
321
+
322
+ def json_response?(response)
323
+ response.content_type == 'application/json'
309
324
  end
310
325
 
311
326
  def json_response(body)
312
327
  JSON.parse(body, symbolize_names: true)
313
328
  end
314
329
 
315
- def validate_args!(api_key, api_port, bulk, sandbox, inbox_id)
316
- raise ArgumentError, 'api_key is required' if api_key.nil?
317
- raise ArgumentError, 'api_port is required' if api_port.nil?
318
- raise ArgumentError, 'bulk stream is not applicable for sandbox API' if bulk && sandbox
319
- raise ArgumentError, 'inbox_id is required for sandbox API' if sandbox && inbox_id.nil?
330
+ def send_path
331
+ "/api/send#{"/#{inbox_id}" if sandbox}"
332
+ end
333
+
334
+ def batch_request_path
335
+ "/api/batch#{"/#{inbox_id}" if sandbox}"
320
336
  end
321
337
  end
322
338
  end
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Mailtrap
4
+ # Data Transfer Object for SandboxAttachment
5
+ # @see https://docs.mailtrap.io/developers/email-sandbox/email-sandbox-api/attachments
6
+ # @attr_reader id [Integer] The attachment ID
7
+ # @attr_reader message_id [Integer] The message ID
8
+ # @attr_reader filename [String] The attachment filename
9
+ # @attr_reader attachment_type [String] The attachment type
10
+ # @attr_reader content_type [String] The attachment content type
11
+ # @attr_reader content_id [String] The attachment content ID
12
+ # @attr_reader transfer_encoding [String] The attachment transfer encoding
13
+ # @attr_reader attachment_size [Integer] The attachment size in bytes
14
+ # @attr_reader created_at [String] The attachment creation timestamp
15
+ # @attr_reader updated_at [String] The attachment update timestamp
16
+ # @attr_reader attachment_human_size [String] The attachment size in human-readable format
17
+ # @attr_reader download_path [String] The attachment download path
18
+ #
19
+ SandboxAttachment = Struct.new(
20
+ :id,
21
+ :message_id,
22
+ :filename,
23
+ :attachment_type,
24
+ :content_type,
25
+ :content_id,
26
+ :transfer_encoding,
27
+ :attachment_size,
28
+ :created_at,
29
+ :updated_at,
30
+ :attachment_human_size,
31
+ :download_path,
32
+ keyword_init: true
33
+ )
34
+ end
@@ -0,0 +1,51 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'base_api'
4
+ require_relative 'sandbox_attachment'
5
+
6
+ module Mailtrap
7
+ class SandboxAttachmentsAPI
8
+ include BaseAPI
9
+
10
+ attr_reader :account_id, :inbox_id, :sandbox_message_id, :client
11
+
12
+ self.response_class = SandboxAttachment
13
+
14
+ # @param account_id [Integer] The account ID
15
+ # @param inbox_id [Integer] The inbox ID
16
+ # @param sandbox_message_id [Integer] The message ID
17
+ # @param client [Mailtrap::Client] The client instance
18
+ # @raise [ArgumentError] If account_id is nil
19
+ # @raise [ArgumentError] If inbox_id is nil
20
+ def initialize(account_id, inbox_id, sandbox_message_id, client = Mailtrap::Client.new)
21
+ raise ArgumentError, 'inbox_id is required' if inbox_id.nil?
22
+ raise ArgumentError, 'sandbox_message_id is required' if sandbox_message_id.nil?
23
+
24
+ @inbox_id = inbox_id
25
+ @sandbox_message_id = sandbox_message_id
26
+
27
+ super(account_id, client)
28
+ end
29
+
30
+ # Retrieves a specific sandbox attachment
31
+ # @param sandbox_attachment_id [Integer] The sandbox attachment ID
32
+ # @return [SandboxAttachment] Sandbox attachment object
33
+ # @!macro api_errors
34
+ def get(sandbox_attachment_id)
35
+ base_get(sandbox_attachment_id)
36
+ end
37
+
38
+ # Lists all sandbox attachments for a message, limited up to 30 at once
39
+ # @return [Array<SandboxAttachment>] Array of sandbox attachment objects
40
+ # @!macro api_errors
41
+ def list
42
+ base_list
43
+ end
44
+
45
+ private
46
+
47
+ def base_path
48
+ "/api/accounts/#{account_id}/inboxes/#{inbox_id}/messages/#{sandbox_message_id}/attachments"
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,59 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Mailtrap
4
+ # Data Transfer Object for Sandbox Message
5
+ # @see https://docs.mailtrap.io/developers/email-sandbox/email-sandbox-api/messages
6
+ # @attr_reader id [Integer] The message ID
7
+ # @attr_reader inbox_id [Integer] The inbox ID
8
+ # @attr_reader subject [String] The message subject
9
+ # @attr_reader sent_at [String] The timestamp when the message was sent
10
+ # @attr_reader from_email [String] The sender's email address
11
+ # @attr_reader from_name [String] The sender's name
12
+ # @attr_reader to_email [String] The recipient's email address
13
+ # @attr_reader to_name [String] The recipient's name
14
+ # @attr_reader email_size [Integer] The size of the email in bytes
15
+ # @attr_reader is_read [Boolean] Whether the message has been read
16
+ # @attr_reader created_at [String] The timestamp when the message was created
17
+ # @attr_reader updated_at [String] The timestamp when the message was last updated
18
+ # @attr_reader html_body_size [Integer] The size of the HTML body in bytes
19
+ # @attr_reader text_body_size [Integer] The size of the text body in bytes
20
+ # @attr_reader human_size [String] The human-readable size of the email
21
+ # @attr_reader html_path [String] The path to the HTML version of the email
22
+ # @attr_reader txt_path [String] The path to the text version of the email
23
+ # @attr_reader raw_path [String] The path to the raw version of the email
24
+ # @attr_reader download_path [String] The path to download the email
25
+ # @attr_reader html_source_path [String] The path to the HTML source of the email
26
+ # @attr_reader blacklists_report_info [Boolean] Information about blacklists report
27
+ # @attr_reader smtp_information [Hash] Information about SMTP
28
+ #
29
+ SandboxMessage = Struct.new(
30
+ :id,
31
+ :inbox_id,
32
+ :subject,
33
+ :sent_at,
34
+ :from_email,
35
+ :from_name,
36
+ :to_email,
37
+ :to_name,
38
+ :email_size,
39
+ :is_read,
40
+ :created_at,
41
+ :updated_at,
42
+ :html_body_size,
43
+ :text_body_size,
44
+ :human_size,
45
+ :html_path,
46
+ :txt_path,
47
+ :raw_path,
48
+ :download_path,
49
+ :html_source_path,
50
+ :blacklists_report_info,
51
+ :smtp_information,
52
+ keyword_init: true
53
+ ) do
54
+ # @return [Boolean] Whether the message has been read
55
+ def read?
56
+ is_read
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,155 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'base_api'
4
+ require_relative 'sandbox_message'
5
+
6
+ module Mailtrap
7
+ class SandboxMessagesAPI
8
+ include BaseAPI
9
+
10
+ attr_reader :account_id, :inbox_id, :client
11
+
12
+ self.supported_options = %i[is_read]
13
+
14
+ self.response_class = SandboxMessage
15
+
16
+ # @param account_id [Integer] The account ID
17
+ # @param inbox_id [Integer] The inbox ID
18
+ # @param client [Mailtrap::Client] The client instance
19
+ # @raise [ArgumentError] If account_id is nil
20
+ # @raise [ArgumentError] If inbox_id is nil
21
+ def initialize(account_id, inbox_id, client = Mailtrap::Client.new)
22
+ raise ArgumentError, 'inbox_id is required' if inbox_id.nil?
23
+
24
+ @inbox_id = inbox_id
25
+
26
+ super(account_id, client)
27
+ end
28
+
29
+ # Retrieves a specific sandbox message from inbox
30
+ # @param message_id [Integer] The sandbox message ID
31
+ # @return [SandboxMessage] Sandbox message object
32
+ # @!macro api_errors
33
+ def get(message_id)
34
+ base_get(message_id)
35
+ end
36
+
37
+ # Deletes a sandbox message
38
+ # @param message_id [Integer] The sandbox message ID
39
+ # @return [SandboxMessage] Deleted Sandbox message object
40
+ # @!macro api_errors
41
+ def delete(message_id)
42
+ base_delete(message_id)
43
+ end
44
+
45
+ # Updates an existing sandbox message
46
+ # @param message_id [Integer] The sandbox message ID
47
+ # @param is_read [Boolean]
48
+ # @return [SandboxMessage] Updated Sandbox message object
49
+ # @!macro api_errors
50
+ def mark_as_read(message_id, is_read: true)
51
+ base_update(message_id, { is_read: is_read })
52
+ end
53
+
54
+ # Lists all sandbox messages for the account, limited up to 30 at once
55
+ # @param search [String] Search query string. Matches subject, to_email, and to_name.
56
+ # @param last_id [Integer] If specified, a page of records before last_id is returned.
57
+ # Overrides page if both are given.
58
+ # @param page [Integer] Page number for paginated results.
59
+ # @return [Array<SandboxMessage>] Array of sandbox message objects
60
+ # @!macro api_errors
61
+ def list(search: nil, last_id: nil, page: nil)
62
+ raise ArgumentError, 'Provide either last_id or page, not both' unless last_id.nil? || page.nil?
63
+
64
+ query_params = {}
65
+ query_params[:search] = search unless search.nil?
66
+ query_params[:last_id] = last_id unless last_id.nil?
67
+ query_params[:page] = page unless page.nil?
68
+
69
+ base_list(query_params)
70
+ end
71
+
72
+ # Forward message to an email address.
73
+ # @param message_id [Integer] The sandbox message ID
74
+ # @param email [String] The email to forward sandbox message to
75
+ # @return [String] Forwarded message confirmation
76
+ # @!macro api_errors
77
+ def forward_message(message_id, email:)
78
+ client.post("#{base_path}/#{message_id}/forward", { email: email })
79
+ end
80
+
81
+ # Get message spam score
82
+ # @param message_id [Integer] The sandbox message ID
83
+ # @return [Hash] Spam report
84
+ # @!macro api_errors
85
+ def spam_score(message_id)
86
+ client.get("#{base_path}/#{message_id}/spam_report")
87
+ end
88
+
89
+ # Get message HTML analysis
90
+ # @param message_id [Integer] The sandbox message ID
91
+ # @return [Hash] brief HTML report
92
+ # @!macro api_errors
93
+ def html_analysis(message_id)
94
+ client.get("#{base_path}/#{message_id}/analyze")
95
+ end
96
+
97
+ # Get text message
98
+ # @param message_id [Integer] The sandbox message ID
99
+ # @return [String] text email body
100
+ # @!macro api_errors
101
+ def text_body(message_id)
102
+ client.get("#{base_path}/#{message_id}/body.txt")
103
+ end
104
+
105
+ # Get raw message
106
+ # @param message_id [Integer] The sandbox message ID
107
+ # @return [String] raw email body
108
+ # @!macro api_errors
109
+ def raw_body(message_id)
110
+ client.get("#{base_path}/#{message_id}/body.raw")
111
+ end
112
+
113
+ # Get message source
114
+ # @param message_id [Integer] The sandbox message ID
115
+ # @return [String] HTML source of a message.
116
+ # @!macro api_errors
117
+ def html_source(message_id)
118
+ client.get("#{base_path}/#{message_id}/body.htmlsource")
119
+ end
120
+
121
+ # Get formatted HTML email body. Not applicable for plain text emails.
122
+ # @param message_id [Integer] The sandbox message ID
123
+ # @return [String] message body in html format.
124
+ # @!macro api_errors
125
+ def html_body(message_id)
126
+ client.get("#{base_path}/#{message_id}/body.html")
127
+ end
128
+
129
+ # Get message as EML
130
+ # @param message_id [Integer] The sandbox message ID
131
+ # @return [String] mail message body in EML format.
132
+ # @!macro api_errors
133
+ def eml_body(message_id)
134
+ client.get("#{base_path}/#{message_id}/body.eml")
135
+ end
136
+
137
+ # Get mail headers
138
+ # @param message_id [Integer] The sandbox message ID
139
+ # @return [Hash] mail headers of the message.
140
+ # @!macro api_errors
141
+ def mail_headers(message_id)
142
+ client.get("#{base_path}/#{message_id}/mail_headers")
143
+ end
144
+
145
+ private
146
+
147
+ def base_path
148
+ "/api/accounts/#{account_id}/inboxes/#{inbox_id}/messages"
149
+ end
150
+
151
+ def wrap_request(options)
152
+ { message: options }
153
+ end
154
+ end
155
+ end
@@ -0,0 +1,42 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Mailtrap
4
+ # Data Transfer Object for Sending Domain
5
+ # @see https://docs.mailtrap.io/developers/management/sending-domains
6
+ # @attr_reader id [Integer] The sending domain ID
7
+ # @attr_reader domain_name [String] The sending domain name
8
+ # @attr_reader demo [Boolean] Whether the sending domain is a demo domain
9
+ # @attr_reader compliance_status [String] The compliance status of the sending domain
10
+ # @attr_reader dns_verified [Boolean] Whether the DNS records are verified
11
+ # @attr_reader dns_verified_at [String, nil] The timestamp when DNS was verified
12
+ # @attr_reader dns_records [Array] The DNS records for the sending domain
13
+ # @attr_reader open_tracking_enabled [Boolean] Whether open tracking is enabled
14
+ # @attr_reader click_tracking_enabled [Boolean] Whether click tracking is enabled
15
+ # @attr_reader auto_unsubscribe_link_enabled [Boolean] Whether auto unsubscribe link is enabled
16
+ # @attr_reader custom_domain_tracking_enabled [Boolean] Whether custom domain tracking is enabled
17
+ # @attr_reader health_alerts_enabled [Boolean] Whether health alerts are enabled
18
+ # @attr_reader critical_alerts_enabled [Boolean] Whether critical alerts are enabled
19
+ # @attr_reader alert_recipient_email [String, nil] The email address for alert recipients
20
+ # @attr_reader permissions [Hash] The permissions for the sending domain
21
+ #
22
+ SendingDomain = Struct.new(
23
+ :id,
24
+ :domain_name,
25
+ :demo,
26
+ :compliance_status,
27
+ :dns_verified,
28
+ :dns_verified_at,
29
+ :dns_records,
30
+ :open_tracking_enabled,
31
+ :click_tracking_enabled,
32
+ :auto_unsubscribe_link_enabled,
33
+ :custom_domain_tracking_enabled,
34
+ :health_alerts_enabled,
35
+ :critical_alerts_enabled,
36
+ :alert_recipient_email,
37
+ :permissions,
38
+ :created_at,
39
+ :updated_at,
40
+ keyword_init: true
41
+ )
42
+ end
@@ -0,0 +1,67 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'base_api'
4
+ require_relative 'sending_domain'
5
+
6
+ module Mailtrap
7
+ class SendingDomainsAPI
8
+ include BaseAPI
9
+
10
+ self.supported_options = %i[domain_name]
11
+
12
+ self.response_class = SendingDomain
13
+
14
+ # Lists all sending domains for the account
15
+ # @return [Array<SendingDomain>] Array of sending domains
16
+ # @!macro api_errors
17
+ def list
18
+ response = client.get(base_path)
19
+ response[:data].map { |item| handle_response(item) }
20
+ end
21
+
22
+ # Retrieves a specific sending domain
23
+ # @param domain_id [Integer] The sending domain ID
24
+ # @return [SendingDomain] Sending domain object
25
+ # @!macro api_errors
26
+ def get(domain_id)
27
+ base_get(domain_id)
28
+ end
29
+
30
+ # Creates a new sending domain
31
+ # @param [Hash] options The parameters to create
32
+ # @option options [String] :domain_name The sending domain name
33
+ # @return [SendingDomain] Created sending domain
34
+ # @!macro api_errors
35
+ # @raise [ArgumentError] If invalid options are provided
36
+ def create(options)
37
+ base_create(options)
38
+ end
39
+
40
+ # Deletes a sending domain
41
+ # @param domain_id [Integer] The sending domain ID
42
+ # @return nil
43
+ # @!macro api_errors
44
+ def delete(domain_id)
45
+ base_delete(domain_id)
46
+ end
47
+
48
+ # Email DNS configuration instructions for the sending domain
49
+ # @param domain_id [Integer] The sending domain ID
50
+ # @param email [String] The email for instructions
51
+ # @return nil
52
+ # @!macro api_errors
53
+ def send_setup_instructions(domain_id, email:)
54
+ client.post("#{base_path}/#{domain_id}/send_setup_instructions", email:)
55
+ end
56
+
57
+ private
58
+
59
+ def base_path
60
+ "/api/accounts/#{account_id}/sending_domains"
61
+ end
62
+
63
+ def wrap_request(options)
64
+ { sending_domain: options }
65
+ end
66
+ end
67
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Mailtrap
4
- VERSION = '2.6.0'
4
+ VERSION = '2.7.0'
5
5
  end
data/lib/mailtrap.rb CHANGED
@@ -4,14 +4,18 @@ require_relative 'mailtrap/action_mailer' if defined? ActionMailer
4
4
  require_relative 'mailtrap/mail'
5
5
  require_relative 'mailtrap/errors'
6
6
  require_relative 'mailtrap/version'
7
+ require_relative 'mailtrap/accounts_api'
7
8
  require_relative 'mailtrap/email_templates_api'
8
9
  require_relative 'mailtrap/contacts_api'
9
10
  require_relative 'mailtrap/contact_lists_api'
10
11
  require_relative 'mailtrap/contact_fields_api'
11
12
  require_relative 'mailtrap/contact_imports_api'
12
13
  require_relative 'mailtrap/suppressions_api'
14
+ require_relative 'mailtrap/sending_domains_api'
13
15
  require_relative 'mailtrap/projects_api'
14
16
  require_relative 'mailtrap/inboxes_api'
17
+ require_relative 'mailtrap/sandbox_messages_api'
18
+ require_relative 'mailtrap/sandbox_attachments_api'
15
19
 
16
20
  module Mailtrap
17
21
  # @!macro api_errors
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mailtrap
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.6.0
4
+ version: 2.7.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Railsware Products Studio LLC
@@ -30,6 +30,7 @@ executables: []
30
30
  extensions: []
31
31
  extra_rdoc_files: []
32
32
  files:
33
+ - ".coderabbit.yaml"
33
34
  - ".rspec"
34
35
  - ".rubocop.yml"
35
36
  - Appraisals
@@ -41,6 +42,8 @@ files:
41
42
  - README.md
42
43
  - Rakefile
43
44
  - lib/mailtrap.rb
45
+ - lib/mailtrap/account.rb
46
+ - lib/mailtrap/accounts_api.rb
44
47
  - lib/mailtrap/action_mailer.rb
45
48
  - lib/mailtrap/action_mailer/delivery_method.rb
46
49
  - lib/mailtrap/action_mailer/railtie.rb
@@ -66,6 +69,12 @@ files:
66
69
  - lib/mailtrap/mail/from_template.rb
67
70
  - lib/mailtrap/project.rb
68
71
  - lib/mailtrap/projects_api.rb
72
+ - lib/mailtrap/sandbox_attachment.rb
73
+ - lib/mailtrap/sandbox_attachments_api.rb
74
+ - lib/mailtrap/sandbox_message.rb
75
+ - lib/mailtrap/sandbox_messages_api.rb
76
+ - lib/mailtrap/sending_domain.rb
77
+ - lib/mailtrap/sending_domains_api.rb
69
78
  - lib/mailtrap/suppression.rb
70
79
  - lib/mailtrap/suppressions_api.rb
71
80
  - lib/mailtrap/version.rb
@@ -92,7 +101,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
92
101
  - !ruby/object:Gem::Version
93
102
  version: '0'
94
103
  requirements: []
95
- rubygems_version: 3.6.9
104
+ rubygems_version: 4.0.3
96
105
  specification_version: 4
97
106
  summary: Official mailtrap.io API client
98
107
  test_files: []