mailtrap 2.3.0 → 2.4.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 +4 -4
- data/.rubocop.yml +12 -0
- data/CHANGELOG.md +9 -0
- data/Gemfile +3 -0
- data/Gemfile.lock +46 -19
- data/README.md +92 -6
- data/lib/mailtrap/base_api.rb +84 -0
- data/lib/mailtrap/client.rb +198 -27
- data/lib/mailtrap/contact.rb +38 -0
- data/lib/mailtrap/contact_field.rb +18 -0
- data/lib/mailtrap/contact_fields_api.rb +67 -0
- data/lib/mailtrap/contact_list.rb +14 -0
- data/lib/mailtrap/contact_lists_api.rb +64 -0
- data/lib/mailtrap/contacts_api.rb +90 -0
- data/lib/mailtrap/email_template.rb +35 -0
- data/lib/mailtrap/email_templates_api.rb +76 -0
- data/lib/mailtrap/mail/base.rb +17 -6
- data/lib/mailtrap/mail/from_template.rb +3 -24
- data/lib/mailtrap/mail.rb +180 -26
- data/lib/mailtrap/version.rb +1 -1
- data/lib/mailtrap.rb +11 -1
- data/mailtrap.gemspec +2 -0
- metadata +26 -3
data/lib/mailtrap/client.rb
CHANGED
@@ -9,57 +9,193 @@ module Mailtrap
|
|
9
9
|
SENDING_API_HOST = 'send.api.mailtrap.io'
|
10
10
|
BULK_SENDING_API_HOST = 'bulk.api.mailtrap.io'
|
11
11
|
SANDBOX_API_HOST = 'sandbox.api.mailtrap.io'
|
12
|
+
GENERAL_API_HOST = 'mailtrap.io'
|
12
13
|
API_PORT = 443
|
13
14
|
|
14
|
-
attr_reader :api_key, :api_host, :api_port, :bulk, :sandbox, :inbox_id
|
15
|
+
attr_reader :api_key, :api_host, :general_api_host, :api_port, :bulk, :sandbox, :inbox_id
|
15
16
|
|
16
17
|
# Initializes a new Mailtrap::Client instance.
|
17
18
|
#
|
18
19
|
# @param [String] api_key The Mailtrap API key to use for sending. Required.
|
19
|
-
#
|
20
|
-
# @param [String
|
20
|
+
# If not set, it is taken from the MAILTRAP_API_KEY environment variable.
|
21
|
+
# @param [String] api_host The Mailtrap API hostname. If not set, it is chosen internally.
|
22
|
+
# @param [String] general_api_host The Mailtrap general API hostname for non-sending operations.
|
21
23
|
# @param [Integer] api_port The Mailtrap API port. Default: 443.
|
22
24
|
# @param [Boolean] bulk Whether to use the Mailtrap bulk sending API. Default: false.
|
23
|
-
#
|
25
|
+
# If enabled, it is incompatible with `sandbox: true`.
|
24
26
|
# @param [Boolean] sandbox Whether to use the Mailtrap sandbox API. Default: false.
|
25
|
-
#
|
27
|
+
# If enabled, it is incompatible with `bulk: true`.
|
26
28
|
# @param [Integer] inbox_id The sandbox inbox ID to send to. Required if sandbox API is used.
|
29
|
+
# @raise [ArgumentError] If api_key or api_port is nil, or if sandbox is true but inbox_id is nil,
|
30
|
+
# or if incompatible options are provided.
|
27
31
|
def initialize( # rubocop:disable Metrics/ParameterLists
|
28
32
|
api_key: ENV.fetch('MAILTRAP_API_KEY'),
|
29
33
|
api_host: nil,
|
34
|
+
general_api_host: GENERAL_API_HOST,
|
30
35
|
api_port: API_PORT,
|
31
36
|
bulk: false,
|
32
37
|
sandbox: false,
|
33
38
|
inbox_id: nil
|
34
39
|
)
|
35
|
-
|
36
|
-
raise ArgumentError, 'api_port is required' if api_port.nil?
|
40
|
+
validate_args!(api_key, api_port, bulk, sandbox, inbox_id)
|
37
41
|
|
38
42
|
api_host ||= select_api_host(bulk:, sandbox:)
|
39
|
-
raise ArgumentError, 'inbox_id is required for sandbox API' if sandbox && inbox_id.nil?
|
40
43
|
|
41
44
|
@api_key = api_key
|
42
45
|
@api_host = api_host
|
46
|
+
@general_api_host = general_api_host
|
43
47
|
@api_port = api_port
|
44
48
|
@bulk = bulk
|
45
49
|
@sandbox = sandbox
|
46
50
|
@inbox_id = inbox_id
|
51
|
+
@http_clients = {}
|
52
|
+
end
|
53
|
+
|
54
|
+
# Sends a batch of emails.
|
55
|
+
# @example Batch sending with template
|
56
|
+
# batch_base = Mailtrap::Mail.batch_base_from_template(
|
57
|
+
# from: { email: 'mailtrap@demomailtrap.co', name: 'Mailtrap Test' },
|
58
|
+
# reply_to: { email: 'support@example.com', name: 'Mailtrap Reply-To' },
|
59
|
+
# template_uuid: '339c8ab0-e73c-4269-984e-0d2446aacf2c'
|
60
|
+
# )
|
61
|
+
#
|
62
|
+
# client.send_batch(
|
63
|
+
# batch_base, [
|
64
|
+
# Mailtrap::Mail.from_template(
|
65
|
+
# to: [
|
66
|
+
# { email: 'john.doe@email.com', name: 'John Doe' }
|
67
|
+
# ],
|
68
|
+
# template_variables: {
|
69
|
+
# user_name: 'John Doe'
|
70
|
+
# }
|
71
|
+
# ),
|
72
|
+
# Mailtrap::Mail::Base.new(
|
73
|
+
# to: [
|
74
|
+
# { email: 'jane.doe@email.com', name: 'Jane Doe' }
|
75
|
+
# ],
|
76
|
+
# template_variables: {
|
77
|
+
# user_name: 'Jane Doe'
|
78
|
+
# }
|
79
|
+
# ),
|
80
|
+
# {
|
81
|
+
# to: [
|
82
|
+
# { email: 'david.doe@email.com', name: 'David Doe' }
|
83
|
+
# ],
|
84
|
+
# template_variables: {
|
85
|
+
# user_name: 'David Doe'
|
86
|
+
# }
|
87
|
+
# }
|
88
|
+
# ]
|
89
|
+
# )
|
90
|
+
#
|
91
|
+
# @example Passing the request parameters directly
|
92
|
+
# client.send_batch(
|
93
|
+
# {
|
94
|
+
# from: { email: 'mailtrap@demomailtrap.co', name: 'Mailtrap Test' },
|
95
|
+
# reply_to: { email: 'support@example.com', name: 'Mailtrap Reply-To' },
|
96
|
+
# template_uuid: '339c8ab0-e73c-4269-984e-0d2446aacf2c'
|
97
|
+
# }, [
|
98
|
+
# {
|
99
|
+
# to: [
|
100
|
+
# { email: 'john.doe@email.com', name: 'John Doe' }
|
101
|
+
# ],
|
102
|
+
# template_variables: {
|
103
|
+
# user_name: 'John Doe'
|
104
|
+
# }
|
105
|
+
# },
|
106
|
+
# {
|
107
|
+
# to: [
|
108
|
+
# { email: 'jane.doe@email.com', name: 'Jane Doe' }
|
109
|
+
# ],
|
110
|
+
# template_variables: {
|
111
|
+
# user_name: 'Jane Doe'
|
112
|
+
# }
|
113
|
+
# }
|
114
|
+
# ]
|
115
|
+
# )
|
116
|
+
# @param base [#to_json] The base email configuration for the batch.
|
117
|
+
# @param requests [Array<#to_json>] Array of individual email requests.
|
118
|
+
# @return [Hash] The JSON response from the API.
|
119
|
+
# @!macro api_errors
|
120
|
+
# @raise [Mailtrap::MailSizeError] If the message is too large.
|
121
|
+
def send_batch(base, requests)
|
122
|
+
perform_request(:post, api_host, batch_request_path, {
|
123
|
+
base:,
|
124
|
+
requests:
|
125
|
+
})
|
47
126
|
end
|
48
127
|
|
128
|
+
# Sends an email
|
129
|
+
# @example
|
130
|
+
# mail = Mailtrap::Mail.from_template(
|
131
|
+
# from: { email: 'mailtrap@example.com', name: 'Mailtrap Test' },
|
132
|
+
# to: [
|
133
|
+
# { email: 'your@email.com' }
|
134
|
+
# ],
|
135
|
+
# template_uuid: '2f45b0aa-bbed-432f-95e4-e145e1965ba2',
|
136
|
+
# template_variables: {
|
137
|
+
# 'user_name' => 'John Doe'
|
138
|
+
# }
|
139
|
+
# )
|
140
|
+
# client.send(mail)
|
141
|
+
# @example
|
142
|
+
# client.send(
|
143
|
+
# from: { email: 'mailtrap@example.com', name: 'Mailtrap Test' },
|
144
|
+
# to: [
|
145
|
+
# { email: 'your@email.com' }
|
146
|
+
# ],
|
147
|
+
# subject: 'You are awesome!',
|
148
|
+
# text: 'Congrats for sending test email with Mailtrap!'
|
149
|
+
# )
|
150
|
+
# @param mail [#to_json] The email to send
|
151
|
+
# @return [Hash] The JSON response
|
152
|
+
# @!macro api_errors
|
153
|
+
# @raise [Mailtrap::MailSizeError] If the message is too large
|
49
154
|
def send(mail)
|
50
|
-
|
155
|
+
perform_request(:post, api_host, send_path, mail)
|
156
|
+
end
|
51
157
|
|
52
|
-
|
53
|
-
|
158
|
+
# Performs a GET request to the specified path
|
159
|
+
# @param path [String] The request path
|
160
|
+
# @return [Hash, nil] The JSON response
|
161
|
+
# @!macro api_errors
|
162
|
+
def get(path)
|
163
|
+
perform_request(:get, general_api_host, path)
|
164
|
+
end
|
54
165
|
|
55
|
-
|
166
|
+
# Performs a POST request to the specified path
|
167
|
+
# @param path [String] The request path
|
168
|
+
# @param body [Hash] The request body
|
169
|
+
# @return [Hash, nil] The JSON response
|
170
|
+
# @!macro api_errors
|
171
|
+
def post(path, body = nil)
|
172
|
+
perform_request(:post, general_api_host, path, body)
|
173
|
+
end
|
174
|
+
|
175
|
+
# Performs a PATCH request to the specified path
|
176
|
+
# @param path [String] The request path
|
177
|
+
# @param body [Hash] The request body
|
178
|
+
# @return [Hash, nil] The JSON response
|
179
|
+
# @!macro api_errors
|
180
|
+
def patch(path, body = nil)
|
181
|
+
perform_request(:patch, general_api_host, path, body)
|
182
|
+
end
|
183
|
+
|
184
|
+
# Performs a DELETE request to the specified path
|
185
|
+
# @param path [String] The request path
|
186
|
+
# @return [Hash, nil] The JSON response
|
187
|
+
# @!macro api_errors
|
188
|
+
def delete(path)
|
189
|
+
perform_request(:delete, general_api_host, path)
|
56
190
|
end
|
57
191
|
|
58
192
|
private
|
59
193
|
|
60
|
-
def
|
61
|
-
|
194
|
+
def http_client_for(host)
|
195
|
+
@http_clients[host] ||= Net::HTTP.new(host, api_port).tap { |client| client.use_ssl = true }
|
196
|
+
end
|
62
197
|
|
198
|
+
def select_api_host(bulk:, sandbox:)
|
63
199
|
if sandbox
|
64
200
|
SANDBOX_API_HOST
|
65
201
|
elsif bulk
|
@@ -69,17 +205,36 @@ module Mailtrap
|
|
69
205
|
end
|
70
206
|
end
|
71
207
|
|
72
|
-
def
|
73
|
-
"/api/send#{
|
208
|
+
def send_path
|
209
|
+
"/api/send#{"/#{inbox_id}" if sandbox}"
|
210
|
+
end
|
211
|
+
|
212
|
+
def batch_request_path
|
213
|
+
"/api/batch#{"/#{inbox_id}" if sandbox}"
|
74
214
|
end
|
75
215
|
|
76
|
-
def
|
77
|
-
|
216
|
+
def perform_request(method, host, path, body = nil)
|
217
|
+
http_client = http_client_for(host)
|
218
|
+
request = setup_request(method, path, body)
|
219
|
+
response = http_client.request(request)
|
220
|
+
handle_response(response)
|
78
221
|
end
|
79
222
|
|
80
|
-
def
|
81
|
-
request =
|
82
|
-
|
223
|
+
def setup_request(method, path, body = nil)
|
224
|
+
request = case method
|
225
|
+
when :get
|
226
|
+
Net::HTTP::Get.new(path)
|
227
|
+
when :post
|
228
|
+
Net::HTTP::Post.new(path)
|
229
|
+
when :patch
|
230
|
+
Net::HTTP::Patch.new(path)
|
231
|
+
when :delete
|
232
|
+
Net::HTTP::Delete.new(path)
|
233
|
+
else
|
234
|
+
raise ArgumentError, "Unsupported HTTP method: #{method}"
|
235
|
+
end
|
236
|
+
|
237
|
+
request.body = body.to_json if body
|
83
238
|
request['Authorization'] = "Bearer #{api_key}"
|
84
239
|
request['Content-Type'] = 'application/json'
|
85
240
|
request['User-Agent'] = 'mailtrap-ruby (https://github.com/railsware/mailtrap-ruby)'
|
@@ -87,22 +242,26 @@ module Mailtrap
|
|
87
242
|
request
|
88
243
|
end
|
89
244
|
|
90
|
-
def handle_response(response) # rubocop:disable Metrics/
|
245
|
+
def handle_response(response) # rubocop:disable Metrics/CyclomaticComplexity, Metrics/MethodLength
|
91
246
|
case response
|
92
|
-
when Net::HTTPOK
|
247
|
+
when Net::HTTPOK, Net::HTTPCreated
|
93
248
|
json_response(response.body)
|
249
|
+
when Net::HTTPNoContent
|
250
|
+
nil
|
94
251
|
when Net::HTTPBadRequest
|
95
|
-
raise Mailtrap::Error,
|
252
|
+
raise Mailtrap::Error, ['bad request'] if response.body.empty?
|
253
|
+
|
254
|
+
raise Mailtrap::Error, response_errors(response.body)
|
96
255
|
when Net::HTTPUnauthorized
|
97
|
-
raise Mailtrap::AuthorizationError,
|
256
|
+
raise Mailtrap::AuthorizationError, response_errors(response.body)
|
98
257
|
when Net::HTTPForbidden
|
99
|
-
raise Mailtrap::RejectionError,
|
258
|
+
raise Mailtrap::RejectionError, response_errors(response.body)
|
100
259
|
when Net::HTTPPayloadTooLarge
|
101
260
|
raise Mailtrap::MailSizeError, ['message too large']
|
102
261
|
when Net::HTTPTooManyRequests
|
103
262
|
raise Mailtrap::RateLimitError, ['too many requests']
|
104
263
|
when Net::HTTPClientError
|
105
|
-
raise Mailtrap::Error, [
|
264
|
+
raise Mailtrap::Error, ["client error '#{response.body}'"]
|
106
265
|
when Net::HTTPServerError
|
107
266
|
raise Mailtrap::Error, ['server error']
|
108
267
|
else
|
@@ -110,8 +269,20 @@ module Mailtrap
|
|
110
269
|
end
|
111
270
|
end
|
112
271
|
|
272
|
+
def response_errors(body)
|
273
|
+
parsed_body = json_response(body)
|
274
|
+
Array(parsed_body[:errors] || parsed_body[:error])
|
275
|
+
end
|
276
|
+
|
113
277
|
def json_response(body)
|
114
278
|
JSON.parse(body, symbolize_names: true)
|
115
279
|
end
|
280
|
+
|
281
|
+
def validate_args!(api_key, api_port, bulk, sandbox, inbox_id)
|
282
|
+
raise ArgumentError, 'api_key is required' if api_key.nil?
|
283
|
+
raise ArgumentError, 'api_port is required' if api_port.nil?
|
284
|
+
raise ArgumentError, 'bulk stream is not applicable for sandbox API' if bulk && sandbox
|
285
|
+
raise ArgumentError, 'inbox_id is required for sandbox API' if sandbox && inbox_id.nil?
|
286
|
+
end
|
116
287
|
end
|
117
288
|
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Mailtrap
|
4
|
+
# Data Transfer Object for Contact
|
5
|
+
# @see https://api-docs.mailtrap.io/docs/mailtrap-api-docs/220a54e31e5ca-contact
|
6
|
+
# @attr_reader id [String] The contact ID
|
7
|
+
# @attr_reader email [String] The contact's email address
|
8
|
+
# @attr_reader fields [Hash] Object of fields with merge tags
|
9
|
+
# @attr_reader list_ids [Array<Integer>] Array of list IDs
|
10
|
+
# @attr_reader status [String] The contact status (subscribed/unsubscribed)
|
11
|
+
# @attr_reader created_at [Integer] The creation timestamp
|
12
|
+
# @attr_reader updated_at [Integer] The last update timestamp
|
13
|
+
Contact = Struct.new(
|
14
|
+
:id,
|
15
|
+
:email,
|
16
|
+
:fields,
|
17
|
+
:list_ids,
|
18
|
+
:status,
|
19
|
+
:created_at,
|
20
|
+
:updated_at,
|
21
|
+
keyword_init: true
|
22
|
+
) do
|
23
|
+
def initialize(options)
|
24
|
+
@action = options[:action]
|
25
|
+
super(options.except(:action))
|
26
|
+
end
|
27
|
+
|
28
|
+
# @return [Boolean] Whether the contact was newly created
|
29
|
+
def newly_created?
|
30
|
+
@action != 'updated'
|
31
|
+
end
|
32
|
+
|
33
|
+
# @return [Hash] The contact attributes as a hash
|
34
|
+
def to_h
|
35
|
+
super.compact
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Mailtrap
|
4
|
+
# Data Transfer Object for Contact Field
|
5
|
+
# @see https://api-docs.mailtrap.io/docs/mailtrap-api-docs/33efe96c91dcc-get-all-contact-fields
|
6
|
+
# @attr_reader id [Integer] The contact field ID
|
7
|
+
# @attr_reader name [String] The name of the contact field (max 80 characters)
|
8
|
+
# @attr_reader data_type [String] The data type of the field
|
9
|
+
# Allowed values: text, integer, float, boolean, date
|
10
|
+
# @attr_reader merge_tag [String] Personalize your campaigns by adding a merge tag.
|
11
|
+
# This field will be replaced with unique contact details for each recipient (max 80 characters)
|
12
|
+
ContactField = Struct.new(:id, :name, :data_type, :merge_tag, keyword_init: true) do
|
13
|
+
# @return [Hash] The contact field attributes as a hash
|
14
|
+
def to_h
|
15
|
+
super.compact
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'base_api'
|
4
|
+
require_relative 'contact_field'
|
5
|
+
|
6
|
+
module Mailtrap
|
7
|
+
class ContactFieldsAPI
|
8
|
+
include BaseAPI
|
9
|
+
|
10
|
+
self.supported_options = %i[name data_type merge_tag]
|
11
|
+
|
12
|
+
self.response_class = ContactField
|
13
|
+
|
14
|
+
# Retrieves a specific contact field
|
15
|
+
# @param field_id [Integer] The contact field identifier
|
16
|
+
# @return [ContactField] Contact field object
|
17
|
+
# @!macro api_errors
|
18
|
+
def get(field_id)
|
19
|
+
base_get(field_id)
|
20
|
+
end
|
21
|
+
|
22
|
+
# Creates a new contact field
|
23
|
+
# @param [Hash] options The parameters to create
|
24
|
+
# @option options [String] :name The contact field name
|
25
|
+
# @option options [String] :data_type The data type of the field
|
26
|
+
# @option options [String] :merge_tag The merge tag of the field
|
27
|
+
# @return [ContactField] Created contact field object
|
28
|
+
# @!macro api_errors
|
29
|
+
# @raise [ArgumentError] If invalid options are provided
|
30
|
+
def create(options)
|
31
|
+
base_create(options)
|
32
|
+
end
|
33
|
+
|
34
|
+
# Updates an existing contact field
|
35
|
+
# @param field_id [Integer] The contact field ID
|
36
|
+
# @param [Hash] options The parameters to update
|
37
|
+
# @option options [String] :name The contact field name
|
38
|
+
# @option options [String] :merge_tag The merge tag of the field
|
39
|
+
# @return [ContactField] Updated contact field object
|
40
|
+
# @!macro api_errors
|
41
|
+
# @raise [ArgumentError] If invalid options are provided
|
42
|
+
def update(field_id, options)
|
43
|
+
base_update(field_id, options, %i[name merge_tag])
|
44
|
+
end
|
45
|
+
|
46
|
+
# Deletes a contact field
|
47
|
+
# @param field_id [Integer] The contact field ID
|
48
|
+
# @return nil
|
49
|
+
# @!macro api_errors
|
50
|
+
def delete(field_id)
|
51
|
+
base_delete(field_id)
|
52
|
+
end
|
53
|
+
|
54
|
+
# Lists all contact fields for the account
|
55
|
+
# @return [Array<ContactField>] Array of contact field objects
|
56
|
+
# @!macro api_errors
|
57
|
+
def list
|
58
|
+
base_list
|
59
|
+
end
|
60
|
+
|
61
|
+
private
|
62
|
+
|
63
|
+
def base_path
|
64
|
+
"/api/accounts/#{account_id}/contacts/fields"
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Mailtrap
|
4
|
+
# Data Transfer Object for Contact List
|
5
|
+
# @see https://api-docs.mailtrap.io/docs/mailtrap-api-docs/6ec7a37234af2-contact-list
|
6
|
+
# @attr_reader id [Integer] The contact list ID
|
7
|
+
# @attr_reader name [String] The name of the contact list
|
8
|
+
ContactList = Struct.new(:id, :name, keyword_init: true) do
|
9
|
+
# @return [Hash] The contact list attributes as a hash
|
10
|
+
def to_h
|
11
|
+
super.compact
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'base_api'
|
4
|
+
require_relative 'contact_list'
|
5
|
+
|
6
|
+
module Mailtrap
|
7
|
+
class ContactListsAPI
|
8
|
+
include BaseAPI
|
9
|
+
|
10
|
+
self.supported_options = %i[name]
|
11
|
+
|
12
|
+
self.response_class = ContactList
|
13
|
+
|
14
|
+
# Retrieves a specific contact list
|
15
|
+
# @param list_id [Integer] The contact list identifier
|
16
|
+
# @return [ContactList] Contact list object
|
17
|
+
# @!macro api_errors
|
18
|
+
def get(list_id)
|
19
|
+
base_get(list_id)
|
20
|
+
end
|
21
|
+
|
22
|
+
# Creates a new contact list
|
23
|
+
# @param [Hash] options The parameters to create
|
24
|
+
# @option options [String] :name The contact list name
|
25
|
+
# @return [ContactList] Created contact list object
|
26
|
+
# @!macro api_errors
|
27
|
+
# @raise [ArgumentError] If invalid options are provided
|
28
|
+
def create(options)
|
29
|
+
base_create(options)
|
30
|
+
end
|
31
|
+
|
32
|
+
# Updates an existing contact list
|
33
|
+
# @param list_id [Integer] The contact list ID
|
34
|
+
# @param [Hash] options The parameters to update
|
35
|
+
# @option options [String] :name The contact list name
|
36
|
+
# @return [ContactList] Updated contact list object
|
37
|
+
# @!macro api_errors
|
38
|
+
# @raise [ArgumentError] If invalid options are provided
|
39
|
+
def update(list_id, options)
|
40
|
+
base_update(list_id, options)
|
41
|
+
end
|
42
|
+
|
43
|
+
# Deletes a contact list
|
44
|
+
# @param list_id [Integer] The contact list ID
|
45
|
+
# @return nil
|
46
|
+
# @!macro api_errors
|
47
|
+
def delete(list_id)
|
48
|
+
base_delete(list_id)
|
49
|
+
end
|
50
|
+
|
51
|
+
# Lists all contact lists for the account
|
52
|
+
# @return [Array<ContactList>] Array of contact list objects
|
53
|
+
# @!macro api_errors
|
54
|
+
def list
|
55
|
+
base_list
|
56
|
+
end
|
57
|
+
|
58
|
+
private
|
59
|
+
|
60
|
+
def base_path
|
61
|
+
"/api/accounts/#{account_id}/contacts/lists"
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
@@ -0,0 +1,90 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'base_api'
|
4
|
+
require_relative 'contact'
|
5
|
+
|
6
|
+
module Mailtrap
|
7
|
+
class ContactsAPI
|
8
|
+
include BaseAPI
|
9
|
+
|
10
|
+
self.supported_options = %i[email fields list_ids]
|
11
|
+
self.response_class = Contact
|
12
|
+
|
13
|
+
# Retrieves a specific contact
|
14
|
+
# @param contact_id [String] The contact identifier, which can be either a UUID or an email address
|
15
|
+
# @return [Contact] Contact object
|
16
|
+
# @!macro api_errors
|
17
|
+
def get(contact_id)
|
18
|
+
base_get(contact_id)
|
19
|
+
end
|
20
|
+
|
21
|
+
# Creates a new contact
|
22
|
+
# @param [Hash] options The parameters to create
|
23
|
+
# @option options [String] :email The contact's email address
|
24
|
+
# @option options [Hash] :fields The contact's fields
|
25
|
+
# @option options [Array<Integer>] :list_ids The contact's list IDs
|
26
|
+
# @return [Contact] Created contact object
|
27
|
+
# @!macro api_errors
|
28
|
+
# @raise [ArgumentError] If invalid options are provided
|
29
|
+
def create(options)
|
30
|
+
base_create(options)
|
31
|
+
end
|
32
|
+
|
33
|
+
# Deletes a contact
|
34
|
+
# @param contact_id [String] The contact ID
|
35
|
+
# @return nil
|
36
|
+
# @!macro api_errors
|
37
|
+
def delete(contact_id)
|
38
|
+
base_delete(contact_id)
|
39
|
+
end
|
40
|
+
|
41
|
+
# Updates an existing contact or creates a new one if it doesn't exist
|
42
|
+
# @param contact_id [String] The contact ID or email address
|
43
|
+
# @param [Hash] options The parameters to update
|
44
|
+
# @option options [String] :email The contact's email address
|
45
|
+
# @option options [Hash] :fields The contact's fields
|
46
|
+
# @option options [Boolean] :unsubscribed Whether to unsubscribe the contact
|
47
|
+
# @return [Contact] Updated contact object
|
48
|
+
# @!macro api_errors
|
49
|
+
# @raise [ArgumentError] If invalid options are provided
|
50
|
+
def upsert(contact_id, options)
|
51
|
+
base_update(contact_id, options, %i[email fields unsubscribed])
|
52
|
+
end
|
53
|
+
|
54
|
+
# Adds a contact to specified lists
|
55
|
+
# @param contact_id [String] The contact ID or email address
|
56
|
+
# @param contact_list_ids [Array<Integer>] Array of list IDs to add the contact to
|
57
|
+
# @return [Contact] Updated contact object
|
58
|
+
# @!macro api_errors
|
59
|
+
def add_to_lists(contact_id, contact_list_ids = [])
|
60
|
+
update_lists(contact_id, list_ids_included: contact_list_ids)
|
61
|
+
end
|
62
|
+
|
63
|
+
# Removes a contact from specified lists
|
64
|
+
# @param contact_id [String] The contact ID or email address
|
65
|
+
# @param contact_list_ids [Array<Integer>] Array of list IDs to remove the contact from
|
66
|
+
# @return [Contact] Updated contact object
|
67
|
+
# @!macro api_errors
|
68
|
+
def remove_from_lists(contact_id, contact_list_ids = [])
|
69
|
+
update_lists(contact_id, list_ids_excluded: contact_list_ids)
|
70
|
+
end
|
71
|
+
|
72
|
+
private
|
73
|
+
|
74
|
+
def update_lists(contact_id, options)
|
75
|
+
base_update(contact_id, options, %i[list_ids_included list_ids_excluded])
|
76
|
+
end
|
77
|
+
|
78
|
+
def wrap_request(options)
|
79
|
+
{ contact: options }
|
80
|
+
end
|
81
|
+
|
82
|
+
def handle_response(response)
|
83
|
+
response_class.new response[:data].slice(*response_class.members).merge(action: response[:action])
|
84
|
+
end
|
85
|
+
|
86
|
+
def base_path
|
87
|
+
"/api/accounts/#{account_id}/contacts"
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Mailtrap
|
4
|
+
# Data Transfer Object for Email Template
|
5
|
+
#
|
6
|
+
# For field descriptions and response format, see the official API documentation:
|
7
|
+
# @see https://api-docs.mailtrap.io/docs/mailtrap-api-docs/9e5914d89c481-email-template
|
8
|
+
#
|
9
|
+
# @attr_reader id [Integer] The template ID
|
10
|
+
# @attr_reader uuid [String] The template UUID
|
11
|
+
# @attr_reader name [String] The template name
|
12
|
+
# @attr_reader subject [String] The email subject
|
13
|
+
# @attr_reader category [String] The template category
|
14
|
+
# @attr_reader body_html [String] The HTML content
|
15
|
+
# @attr_reader body_text [String] The plain text content
|
16
|
+
# @attr_reader created_at [String] The creation timestamp
|
17
|
+
# @attr_reader updated_at [String] The last update timestamp
|
18
|
+
EmailTemplate = Struct.new(
|
19
|
+
:id,
|
20
|
+
:uuid,
|
21
|
+
:name,
|
22
|
+
:subject,
|
23
|
+
:category,
|
24
|
+
:body_html,
|
25
|
+
:body_text,
|
26
|
+
:created_at,
|
27
|
+
:updated_at,
|
28
|
+
keyword_init: true
|
29
|
+
) do
|
30
|
+
# @return [Hash] The template attributes as a hash
|
31
|
+
def to_h
|
32
|
+
super.compact
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|