mailinator_client 1.0.6 → 1.1.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/.agent/rules/tdd.md +7 -0
- data/.agent/tdd-flow/skill.md +15 -0
- data/.env.example +25 -0
- data/.github/copilot-instructions.md +7 -0
- data/.gitignore +2 -0
- data/.ruby-version +1 -1
- data/AGENTS.md +9 -0
- data/AI_INSTRUCTIONS.md +205 -0
- data/CHANGELOG.md +65 -0
- data/EXAMPLES.md +11 -0
- data/README.md +18 -13
- data/ROADMAP.md +58 -0
- data/docs/domains.md +6 -0
- data/docs/rules.md +9 -6
- data/lib/mailinator_client/authenticators.rb +0 -22
- data/lib/mailinator_client/client.rb +14 -24
- data/lib/mailinator_client/domains.rb +5 -25
- data/lib/mailinator_client/error.rb +11 -25
- data/lib/mailinator_client/messages.rb +464 -48
- data/lib/mailinator_client/rules.rb +12 -28
- data/lib/mailinator_client/stats.rb +0 -22
- data/lib/mailinator_client/utils.rb +0 -22
- data/lib/mailinator_client/version.rb +3 -25
- data/lib/mailinator_client/webhooks.rb +1 -22
- data/lib/mailinator_client.rb +0 -22
- data/mailinator_client.gemspec +25 -25
- data/test/authenticators_api_test.rb +28 -0
- data/test/domains_api_test.rb +15 -0
- data/test/messages_api_test.rb +274 -0
- data/test/messages_headers_api_test.rb +30 -0
- data/test/messages_query_params_test.rb +76 -0
- data/test/messages_stream_domain_api_test.rb +39 -0
- data/test/messages_stream_inbox_api_test.rb +40 -0
- data/test/messages_summary_api_test.rb +28 -0
- data/test/messages_text_api_test.rb +28 -0
- data/test/messages_texthtml_api_test.rb +28 -0
- data/test/messages_textplain_api_test.rb +28 -0
- data/test/rules_api_test.rb +7 -0
- data/test/stats_api_test.rb +19 -0
- data/test/test_helper.rb +31 -1
- data/test/webhooks_api_test.rb +49 -0
- metadata +84 -23
- data/test/mailinator_client_api_test.rb +0 -246
|
@@ -1,26 +1,6 @@
|
|
|
1
|
-
# The MIT License (MIT)
|
|
2
|
-
#
|
|
3
|
-
# Copyright (c) 2024 Manybrain, Inc.
|
|
4
|
-
#
|
|
5
|
-
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
-
# of this software and associated documentation files (the "Software"), to deal
|
|
7
|
-
# in the Software without restriction, including without limitation the rights
|
|
8
|
-
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
-
# copies of the Software, and to permit persons to whom the Software is
|
|
10
|
-
# furnished to do so, subject to the following conditions:
|
|
11
|
-
#
|
|
12
|
-
# The above copyright notice and this permission notice shall be included in all
|
|
13
|
-
# copies or substantial portions of the Software.
|
|
14
|
-
#
|
|
15
|
-
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
-
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
-
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
-
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
-
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
-
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
-
# SOFTWARE.
|
|
22
|
-
|
|
23
1
|
require "json"
|
|
2
|
+
require "net/http"
|
|
3
|
+
require "uri"
|
|
24
4
|
|
|
25
5
|
module MailinatorClient
|
|
26
6
|
|
|
@@ -38,7 +18,7 @@ module MailinatorClient
|
|
|
38
18
|
# access token to call this action.
|
|
39
19
|
#
|
|
40
20
|
# Parameters:
|
|
41
|
-
# * {string} domainId - The Domain name or
|
|
21
|
+
# * {string} domainId - The Domain name or simply 'private'
|
|
42
22
|
# * {string} inbox - The Inbox name
|
|
43
23
|
# * {number} skip - [Optional] Skip this many emails in your Private Domain
|
|
44
24
|
# * {number} limit - [Optional] Number of emails to fetch from your Private Domain
|
|
@@ -47,7 +27,6 @@ module MailinatorClient
|
|
|
47
27
|
# * {string} cursor - [Optional] Pagination cursor for large result sets (obtained from previous response)
|
|
48
28
|
# * {boolean} full - [Optional] Return full email content with body/attachments (true) or just metadata (false). Default: false
|
|
49
29
|
# * {string} delete - [Optional] Auto-delete message after retrieval (e.g., "10s" = 10 seconds, "5m" = 5 minutes)
|
|
50
|
-
# * {string} wait - [Optional] Maximum time to wait for new messages (e.g., "30s" = 30 seconds)
|
|
51
30
|
#
|
|
52
31
|
# Responses:
|
|
53
32
|
# * Collection of messages (https://manybrain.github.io/m8rdocs/#fetch-inbox-aka-fetch-message-summaries)
|
|
@@ -67,16 +46,17 @@ module MailinatorClient
|
|
|
67
46
|
query_params[:cursor] = params[:cursor] if params.has_key?(:cursor)
|
|
68
47
|
query_params[:full] = params[:full] if params.has_key?(:full)
|
|
69
48
|
query_params[:delete] = params[:delete] if params.has_key?(:delete)
|
|
70
|
-
query_params[:wait] = params[:wait] if params.has_key?(:wait)
|
|
71
49
|
|
|
72
50
|
path = "/domains/#{params[:domain]}/inboxes/#{params[:inbox]}"
|
|
73
51
|
|
|
74
|
-
@client.request(
|
|
52
|
+
response = @client.request(
|
|
75
53
|
method: :get,
|
|
76
54
|
path: path,
|
|
77
55
|
query: query_params,
|
|
78
56
|
headers: headers,
|
|
79
57
|
body: body)
|
|
58
|
+
|
|
59
|
+
response
|
|
80
60
|
end
|
|
81
61
|
|
|
82
62
|
# Retrieves a specific message by id for specific inbox.
|
|
@@ -86,9 +66,10 @@ module MailinatorClient
|
|
|
86
66
|
# access token to call this action.
|
|
87
67
|
#
|
|
88
68
|
# Parameters:
|
|
89
|
-
# * {string} domainId - The Domain name or
|
|
69
|
+
# * {string} domainId - The Domain name or simply 'private'
|
|
90
70
|
# * {string} inbox - The Inbox name
|
|
91
71
|
# * {string} messageId - The Message id
|
|
72
|
+
# * {string} delete - [Optional] Auto-delete message after retrieval (e.g., "10s" = 10 seconds, "5m" = 5 minutes)
|
|
92
73
|
#
|
|
93
74
|
# Responses:
|
|
94
75
|
# * Message (https://manybrain.github.io/m8rdocs/#fetch-inbox-message)
|
|
@@ -102,6 +83,8 @@ module MailinatorClient
|
|
|
102
83
|
raise ArgumentError.new("inbox is required") unless params.has_key?(:inbox)
|
|
103
84
|
raise ArgumentError.new("message id is required") unless params.has_key?(:messageId)
|
|
104
85
|
|
|
86
|
+
query_params[:delete] = params[:delete] if params.has_key?(:delete)
|
|
87
|
+
|
|
105
88
|
path = "/domains/#{params[:domain]}/inboxes/#{params[:inbox]}/messages/#{params[:messageId]}"
|
|
106
89
|
|
|
107
90
|
@client.request(
|
|
@@ -119,12 +102,12 @@ module MailinatorClient
|
|
|
119
102
|
# access token to call this action.
|
|
120
103
|
#
|
|
121
104
|
# Parameters:
|
|
122
|
-
# * {string} domainId - The Domain name or
|
|
105
|
+
# * {string} domainId - The Domain name or simply 'private'
|
|
123
106
|
# * {string} messageId - The Message id
|
|
124
107
|
# * {string} delete - [Optional] Auto-delete message after retrieval (e.g., "10s" = 10 seconds, "5m" = 5 minutes)
|
|
125
108
|
#
|
|
126
109
|
# Responses:
|
|
127
|
-
# * Message (https://
|
|
110
|
+
# * Message (https://www.mailinator.com/documentation/docs/api/get-domain-message/index.html)
|
|
128
111
|
def fetch_message(params = {})
|
|
129
112
|
params = Utils.symbolize_hash_keys(params)
|
|
130
113
|
query_params = { }
|
|
@@ -146,6 +129,421 @@ module MailinatorClient
|
|
|
146
129
|
body: body)
|
|
147
130
|
end
|
|
148
131
|
|
|
132
|
+
# Retrieves the summary for a specific message by id.
|
|
133
|
+
#
|
|
134
|
+
# Authentication:
|
|
135
|
+
# The client must be configured with a valid api
|
|
136
|
+
# access token to call this action.
|
|
137
|
+
#
|
|
138
|
+
# Parameters:
|
|
139
|
+
# * {string} domainId - The Domain name or simply 'private'
|
|
140
|
+
# * {string} messageId - The Message id
|
|
141
|
+
#
|
|
142
|
+
# Responses:
|
|
143
|
+
# * Message summary
|
|
144
|
+
def fetch_message_summary(params = {})
|
|
145
|
+
params = Utils.symbolize_hash_keys(params)
|
|
146
|
+
query_params = { }
|
|
147
|
+
headers = {}
|
|
148
|
+
body = nil
|
|
149
|
+
|
|
150
|
+
raise ArgumentError.new("domain is required") unless params.has_key?(:domain)
|
|
151
|
+
raise ArgumentError.new("message id is required") unless params.has_key?(:messageId)
|
|
152
|
+
|
|
153
|
+
path = "/domains/#{params[:domain]}/messages/#{params[:messageId]}/summary"
|
|
154
|
+
|
|
155
|
+
@client.request(
|
|
156
|
+
method: :get,
|
|
157
|
+
path: path,
|
|
158
|
+
query: query_params,
|
|
159
|
+
headers: headers,
|
|
160
|
+
body: body)
|
|
161
|
+
end
|
|
162
|
+
|
|
163
|
+
# Retrieves text content for a specific message by id.
|
|
164
|
+
#
|
|
165
|
+
# Authentication:
|
|
166
|
+
# The client must be configured with a valid api
|
|
167
|
+
# access token to call this action.
|
|
168
|
+
#
|
|
169
|
+
# Parameters:
|
|
170
|
+
# * {string} domainId - The Domain name or simply 'private'
|
|
171
|
+
# * {string} messageId - The Message id
|
|
172
|
+
#
|
|
173
|
+
# Responses:
|
|
174
|
+
# * Message text response
|
|
175
|
+
def fetch_message_text(params = {})
|
|
176
|
+
params = Utils.symbolize_hash_keys(params)
|
|
177
|
+
query_params = { }
|
|
178
|
+
headers = {}
|
|
179
|
+
body = nil
|
|
180
|
+
|
|
181
|
+
raise ArgumentError.new("domain is required") unless params.has_key?(:domain)
|
|
182
|
+
raise ArgumentError.new("message id is required") unless params.has_key?(:messageId)
|
|
183
|
+
|
|
184
|
+
path = "/domains/#{params[:domain]}/messages/#{params[:messageId]}/text"
|
|
185
|
+
|
|
186
|
+
@client.request(
|
|
187
|
+
method: :get,
|
|
188
|
+
path: path,
|
|
189
|
+
query: query_params,
|
|
190
|
+
headers: headers,
|
|
191
|
+
body: body)
|
|
192
|
+
end
|
|
193
|
+
|
|
194
|
+
# Retrieves text/plain content for a specific message by id.
|
|
195
|
+
#
|
|
196
|
+
# Authentication:
|
|
197
|
+
# The client must be configured with a valid api
|
|
198
|
+
# access token to call this action.
|
|
199
|
+
#
|
|
200
|
+
# Parameters:
|
|
201
|
+
# * {string} domainId - The Domain name or simply 'private'
|
|
202
|
+
# * {string} messageId - The Message id
|
|
203
|
+
#
|
|
204
|
+
# Responses:
|
|
205
|
+
# * Message text/plain response
|
|
206
|
+
def fetch_message_textplain(params = {})
|
|
207
|
+
params = Utils.symbolize_hash_keys(params)
|
|
208
|
+
query_params = { }
|
|
209
|
+
headers = {}
|
|
210
|
+
body = nil
|
|
211
|
+
|
|
212
|
+
raise ArgumentError.new("domain is required") unless params.has_key?(:domain)
|
|
213
|
+
raise ArgumentError.new("message id is required") unless params.has_key?(:messageId)
|
|
214
|
+
|
|
215
|
+
path = "/domains/#{params[:domain]}/messages/#{params[:messageId]}/textplain"
|
|
216
|
+
|
|
217
|
+
@client.request(
|
|
218
|
+
method: :get,
|
|
219
|
+
path: path,
|
|
220
|
+
query: query_params,
|
|
221
|
+
headers: headers,
|
|
222
|
+
body: body)
|
|
223
|
+
end
|
|
224
|
+
|
|
225
|
+
# Retrieves text/html content for a specific message by id.
|
|
226
|
+
#
|
|
227
|
+
# Authentication:
|
|
228
|
+
# The client must be configured with a valid api
|
|
229
|
+
# access token to call this action.
|
|
230
|
+
#
|
|
231
|
+
# Parameters:
|
|
232
|
+
# * {string} domainId - The Domain name or simply 'private'
|
|
233
|
+
# * {string} messageId - The Message id
|
|
234
|
+
#
|
|
235
|
+
# Responses:
|
|
236
|
+
# * Message text/html response
|
|
237
|
+
def fetch_message_texthtml(params = {})
|
|
238
|
+
params = Utils.symbolize_hash_keys(params)
|
|
239
|
+
query_params = { }
|
|
240
|
+
headers = {}
|
|
241
|
+
body = nil
|
|
242
|
+
|
|
243
|
+
raise ArgumentError.new("domain is required") unless params.has_key?(:domain)
|
|
244
|
+
raise ArgumentError.new("message id is required") unless params.has_key?(:messageId)
|
|
245
|
+
|
|
246
|
+
path = "/domains/#{params[:domain]}/messages/#{params[:messageId]}/texthtml"
|
|
247
|
+
|
|
248
|
+
@client.request(
|
|
249
|
+
method: :get,
|
|
250
|
+
path: path,
|
|
251
|
+
query: query_params,
|
|
252
|
+
headers: headers,
|
|
253
|
+
body: body)
|
|
254
|
+
end
|
|
255
|
+
|
|
256
|
+
# Retrieves headers for a specific message by id.
|
|
257
|
+
#
|
|
258
|
+
# Authentication:
|
|
259
|
+
# The client must be configured with a valid api
|
|
260
|
+
# access token to call this action.
|
|
261
|
+
#
|
|
262
|
+
# Parameters:
|
|
263
|
+
# * {string} domainId - The Domain name or simply 'private'
|
|
264
|
+
# * {string} messageId - The Message id
|
|
265
|
+
#
|
|
266
|
+
# Responses:
|
|
267
|
+
# * Message headers response
|
|
268
|
+
def fetch_message_headers(params = {})
|
|
269
|
+
params = Utils.symbolize_hash_keys(params)
|
|
270
|
+
query_params = { }
|
|
271
|
+
headers = {}
|
|
272
|
+
body = nil
|
|
273
|
+
|
|
274
|
+
raise ArgumentError.new("domain is required") unless params.has_key?(:domain)
|
|
275
|
+
raise ArgumentError.new("message id is required") unless params.has_key?(:messageId)
|
|
276
|
+
|
|
277
|
+
path = "/domains/#{params[:domain]}/messages/#{params[:messageId]}/headers"
|
|
278
|
+
|
|
279
|
+
@client.request(
|
|
280
|
+
method: :get,
|
|
281
|
+
path: path,
|
|
282
|
+
query: query_params,
|
|
283
|
+
headers: headers,
|
|
284
|
+
body: body)
|
|
285
|
+
end
|
|
286
|
+
|
|
287
|
+
# Streams all messages from a domain.
|
|
288
|
+
#
|
|
289
|
+
# Authentication:
|
|
290
|
+
# The client must be configured with a valid api
|
|
291
|
+
# access token to call this action.
|
|
292
|
+
#
|
|
293
|
+
# Parameters:
|
|
294
|
+
# * {string} domainId - The Domain name or simply 'private'
|
|
295
|
+
# * {boolean} full - [Optional] Return full email content with body/attachments (true) or just metadata (false). Default: false
|
|
296
|
+
# * {number} limit - [Optional] Number of messages to fetch
|
|
297
|
+
# * {number} throttleInterval - [Optional] Throttle interval in milliseconds
|
|
298
|
+
# * {string} delete - [Optional] Auto-delete message after retrieval (e.g., "10s" = 10 seconds, "5m" = 5 minutes)
|
|
299
|
+
#
|
|
300
|
+
# Responses:
|
|
301
|
+
# * Message stream response
|
|
302
|
+
def stream_domain_messages(params = {})
|
|
303
|
+
params = Utils.symbolize_hash_keys(params)
|
|
304
|
+
query_params = { }
|
|
305
|
+
headers = {}
|
|
306
|
+
body = nil
|
|
307
|
+
|
|
308
|
+
raise ArgumentError.new("domain is required") unless params.has_key?(:domain)
|
|
309
|
+
|
|
310
|
+
query_params[:full] = params[:full] if params.has_key?(:full)
|
|
311
|
+
query_params[:limit] = params[:limit] if params.has_key?(:limit)
|
|
312
|
+
query_params[:throttleInterval] = params[:throttleInterval] if params.has_key?(:throttleInterval)
|
|
313
|
+
query_params[:delete] = params[:delete] if params.has_key?(:delete)
|
|
314
|
+
|
|
315
|
+
path = "/domains/#{params[:domain]}/stream"
|
|
316
|
+
|
|
317
|
+
uri = URI.parse(@client.url + path)
|
|
318
|
+
query = Utils.fix_query_arrays(query_params)
|
|
319
|
+
uri.query = URI.encode_www_form(query) unless query.nil? || query.empty?
|
|
320
|
+
|
|
321
|
+
headers["Accept"] = "application/json"
|
|
322
|
+
headers["Content-Type"] = "application/json"
|
|
323
|
+
headers["User-Agent"] = "Mailinator SDK - Ruby V#{MailinatorClient::VERSION}"
|
|
324
|
+
headers["Authorization"] = @client.auth_token if @client.auth_token
|
|
325
|
+
|
|
326
|
+
response_body = +""
|
|
327
|
+
http = Net::HTTP.new(uri.host, uri.port)
|
|
328
|
+
http.use_ssl = uri.scheme == "https"
|
|
329
|
+
http.read_timeout = 20
|
|
330
|
+
|
|
331
|
+
request = Net::HTTP::Get.new(uri)
|
|
332
|
+
headers.each { |key, value| request[key] = value }
|
|
333
|
+
|
|
334
|
+
http.request(request) do |response|
|
|
335
|
+
if response.code.to_i >= 400
|
|
336
|
+
raise ResponseError.new(response.code.to_i, nil, response.body)
|
|
337
|
+
end
|
|
338
|
+
|
|
339
|
+
catch(:done) do
|
|
340
|
+
response.read_body do |chunk|
|
|
341
|
+
response_body << chunk
|
|
342
|
+
if response_body.include?("\n\n") || response_body.include?("}\n") || response_body.strip.end_with?("}")
|
|
343
|
+
throw :done
|
|
344
|
+
end
|
|
345
|
+
end
|
|
346
|
+
end
|
|
347
|
+
end
|
|
348
|
+
|
|
349
|
+
payload = response_body.strip
|
|
350
|
+
if payload.start_with?("data:")
|
|
351
|
+
payload_line = payload.lines.find { |line| line.start_with?("data:") }
|
|
352
|
+
payload = payload_line.to_s.sub(/^data:\\s*/, "").strip
|
|
353
|
+
end
|
|
354
|
+
|
|
355
|
+
parsed = begin
|
|
356
|
+
JSON.parse(payload)
|
|
357
|
+
rescue JSON::ParserError
|
|
358
|
+
cleaned = payload.encode("UTF-8", invalid: :replace, undef: :replace, replace: "")
|
|
359
|
+
candidate = cleaned
|
|
360
|
+
if candidate.include?("data:")
|
|
361
|
+
data_line = candidate.lines.find { |line| line.start_with?("data:") }
|
|
362
|
+
candidate = data_line.to_s.sub(/^data:\s*/, "")
|
|
363
|
+
end
|
|
364
|
+
|
|
365
|
+
in_string = false
|
|
366
|
+
escape = false
|
|
367
|
+
depth = 0
|
|
368
|
+
start_idx = nil
|
|
369
|
+
end_idx = nil
|
|
370
|
+
|
|
371
|
+
candidate.each_char.with_index do |ch, idx|
|
|
372
|
+
if start_idx.nil?
|
|
373
|
+
if ch == "{"
|
|
374
|
+
start_idx = idx
|
|
375
|
+
depth = 1
|
|
376
|
+
end
|
|
377
|
+
next
|
|
378
|
+
end
|
|
379
|
+
|
|
380
|
+
if in_string
|
|
381
|
+
if escape
|
|
382
|
+
escape = false
|
|
383
|
+
elsif ch == "\\"
|
|
384
|
+
escape = true
|
|
385
|
+
elsif ch == "\""
|
|
386
|
+
in_string = false
|
|
387
|
+
end
|
|
388
|
+
else
|
|
389
|
+
case ch
|
|
390
|
+
when "\""
|
|
391
|
+
in_string = true
|
|
392
|
+
when "{"
|
|
393
|
+
depth += 1
|
|
394
|
+
when "}"
|
|
395
|
+
depth -= 1
|
|
396
|
+
if depth == 0
|
|
397
|
+
end_idx = idx
|
|
398
|
+
break
|
|
399
|
+
end
|
|
400
|
+
end
|
|
401
|
+
end
|
|
402
|
+
end
|
|
403
|
+
|
|
404
|
+
if start_idx && end_idx && end_idx >= start_idx
|
|
405
|
+
JSON.parse(candidate[start_idx..end_idx])
|
|
406
|
+
end
|
|
407
|
+
end
|
|
408
|
+
|
|
409
|
+
raise ResponseError.new(500, nil, payload) if parsed.nil?
|
|
410
|
+
|
|
411
|
+
return parsed if parsed.is_a?(Hash) && parsed.key?("domain") && parsed.key?("msgs")
|
|
412
|
+
return { "domain" => parsed["domain"], "to" => parsed["to"], "msgs" => [parsed] } if parsed.is_a?(Hash)
|
|
413
|
+
parsed
|
|
414
|
+
end
|
|
415
|
+
|
|
416
|
+
# Streams all messages from an inbox.
|
|
417
|
+
#
|
|
418
|
+
# Authentication:
|
|
419
|
+
# The client must be configured with a valid api
|
|
420
|
+
# access token to call this action.
|
|
421
|
+
#
|
|
422
|
+
# Parameters:
|
|
423
|
+
# * {string} domainId - The Domain name or simply 'private'
|
|
424
|
+
# * {string} inbox - The Inbox name
|
|
425
|
+
# * {boolean} full - [Optional] Return full email content with body/attachments (true) or just metadata (false). Default: false
|
|
426
|
+
# * {number} limit - [Optional] Number of messages to fetch
|
|
427
|
+
# * {number} throttleInterval - [Optional] Throttle interval in milliseconds
|
|
428
|
+
# * {string} delete - [Optional] Auto-delete message after retrieval (e.g., "10s" = 10 seconds, "5m" = 5 minutes)
|
|
429
|
+
#
|
|
430
|
+
# Responses:
|
|
431
|
+
# * Message stream response
|
|
432
|
+
def stream_inbox_messages(params = {})
|
|
433
|
+
params = Utils.symbolize_hash_keys(params)
|
|
434
|
+
query_params = { }
|
|
435
|
+
headers = {}
|
|
436
|
+
body = nil
|
|
437
|
+
|
|
438
|
+
raise ArgumentError.new("domain is required") unless params.has_key?(:domain)
|
|
439
|
+
raise ArgumentError.new("inbox is required") unless params.has_key?(:inbox)
|
|
440
|
+
|
|
441
|
+
query_params[:full] = params[:full] if params.has_key?(:full)
|
|
442
|
+
query_params[:limit] = params[:limit] if params.has_key?(:limit)
|
|
443
|
+
query_params[:throttleInterval] = params[:throttleInterval] if params.has_key?(:throttleInterval)
|
|
444
|
+
query_params[:delete] = params[:delete] if params.has_key?(:delete)
|
|
445
|
+
|
|
446
|
+
path = "/domains/#{params[:domain]}/stream/#{params[:inbox]}"
|
|
447
|
+
|
|
448
|
+
uri = URI.parse(@client.url + path)
|
|
449
|
+
query = Utils.fix_query_arrays(query_params)
|
|
450
|
+
uri.query = URI.encode_www_form(query) unless query.nil? || query.empty?
|
|
451
|
+
|
|
452
|
+
headers["Accept"] = "application/json"
|
|
453
|
+
headers["Content-Type"] = "application/json"
|
|
454
|
+
headers["User-Agent"] = "Mailinator SDK - Ruby V#{MailinatorClient::VERSION}"
|
|
455
|
+
headers["Authorization"] = @client.auth_token if @client.auth_token
|
|
456
|
+
|
|
457
|
+
response_body = +""
|
|
458
|
+
http = Net::HTTP.new(uri.host, uri.port)
|
|
459
|
+
http.use_ssl = uri.scheme == "https"
|
|
460
|
+
http.read_timeout = 20
|
|
461
|
+
|
|
462
|
+
request = Net::HTTP::Get.new(uri)
|
|
463
|
+
headers.each { |key, value| request[key] = value }
|
|
464
|
+
|
|
465
|
+
http.request(request) do |response|
|
|
466
|
+
if response.code.to_i >= 400
|
|
467
|
+
raise ResponseError.new(response.code.to_i, nil, response.body)
|
|
468
|
+
end
|
|
469
|
+
|
|
470
|
+
catch(:done) do
|
|
471
|
+
response.read_body do |chunk|
|
|
472
|
+
response_body << chunk
|
|
473
|
+
if response_body.include?("\n\n") || response_body.include?("}\n") || response_body.strip.end_with?("}")
|
|
474
|
+
throw :done
|
|
475
|
+
end
|
|
476
|
+
end
|
|
477
|
+
end
|
|
478
|
+
end
|
|
479
|
+
|
|
480
|
+
payload = response_body.strip
|
|
481
|
+
if payload.start_with?("data:")
|
|
482
|
+
payload_line = payload.lines.find { |line| line.start_with?("data:") }
|
|
483
|
+
payload = payload_line.to_s.sub(/^data:\\s*/, "").strip
|
|
484
|
+
end
|
|
485
|
+
|
|
486
|
+
parsed = begin
|
|
487
|
+
JSON.parse(payload)
|
|
488
|
+
rescue JSON::ParserError
|
|
489
|
+
cleaned = payload.encode("UTF-8", invalid: :replace, undef: :replace, replace: "")
|
|
490
|
+
candidate = cleaned
|
|
491
|
+
if candidate.include?("data:")
|
|
492
|
+
data_line = candidate.lines.find { |line| line.start_with?("data:") }
|
|
493
|
+
candidate = data_line.to_s.sub(/^data:\s*/, "")
|
|
494
|
+
end
|
|
495
|
+
|
|
496
|
+
in_string = false
|
|
497
|
+
escape = false
|
|
498
|
+
depth = 0
|
|
499
|
+
start_idx = nil
|
|
500
|
+
end_idx = nil
|
|
501
|
+
|
|
502
|
+
candidate.each_char.with_index do |ch, idx|
|
|
503
|
+
if start_idx.nil?
|
|
504
|
+
if ch == "{"
|
|
505
|
+
start_idx = idx
|
|
506
|
+
depth = 1
|
|
507
|
+
end
|
|
508
|
+
next
|
|
509
|
+
end
|
|
510
|
+
|
|
511
|
+
if in_string
|
|
512
|
+
if escape
|
|
513
|
+
escape = false
|
|
514
|
+
elsif ch == "\\"
|
|
515
|
+
escape = true
|
|
516
|
+
elsif ch == "\""
|
|
517
|
+
in_string = false
|
|
518
|
+
end
|
|
519
|
+
else
|
|
520
|
+
case ch
|
|
521
|
+
when "\""
|
|
522
|
+
in_string = true
|
|
523
|
+
when "{"
|
|
524
|
+
depth += 1
|
|
525
|
+
when "}"
|
|
526
|
+
depth -= 1
|
|
527
|
+
if depth == 0
|
|
528
|
+
end_idx = idx
|
|
529
|
+
break
|
|
530
|
+
end
|
|
531
|
+
end
|
|
532
|
+
end
|
|
533
|
+
end
|
|
534
|
+
|
|
535
|
+
if start_idx && end_idx && end_idx >= start_idx
|
|
536
|
+
JSON.parse(candidate[start_idx..end_idx])
|
|
537
|
+
end
|
|
538
|
+
end
|
|
539
|
+
|
|
540
|
+
raise ResponseError.new(500, nil, payload) if parsed.nil?
|
|
541
|
+
|
|
542
|
+
return parsed if parsed.is_a?(Hash) && parsed.key?("domain") && parsed.key?("msgs")
|
|
543
|
+
return { "domain" => parsed["domain"], "to" => parsed["to"], "msgs" => [parsed] } if parsed.is_a?(Hash)
|
|
544
|
+
parsed
|
|
545
|
+
end
|
|
546
|
+
|
|
149
547
|
# Retrieves a specific SMS message by sms number.
|
|
150
548
|
#
|
|
151
549
|
# Authentication:
|
|
@@ -153,20 +551,38 @@ module MailinatorClient
|
|
|
153
551
|
# access token to call this action.
|
|
154
552
|
#
|
|
155
553
|
# Parameters:
|
|
156
|
-
# * {string} domainId - The Domain name or
|
|
554
|
+
# * {string} domainId - The Domain name or simply 'private'
|
|
157
555
|
# * {string} teamSmsNumber - The Team sms number
|
|
556
|
+
# * {number} skip - [Optional] Skip this many emails in your Private Domain
|
|
557
|
+
# * {number} limit - [Optional] Number of emails to fetch from your Private Domain
|
|
558
|
+
# * {string} sort - [Optional] Sort results by ascending or descending
|
|
559
|
+
# * {boolean} decode_subject - [Optional] true: decode encoded subjects
|
|
560
|
+
# * {string} cursor - [Optional] Pagination cursor for large result sets (obtained from previous response)
|
|
561
|
+
# * {boolean} full - [Optional] Return full email content with body/attachments (true) or just metadata (false). Default: false
|
|
562
|
+
# * {string} delete - [Optional] Auto-delete message after retrieval (e.g., "10s" = 10 seconds, "5m" = 5 minutes)
|
|
563
|
+
# * {string} wait - [Optional] Maximum time to wait for new messages (e.g., "30s" = 30 seconds)
|
|
158
564
|
#
|
|
159
565
|
# Responses:
|
|
160
566
|
# * Collection of messages (https://manybrain.github.io/m8rdocs/#fetch-an-sms-messages)
|
|
161
567
|
def fetch_sms_message(params = {})
|
|
162
568
|
params = Utils.symbolize_hash_keys(params)
|
|
163
|
-
query_params = { }
|
|
569
|
+
query_params = { skip: 0, limit: 50, sort: "ascending", decode_subject: false }
|
|
164
570
|
headers = {}
|
|
165
571
|
body = nil
|
|
166
572
|
|
|
167
573
|
raise ArgumentError.new("domain is required") unless params.has_key?(:domain)
|
|
168
574
|
raise ArgumentError.new("team sms number is required") unless params.has_key?(:teamSmsNumber)
|
|
169
575
|
|
|
576
|
+
query_params[:skip] = params[:skip] if params.has_key?(:skip)
|
|
577
|
+
query_params[:limit] = params[:limit] if params.has_key?(:limit)
|
|
578
|
+
query_params[:sort] = params[:sort] if params.has_key?(:sort)
|
|
579
|
+
query_params[:decode_subject] = params[:decode_subject] if params.has_key?(:decode_subject)
|
|
580
|
+
query_params[:decode_subject] = params[:decodeSubject] if params.has_key?(:decodeSubject)
|
|
581
|
+
query_params[:cursor] = params[:cursor] if params.has_key?(:cursor)
|
|
582
|
+
query_params[:full] = params[:full] if params.has_key?(:full)
|
|
583
|
+
query_params[:delete] = params[:delete] if params.has_key?(:delete)
|
|
584
|
+
query_params[:wait] = params[:wait] if params.has_key?(:wait)
|
|
585
|
+
|
|
170
586
|
path = "/domains/#{params[:domain]}/inboxes/#{params[:teamSmsNumber]}"
|
|
171
587
|
|
|
172
588
|
@client.request(
|
|
@@ -184,7 +600,7 @@ module MailinatorClient
|
|
|
184
600
|
# access token to call this action.
|
|
185
601
|
#
|
|
186
602
|
# Parameters:
|
|
187
|
-
# * {string} domainId - The Domain name or
|
|
603
|
+
# * {string} domainId - The Domain name or simply 'private'
|
|
188
604
|
# * {string} inbox - The Inbox name
|
|
189
605
|
# * {string} messageId - The Message id
|
|
190
606
|
#
|
|
@@ -217,7 +633,7 @@ module MailinatorClient
|
|
|
217
633
|
# access token to call this action.
|
|
218
634
|
#
|
|
219
635
|
# Parameters:
|
|
220
|
-
# * {string} domainId - The Domain name or
|
|
636
|
+
# * {string} domainId - The Domain name or simply 'private'
|
|
221
637
|
# * {string} messageId - The Message id
|
|
222
638
|
#
|
|
223
639
|
# Responses:
|
|
@@ -248,7 +664,7 @@ module MailinatorClient
|
|
|
248
664
|
# access token to call this action.
|
|
249
665
|
#
|
|
250
666
|
# Parameters:
|
|
251
|
-
# * {string} domainId - The Domain name or
|
|
667
|
+
# * {string} domainId - The Domain name or simply 'private'
|
|
252
668
|
# * {string} inbox - The Inbox name
|
|
253
669
|
# * {string} messageId - The Message id
|
|
254
670
|
# * {string} attachmentId - The Attachment id
|
|
@@ -283,7 +699,7 @@ module MailinatorClient
|
|
|
283
699
|
# access token to call this action.
|
|
284
700
|
#
|
|
285
701
|
# Parameters:
|
|
286
|
-
# * {string} domainId - The Domain name or
|
|
702
|
+
# * {string} domainId - The Domain name or simply 'private'
|
|
287
703
|
# * {string} messageId - The Message id
|
|
288
704
|
# * {string} attachmentId - The Attachment id
|
|
289
705
|
#
|
|
@@ -316,7 +732,7 @@ module MailinatorClient
|
|
|
316
732
|
# access token to call this action.
|
|
317
733
|
#
|
|
318
734
|
# Parameters:
|
|
319
|
-
# * {string} domainId - The Domain name or
|
|
735
|
+
# * {string} domainId - The Domain name or simply 'private'
|
|
320
736
|
# * {string} messageId - The Message id
|
|
321
737
|
#
|
|
322
738
|
# Responses:
|
|
@@ -347,7 +763,7 @@ module MailinatorClient
|
|
|
347
763
|
# access token to call this action.
|
|
348
764
|
#
|
|
349
765
|
# Parameters:
|
|
350
|
-
# * {string} domainId - The Domain name or
|
|
766
|
+
# * {string} domainId - The Domain name or simply 'private'
|
|
351
767
|
# * {string} messageId - The Message id
|
|
352
768
|
#
|
|
353
769
|
# Responses:
|
|
@@ -378,7 +794,7 @@ module MailinatorClient
|
|
|
378
794
|
# access token to call this action.
|
|
379
795
|
#
|
|
380
796
|
# Parameters:
|
|
381
|
-
# * {string} domainId - The Domain name or
|
|
797
|
+
# * {string} domainId - The Domain name or simply 'private'
|
|
382
798
|
# * {string} inbox - The Inbox name
|
|
383
799
|
# * {string} messageId - The Message id
|
|
384
800
|
#
|
|
@@ -411,7 +827,7 @@ module MailinatorClient
|
|
|
411
827
|
# access token to call this action.
|
|
412
828
|
#
|
|
413
829
|
# Parameters:
|
|
414
|
-
# * {string} domainId - The Domain name or
|
|
830
|
+
# * {string} domainId - The Domain name or simply 'private'
|
|
415
831
|
#
|
|
416
832
|
# Responses:
|
|
417
833
|
# * Status and count of removed messages (https://manybrain.github.io/m8rdocs/#delete-all-messages-by-domain)
|
|
@@ -440,7 +856,7 @@ module MailinatorClient
|
|
|
440
856
|
# access token to call this action.
|
|
441
857
|
#
|
|
442
858
|
# Parameters:
|
|
443
|
-
# * {string} domainId - The Domain name or
|
|
859
|
+
# * {string} domainId - The Domain name or simply 'private'
|
|
444
860
|
# * {string} inbox - The Inbox name
|
|
445
861
|
#
|
|
446
862
|
# Responses:
|
|
@@ -471,7 +887,7 @@ module MailinatorClient
|
|
|
471
887
|
# access token to call this action.
|
|
472
888
|
#
|
|
473
889
|
# Parameters:
|
|
474
|
-
# * {string} domainId - The Domain name or
|
|
890
|
+
# * {string} domainId - The Domain name or simply 'private'
|
|
475
891
|
# * {string} inbox - The Inbox name
|
|
476
892
|
# * {string} messageId - The Message id
|
|
477
893
|
#
|
|
@@ -504,7 +920,7 @@ module MailinatorClient
|
|
|
504
920
|
# access token to call this action.
|
|
505
921
|
#
|
|
506
922
|
# Parameters:
|
|
507
|
-
# * {string} domainId - The Domain name or
|
|
923
|
+
# * {string} domainId - The Domain name or simply 'private'
|
|
508
924
|
# * {string} inbox - The Inbox name
|
|
509
925
|
# * {string} messageToPost - The Message object (https://manybrain.github.io/m8rdocs/#inject-a-message-http-post-messages)
|
|
510
926
|
#
|
|
@@ -539,7 +955,7 @@ module MailinatorClient
|
|
|
539
955
|
# access token to call this action.
|
|
540
956
|
#
|
|
541
957
|
# Parameters:
|
|
542
|
-
# * {string} domainId - The Domain name or
|
|
958
|
+
# * {string} domainId - The Domain name or simply 'private'
|
|
543
959
|
# * {string} messageId - The Message id
|
|
544
960
|
#
|
|
545
961
|
# Responses:
|
|
@@ -570,7 +986,7 @@ module MailinatorClient
|
|
|
570
986
|
# access token to call this action.
|
|
571
987
|
#
|
|
572
988
|
# Parameters:
|
|
573
|
-
# * {string} domainId - The Domain name or
|
|
989
|
+
# * {string} domainId - The Domain name or simply 'private'
|
|
574
990
|
# * {string} inbox - The Inbox name
|
|
575
991
|
# * {string} messageId - The Message id
|
|
576
992
|
#
|
|
@@ -603,7 +1019,7 @@ module MailinatorClient
|
|
|
603
1019
|
# access token to call this action.
|
|
604
1020
|
#
|
|
605
1021
|
# Parameters:
|
|
606
|
-
# * {string} domainId - The Domain name or
|
|
1022
|
+
# * {string} domainId - The Domain name or simply 'private'
|
|
607
1023
|
# * {string} messageId - The Message id
|
|
608
1024
|
#
|
|
609
1025
|
# Responses:
|
|
@@ -634,7 +1050,7 @@ module MailinatorClient
|
|
|
634
1050
|
# access token to call this action.
|
|
635
1051
|
#
|
|
636
1052
|
# Parameters:
|
|
637
|
-
# * {string} domainId - The Domain name or
|
|
1053
|
+
# * {string} domainId - The Domain name or simply 'private'
|
|
638
1054
|
# * {string} inbox - The Inbox name
|
|
639
1055
|
# * {string} messageId - The Message id
|
|
640
1056
|
#
|
|
@@ -667,7 +1083,7 @@ module MailinatorClient
|
|
|
667
1083
|
# access token to call this action.
|
|
668
1084
|
#
|
|
669
1085
|
# Parameters:
|
|
670
|
-
# * {string} domainId - The Domain name or
|
|
1086
|
+
# * {string} domainId - The Domain name or simply 'private'
|
|
671
1087
|
#
|
|
672
1088
|
# Responses:
|
|
673
1089
|
# * Collection of latest messages (https://manybrain.github.io/m8rdocs/#fetch-latest-messages)
|
|
@@ -696,7 +1112,7 @@ module MailinatorClient
|
|
|
696
1112
|
# access token to call this action.
|
|
697
1113
|
#
|
|
698
1114
|
# Parameters:
|
|
699
|
-
# * {string} domainId - The Domain name or
|
|
1115
|
+
# * {string} domainId - The Domain name or simply 'private'
|
|
700
1116
|
# * {string} inbox - The Inbox name
|
|
701
1117
|
#
|
|
702
1118
|
# Responses:
|