haskimail 1.0.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 +7 -0
- data/CHANGELOG.md +51 -0
- data/LICENSE +21 -0
- data/README.md +414 -0
- data/SECURITY.md +64 -0
- data/lib/haskimail/api_object.rb +294 -0
- data/lib/haskimail/attachment.rb +171 -0
- data/lib/haskimail/base_client.rb +199 -0
- data/lib/haskimail/clients.rb +146 -0
- data/lib/haskimail/configuration.rb +246 -0
- data/lib/haskimail/errors.rb +246 -0
- data/lib/haskimail/http/net_http_transport.rb +288 -0
- data/lib/haskimail/http/response_parser.rb +104 -0
- data/lib/haskimail/http/retry_policy.rb +92 -0
- data/lib/haskimail/redacted.rb +31 -0
- data/lib/haskimail/resources/account_resources.rb +157 -0
- data/lib/haskimail/resources/base.rb +193 -0
- data/lib/haskimail/resources/emails.rb +352 -0
- data/lib/haskimail/resources/messages.rb +178 -0
- data/lib/haskimail/resources/server_resources.rb +297 -0
- data/lib/haskimail/resources/templates.rb +107 -0
- data/lib/haskimail/test_addresses.rb +25 -0
- data/lib/haskimail/util.rb +250 -0
- data/lib/haskimail/version.rb +6 -0
- data/lib/haskimail/webhook.rb +395 -0
- data/lib/haskimail.rb +34 -0
- data/sig/haskimail/internal.rbs +247 -0
- data/sig/haskimail.rbs +619 -0
- metadata +78 -0
data/sig/haskimail.rbs
ADDED
|
@@ -0,0 +1,619 @@
|
|
|
1
|
+
module Haskimail
|
|
2
|
+
VERSION: String
|
|
3
|
+
TEST_TOKEN: String
|
|
4
|
+
|
|
5
|
+
type json = Hash[String, untyped] | Array[untyped] | String | Integer | Float | bool | nil
|
|
6
|
+
type params = Hash[Symbol | String, untyped]
|
|
7
|
+
type id = Integer | String
|
|
8
|
+
|
|
9
|
+
def self.configuration: () -> Configuration
|
|
10
|
+
def self.configure: () { (Configuration) -> void } -> void
|
|
11
|
+
def self.reset_configuration!: () -> Configuration
|
|
12
|
+
def self.parse_time: (untyped value) -> Time?
|
|
13
|
+
|
|
14
|
+
class Error < StandardError
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
class ConfigurationError < Error
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
class ValidationError < Error
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
class SignatureVerificationError < Error
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
class WebhookPayloadTooLargeError < ValidationError
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
class ConnectionError < Error
|
|
30
|
+
attr_reader original_error: Exception?
|
|
31
|
+
def initialize: (?String? message, ?original_error: Exception?, ?request_sent: bool) -> void
|
|
32
|
+
def request_sent?: () -> bool
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
class TimeoutError < ConnectionError
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
class TlsError < ConnectionError
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
class ApiError < Error
|
|
42
|
+
attr_reader http_status: Integer?
|
|
43
|
+
attr_reader error_code: Integer?
|
|
44
|
+
attr_reader api_message: String?
|
|
45
|
+
attr_reader response_body: String?
|
|
46
|
+
attr_reader response_headers: Hash[String, String]
|
|
47
|
+
def initialize: (?String? message, ?http_status: Integer?, ?error_code: Integer?, ?api_message: String?,
|
|
48
|
+
?response_body: String?, ?response_headers: Hash[String, String]) -> void
|
|
49
|
+
def error_code_description: () -> String?
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
class AuthenticationError < ApiError
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
class ForbiddenError < ApiError
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
class NotFoundError < ApiError
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
class PayloadTooLargeError < ApiError
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
class UnprocessableEntityError < ApiError
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
class RateLimitError < ApiError
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
class ServerError < ApiError
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
class ServiceUnavailableError < ServerError
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
class UnexpectedResponseError < ApiError
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
module ErrorCodes
|
|
80
|
+
INVALID_API_TOKEN: Integer
|
|
81
|
+
NOT_FOUND_OR_INCOMPLETE_REQUEST: Integer
|
|
82
|
+
INTERNAL_ERROR: Integer
|
|
83
|
+
UNKNOWN_API_METHOD: Integer
|
|
84
|
+
MISSING_REQUIRED_FIELDS: Integer
|
|
85
|
+
ACCOUNT_CANNOT_SEND: Integer
|
|
86
|
+
INVALID_EMAIL_ADDRESS: Integer
|
|
87
|
+
ACTION_NOT_ALLOWED: Integer
|
|
88
|
+
ATTACHMENT_TOO_LARGE: Integer
|
|
89
|
+
INVALID_ATTACHMENT_TYPE: Integer
|
|
90
|
+
SENDING_UNAVAILABLE: Integer
|
|
91
|
+
TEMPORARY_SENDING_ERROR: Integer
|
|
92
|
+
INVALID_HEADERS: Integer
|
|
93
|
+
SENDER_SIGNATURE_NOT_CONFIRMED: Integer
|
|
94
|
+
INVALID_FIELD_VALUE_OR_BATCH: Integer
|
|
95
|
+
SENDER_NOT_CONFIRMED: Integer
|
|
96
|
+
INVALID_REQUEST_FIELD: Integer
|
|
97
|
+
FORBIDDEN_ATTACHMENT_TYPE: Integer
|
|
98
|
+
RECIPIENT_NOT_CONFIRMED: Integer
|
|
99
|
+
TEMPLATE_NOT_FOUND: Integer
|
|
100
|
+
MESSAGE_STREAM_NOT_FOUND: Integer
|
|
101
|
+
CANNOT_SEND_VIA_INBOUND_STREAM: Integer
|
|
102
|
+
INVALID_MESSAGES_QUERY: Integer
|
|
103
|
+
MESSAGE_NOT_FOUND: Integer
|
|
104
|
+
BYPASS_ONLY_BLOCKED: Integer
|
|
105
|
+
RETRY_ONLY_FAILED: Integer
|
|
106
|
+
INVALID_RULE_REQUEST: Integer
|
|
107
|
+
RULE_ALREADY_EXISTS: Integer
|
|
108
|
+
RULE_NOT_FOUND: Integer
|
|
109
|
+
INVALID_RULE: Integer
|
|
110
|
+
DOMAIN_OR_SERVER_NOT_FOUND: Integer
|
|
111
|
+
DOMAIN_ALREADY_EXISTS: Integer
|
|
112
|
+
INVALID_DOMAIN: Integer
|
|
113
|
+
TEMPLATE_VALIDATION_NOTHING_TO_CHECK: Integer
|
|
114
|
+
INVALID_INBOUND_DOMAIN: Integer
|
|
115
|
+
INBOUND_DOMAIN_IN_USE: Integer
|
|
116
|
+
INVALID_INBOUND_HOOK_URL: Integer
|
|
117
|
+
INBOUND_DOMAIN_MISSING_MX: Integer
|
|
118
|
+
INVALID_INBOUND_SPAM_THRESHOLD: Integer
|
|
119
|
+
INVALID_MESSAGE_STREAM_TYPE: Integer
|
|
120
|
+
CANNOT_CREATE_INBOUND_STREAM: Integer
|
|
121
|
+
CANNOT_ARCHIVE_INBOUND_STREAM: Integer
|
|
122
|
+
DESCRIPTIONS: Hash[Integer, String]
|
|
123
|
+
def self.describe: (Integer? code) -> String?
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
class Configuration
|
|
127
|
+
DEFAULT_BASE_URL: String
|
|
128
|
+
ATTRIBUTES: Array[Symbol]
|
|
129
|
+
|
|
130
|
+
attr_reader base_url: String
|
|
131
|
+
attr_reader open_timeout: Numeric
|
|
132
|
+
attr_reader read_timeout: Numeric
|
|
133
|
+
attr_reader write_timeout: Numeric
|
|
134
|
+
attr_reader max_retries: Integer
|
|
135
|
+
attr_reader logger: untyped
|
|
136
|
+
attr_reader proxy: URI::Generic | false | nil
|
|
137
|
+
attr_reader ca_file: String?
|
|
138
|
+
attr_reader user_agent: String?
|
|
139
|
+
|
|
140
|
+
def initialize: (**untyped options) -> void
|
|
141
|
+
def update: (**untyped options) -> self
|
|
142
|
+
def base_url=: (String value) -> void
|
|
143
|
+
def open_timeout=: (Numeric value) -> void
|
|
144
|
+
def read_timeout=: (Numeric value) -> void
|
|
145
|
+
def write_timeout=: (Numeric value) -> void
|
|
146
|
+
def max_retries=: (Integer value) -> void
|
|
147
|
+
def logger=: (untyped value) -> void
|
|
148
|
+
def proxy=: (String | URI::Generic | false | nil value) -> void
|
|
149
|
+
def ca_file=: (String? value) -> void
|
|
150
|
+
def user_agent=: (String? value) -> void
|
|
151
|
+
def to_h: () -> Hash[Symbol, untyped]
|
|
152
|
+
def inspect: () -> String
|
|
153
|
+
alias to_s inspect
|
|
154
|
+
def marshal_dump: () -> bot
|
|
155
|
+
def encode_with: (untyped coder) -> void
|
|
156
|
+
def self.parse_proxy: (untyped value, ?source: String) -> URI::Generic
|
|
157
|
+
def self.normalize_base_url: (untyped value) -> String
|
|
158
|
+
end
|
|
159
|
+
|
|
160
|
+
class ApiObject
|
|
161
|
+
def initialize: (Hash[untyped, untyped] data) -> void
|
|
162
|
+
def []: (untyped key) -> untyped
|
|
163
|
+
def fetch: (String | Symbol key, *untyped default) ?{ (String | Symbol) -> untyped } -> untyped
|
|
164
|
+
def key?: (untyped key) -> bool
|
|
165
|
+
alias include? key?
|
|
166
|
+
def dig: (String | Symbol key, *untyped rest) -> untyped
|
|
167
|
+
def keys: () -> Array[String]
|
|
168
|
+
def each: () { (String, untyped) -> void } -> self
|
|
169
|
+
| () -> Enumerator[[String, untyped], self]
|
|
170
|
+
def to_h: () -> Hash[String, untyped]
|
|
171
|
+
alias to_hash to_h
|
|
172
|
+
def to_json: (*untyped args) -> String
|
|
173
|
+
def ==: (untyped other) -> bool
|
|
174
|
+
def eql?: (untyped other) -> bool
|
|
175
|
+
def hash: () -> Integer
|
|
176
|
+
def marshal_dump: () -> Hash[String, untyped]
|
|
177
|
+
def marshal_load: (Hash[String, untyped] data) -> void
|
|
178
|
+
def inspect: () -> String
|
|
179
|
+
alias to_s inspect
|
|
180
|
+
def self.normalize: (String | Symbol key) -> String
|
|
181
|
+
def self.wrap: (untyped value) -> untyped
|
|
182
|
+
end
|
|
183
|
+
|
|
184
|
+
class SendResult < ApiObject
|
|
185
|
+
def error_code: () -> Integer?
|
|
186
|
+
def success?: () -> bool
|
|
187
|
+
def message_ids: () -> Array[String]
|
|
188
|
+
def submitted_at_time: () -> Time?
|
|
189
|
+
end
|
|
190
|
+
|
|
191
|
+
class BatchResult
|
|
192
|
+
include Enumerable[SendResult]
|
|
193
|
+
|
|
194
|
+
attr_reader results: Array[SendResult]
|
|
195
|
+
def initialize: (Array[SendResult] results) -> void
|
|
196
|
+
def each: () { (SendResult) -> void } -> self
|
|
197
|
+
| () -> Enumerator[SendResult, self]
|
|
198
|
+
def []: (Integer index) -> SendResult?
|
|
199
|
+
def size: () -> Integer
|
|
200
|
+
alias length size
|
|
201
|
+
def empty?: () -> bool
|
|
202
|
+
def success?: () -> bool
|
|
203
|
+
def successful: () -> Array[SendResult]
|
|
204
|
+
def failed: () -> Array[SendResult]
|
|
205
|
+
def to_a: () -> Array[SendResult]
|
|
206
|
+
def as_json: (*untyped) -> Array[Hash[String, untyped]]
|
|
207
|
+
def to_json: (*untyped args) -> String
|
|
208
|
+
def ==: (untyped other) -> bool
|
|
209
|
+
def eql?: (untyped other) -> bool
|
|
210
|
+
def hash: () -> Integer
|
|
211
|
+
def inspect: () -> String
|
|
212
|
+
alias to_s inspect
|
|
213
|
+
end
|
|
214
|
+
|
|
215
|
+
class Paginator
|
|
216
|
+
include Enumerable[ApiObject]
|
|
217
|
+
|
|
218
|
+
def initialize: (items_key: String, page_size: Integer, ?max_window: Integer?) {
|
|
219
|
+
(Integer, Integer) -> untyped
|
|
220
|
+
} -> void
|
|
221
|
+
def each: () { (ApiObject) -> void } -> self
|
|
222
|
+
| () -> Enumerator[ApiObject, self]
|
|
223
|
+
private def last_page?: (untyped total, Integer size, Integer count, Integer offset) -> bool
|
|
224
|
+
end
|
|
225
|
+
|
|
226
|
+
class Attachment
|
|
227
|
+
FORBIDDEN_EXTENSIONS: Array[String]
|
|
228
|
+
MAX_MESSAGE_SIZE: Integer
|
|
229
|
+
MIME_TYPES: Hash[String, String]
|
|
230
|
+
DEFAULT_CONTENT_TYPE: String
|
|
231
|
+
CONTENT_TYPE_FORMAT: Regexp
|
|
232
|
+
|
|
233
|
+
attr_reader name: String
|
|
234
|
+
attr_reader content_type: String
|
|
235
|
+
attr_reader content_id: String?
|
|
236
|
+
|
|
237
|
+
def self.from_file: (String | _ToS path, ?name: String?, ?content_type: String?, ?content_id: String?) -> Attachment
|
|
238
|
+
def initialize: (name: String, content: String, ?content_type: String?, ?content_id: String?) -> void
|
|
239
|
+
def inline?: () -> bool
|
|
240
|
+
def encoded_size: () -> Integer
|
|
241
|
+
def to_haskimail: () -> Hash[String, String]
|
|
242
|
+
alias to_h to_haskimail
|
|
243
|
+
def self.validate_name!: (untyped name) -> String
|
|
244
|
+
def self.validate_content_type!: (untyped value) -> String
|
|
245
|
+
def self.validate_content_id!: (untyped value) -> String
|
|
246
|
+
def self.extension_of: (String name) -> String
|
|
247
|
+
def self.detect_content_type: (String name) -> String
|
|
248
|
+
end
|
|
249
|
+
|
|
250
|
+
module HTTP
|
|
251
|
+
SENSITIVE_HEADERS: Array[String]
|
|
252
|
+
|
|
253
|
+
class Request
|
|
254
|
+
attr_reader method: Symbol
|
|
255
|
+
attr_reader url: String
|
|
256
|
+
attr_reader headers: Hash[String, String]
|
|
257
|
+
attr_reader body: String?
|
|
258
|
+
attr_reader idempotent: bool?
|
|
259
|
+
def initialize: (method: Symbol, url: String, headers: Hash[String, String], body: String?,
|
|
260
|
+
?idempotent: bool?) -> void
|
|
261
|
+
def idempotent?: () -> bool
|
|
262
|
+
def inspect: () -> String
|
|
263
|
+
alias to_s inspect
|
|
264
|
+
def pretty_print: (untyped printer) -> void
|
|
265
|
+
end
|
|
266
|
+
|
|
267
|
+
class Response
|
|
268
|
+
attr_reader status: Integer
|
|
269
|
+
attr_reader headers: Hash[String, String]
|
|
270
|
+
attr_reader body: String
|
|
271
|
+
def initialize: (status: Integer, headers: Hash[String, String], body: String) -> void
|
|
272
|
+
def ==: (untyped other) -> bool
|
|
273
|
+
end
|
|
274
|
+
|
|
275
|
+
interface _Transport
|
|
276
|
+
def call: (Request request, open_timeout: Numeric, read_timeout: Numeric, write_timeout: Numeric) -> Response
|
|
277
|
+
end
|
|
278
|
+
|
|
279
|
+
class RetryPolicy
|
|
280
|
+
RETRYABLE_STATUSES: Array[Integer]
|
|
281
|
+
REFUSED_STATUSES: Array[Integer]
|
|
282
|
+
RETRYABLE_ERROR_CODES: Array[Integer]
|
|
283
|
+
IDEMPOTENT_RETRYABLE_ERROR_CODES: Array[Integer]
|
|
284
|
+
MAX_RETRY_AFTER: Integer
|
|
285
|
+
BASE_DELAY: Float
|
|
286
|
+
MAX_DELAY: Float
|
|
287
|
+
|
|
288
|
+
attr_reader max_retries: Integer
|
|
289
|
+
def initialize: (max_retries: Integer, ?random: untyped, ?clock: ^() -> Time) -> void
|
|
290
|
+
def retry_response?: (Request request, Response response, Integer? error_code, Integer attempt) -> bool
|
|
291
|
+
def retry_error?: (Request request, ConnectionError error, Integer attempt) -> bool
|
|
292
|
+
def delay: (Integer attempt, ?Response? response) -> Float
|
|
293
|
+
end
|
|
294
|
+
|
|
295
|
+
module ResponseParser
|
|
296
|
+
ERROR_CLASSES: Hash[Integer, singleton(ApiError)]
|
|
297
|
+
def self.parse: (Response response) -> untyped
|
|
298
|
+
def self.blank_body?: (untyped body) -> bool
|
|
299
|
+
def self.error_code: (untyped data) -> Integer?
|
|
300
|
+
def self.malformed_error_code?: (untyped data) -> bool
|
|
301
|
+
def self.success?: (Response response, untyped data) -> bool
|
|
302
|
+
def self.api_error: (Response response, untyped data) -> ApiError
|
|
303
|
+
def self.unexpected_body_error: (Request request, Response response, ?String reason) -> UnexpectedResponseError
|
|
304
|
+
def self.error_class: (Integer status) -> singleton(ApiError)
|
|
305
|
+
end
|
|
306
|
+
|
|
307
|
+
interface _Env
|
|
308
|
+
def []: (String name) -> String?
|
|
309
|
+
end
|
|
310
|
+
|
|
311
|
+
class NetHttpTransport
|
|
312
|
+
include _Transport
|
|
313
|
+
MAX_RESPONSE_SIZE: Integer
|
|
314
|
+
PROXY_ENV: Array[String]
|
|
315
|
+
def initialize: (?proxy: URI::Generic | false | nil, ?ca_file: String?, ?env: _Env) -> void
|
|
316
|
+
def self.env_proxy: (_Env env) -> URI::Generic?
|
|
317
|
+
end
|
|
318
|
+
end
|
|
319
|
+
|
|
320
|
+
class BaseClient
|
|
321
|
+
HTTP_METHODS: Array[Symbol]
|
|
322
|
+
|
|
323
|
+
attr_reader config: Configuration
|
|
324
|
+
def initialize: (String? token, ?transport: HTTP::_Transport?, ?sleeper: ^(Float) -> void | nil,
|
|
325
|
+
**untyped options) -> void
|
|
326
|
+
def request: (Symbol method, String path, ?query: Hash[String, untyped]?, ?body: untyped) -> untyped
|
|
327
|
+
def inspect: () -> String
|
|
328
|
+
alias to_s inspect
|
|
329
|
+
def self.validate_token!: (untyped token) -> String
|
|
330
|
+
def perform: (Symbol method, String path, ?query: Hash[String, untyped]?, ?body: untyped,
|
|
331
|
+
?idempotent: bool?) -> json
|
|
332
|
+
def expect_object: (untyped data) -> Hash[String, untyped]
|
|
333
|
+
def wrap: (json data) -> untyped
|
|
334
|
+
end
|
|
335
|
+
|
|
336
|
+
class ServerClient < BaseClient
|
|
337
|
+
TOKEN_HEADER: String
|
|
338
|
+
def initialize: (?String? token, ?transport: HTTP::_Transport?, ?sleeper: ^(Float) -> void | nil,
|
|
339
|
+
**untyped options) -> void
|
|
340
|
+
attr_reader emails: Resources::Emails
|
|
341
|
+
attr_reader templates: Resources::Templates
|
|
342
|
+
attr_reader messages: Resources::Messages
|
|
343
|
+
attr_reader opens: Resources::Opens
|
|
344
|
+
attr_reader clicks: Resources::Clicks
|
|
345
|
+
attr_reader inbound_messages: Resources::InboundMessages
|
|
346
|
+
attr_reader bounces: Resources::Bounces
|
|
347
|
+
attr_reader message_streams: Resources::MessageStreams
|
|
348
|
+
attr_reader suppressions: Resources::Suppressions
|
|
349
|
+
attr_reader webhooks: Resources::Webhooks
|
|
350
|
+
attr_reader inbound_rules: Resources::InboundRules
|
|
351
|
+
attr_reader stats: Resources::Stats
|
|
352
|
+
end
|
|
353
|
+
|
|
354
|
+
class AccountClient < BaseClient
|
|
355
|
+
TOKEN_HEADER: String
|
|
356
|
+
def initialize: (?String? token, ?transport: HTTP::_Transport?, ?sleeper: ^(Float) -> void | nil,
|
|
357
|
+
**untyped options) -> void
|
|
358
|
+
attr_reader servers: Resources::Servers
|
|
359
|
+
attr_reader domains: Resources::Domains
|
|
360
|
+
attr_reader templates: Resources::AccountTemplates
|
|
361
|
+
attr_reader messages: Resources::Messages
|
|
362
|
+
attr_reader opens: Resources::Opens
|
|
363
|
+
attr_reader clicks: Resources::Clicks
|
|
364
|
+
attr_reader bounces: Resources::Bounces
|
|
365
|
+
attr_reader message_streams: Resources::MessageStreams
|
|
366
|
+
attr_reader webhooks: Resources::Webhooks
|
|
367
|
+
attr_reader stats: Resources::Stats
|
|
368
|
+
end
|
|
369
|
+
|
|
370
|
+
module TestAddresses
|
|
371
|
+
DOMAIN: String
|
|
372
|
+
HARD_BOUNCE: String
|
|
373
|
+
SOFT_BOUNCE: String
|
|
374
|
+
BLOCKED: String
|
|
375
|
+
SPAM_COMPLAINT: String
|
|
376
|
+
end
|
|
377
|
+
|
|
378
|
+
module Resources
|
|
379
|
+
class Base
|
|
380
|
+
PAGING: Hash[Symbol, String]
|
|
381
|
+
def initialize: (BaseClient client) -> void
|
|
382
|
+
end
|
|
383
|
+
|
|
384
|
+
class Emails < Base
|
|
385
|
+
MAX_BATCH_SIZE: Integer
|
|
386
|
+
MAX_BATCH_BYTES: Integer
|
|
387
|
+
MAX_MESSAGE_BYTES: Integer
|
|
388
|
+
RECIPIENT_FIELDS: Array[String]
|
|
389
|
+
BODY_FIELDS: Array[String]
|
|
390
|
+
TEMPLATE_FIELDS: Array[String]
|
|
391
|
+
EMAIL_FIELDS: Array[String]
|
|
392
|
+
HEADER_ITEM_FIELDS: Array[String]
|
|
393
|
+
ATTACHMENT_FIELDS: Array[String]
|
|
394
|
+
COMMENT: Regexp
|
|
395
|
+
HEADER_FIELDS: Array[String]
|
|
396
|
+
ADDRESS_FIELDS: Array[String]
|
|
397
|
+
UNSAFE_HEADER_CHARS: Regexp
|
|
398
|
+
HEADER_NAME: Regexp
|
|
399
|
+
MAX_RECIPIENTS: Integer
|
|
400
|
+
MAX_FROM_LENGTH: Integer
|
|
401
|
+
MAX_SUBJECT_LENGTH: Integer
|
|
402
|
+
MAX_TAG_LENGTH: Integer
|
|
403
|
+
MAX_BODY_BYTES: Integer
|
|
404
|
+
LENGTH_LIMITS: Hash[String, Integer]
|
|
405
|
+
QUOTED: Regexp
|
|
406
|
+
ANGLE_ADDR: Regexp
|
|
407
|
+
def self.count_addresses: (untyped list) -> Integer
|
|
408
|
+
def deliver: (?params? message, **untyped fields) -> SendResult
|
|
409
|
+
def deliver_batch: (Array[params] messages) -> BatchResult
|
|
410
|
+
def deliver_with_template: (?params? message, **untyped fields) -> SendResult
|
|
411
|
+
def deliver_batch_with_templates: (Array[params] messages) -> BatchResult
|
|
412
|
+
end
|
|
413
|
+
|
|
414
|
+
class Templates < Base
|
|
415
|
+
def list: (?count: Integer?, ?offset: Integer?) -> ApiObject
|
|
416
|
+
def each: (?page_size: Integer) -> Paginator
|
|
417
|
+
| (?page_size: Integer) { (ApiObject) -> void } -> Paginator
|
|
418
|
+
def get: (id id_or_alias) -> ApiObject
|
|
419
|
+
def create: (?params? params, **untyped fields) -> ApiObject
|
|
420
|
+
def update: (id id_or_alias, name: String, subject: String, html_body: String, text_body: String) -> ApiObject
|
|
421
|
+
def delete: (id id_or_alias) -> ApiObject
|
|
422
|
+
def validate: (?params? params, **untyped fields) -> ApiObject
|
|
423
|
+
end
|
|
424
|
+
|
|
425
|
+
class AccountTemplates < Templates
|
|
426
|
+
def create: (?params? params, **untyped fields) -> ApiObject
|
|
427
|
+
def push: (source_server_id: Integer, destination_server_id: Integer, perform_changes: bool) -> ApiObject
|
|
428
|
+
end
|
|
429
|
+
|
|
430
|
+
class OutboundSearch < Base
|
|
431
|
+
MAX_PAGE_SIZE: Integer
|
|
432
|
+
MAX_WINDOW: Integer
|
|
433
|
+
end
|
|
434
|
+
|
|
435
|
+
class Messages < OutboundSearch
|
|
436
|
+
FILTERS: Hash[Symbol, String]
|
|
437
|
+
def list: (**untyped filters) -> ApiObject
|
|
438
|
+
def each: (?page_size: Integer, **untyped filters) ?{ (ApiObject) -> void } -> Paginator
|
|
439
|
+
def details: (id message_id) -> ApiObject
|
|
440
|
+
end
|
|
441
|
+
|
|
442
|
+
class Opens < OutboundSearch
|
|
443
|
+
FILTERS: Hash[Symbol, String]
|
|
444
|
+
MESSAGE_FILTERS: Hash[Symbol, String]
|
|
445
|
+
def list: (**untyped filters) -> ApiObject
|
|
446
|
+
def each: (?page_size: Integer, **untyped filters) ?{ (ApiObject) -> void } -> Paginator
|
|
447
|
+
def for_message: (id message_id, **untyped filters) -> ApiObject
|
|
448
|
+
end
|
|
449
|
+
|
|
450
|
+
class Clicks < OutboundSearch
|
|
451
|
+
FILTERS: Hash[Symbol, String]
|
|
452
|
+
MESSAGE_FILTERS: Hash[Symbol, String]
|
|
453
|
+
def list: (**untyped filters) -> ApiObject
|
|
454
|
+
def each: (?page_size: Integer, **untyped filters) ?{ (ApiObject) -> void } -> Paginator
|
|
455
|
+
def for_message: (id message_id, **untyped filters) -> ApiObject
|
|
456
|
+
end
|
|
457
|
+
|
|
458
|
+
class InboundMessages < Base
|
|
459
|
+
FILTERS: Hash[Symbol, String]
|
|
460
|
+
STATUSES: Array[String]
|
|
461
|
+
MAX_PAGE_SIZE: Integer
|
|
462
|
+
def list: (**untyped filters) -> ApiObject
|
|
463
|
+
def each: (?page_size: Integer, **untyped filters) ?{ (ApiObject) -> void } -> Paginator
|
|
464
|
+
def details: (id message_id) -> ApiObject
|
|
465
|
+
def bypass: (id message_id) -> ApiObject
|
|
466
|
+
def retry: (id message_id) -> ApiObject
|
|
467
|
+
end
|
|
468
|
+
|
|
469
|
+
class Bounces < Base
|
|
470
|
+
FILTERS: Hash[Symbol, String]
|
|
471
|
+
TYPES: Array[String]
|
|
472
|
+
def delivery_stats: () -> ApiObject
|
|
473
|
+
def list: (**untyped filters) -> ApiObject
|
|
474
|
+
def each: (?page_size: Integer, **untyped filters) ?{ (ApiObject) -> void } -> Paginator
|
|
475
|
+
end
|
|
476
|
+
|
|
477
|
+
module Dates
|
|
478
|
+
KEYS: Array[Symbol]
|
|
479
|
+
def self.date_only: (Hash[untyped, untyped] filters) -> Hash[untyped, untyped]
|
|
480
|
+
end
|
|
481
|
+
|
|
482
|
+
class MessageStreams < Base
|
|
483
|
+
TYPES: Array[String]
|
|
484
|
+
def list: () -> ApiObject
|
|
485
|
+
def get: (id stream_id) -> ApiObject
|
|
486
|
+
def create: (name: String, message_stream_type: String | Symbol, ?server_id: Integer?) -> ApiObject
|
|
487
|
+
def update: (id stream_id, name: String) -> ApiObject
|
|
488
|
+
def archive: (id stream_id) -> ApiObject
|
|
489
|
+
def unarchive: (id stream_id) -> ApiObject
|
|
490
|
+
end
|
|
491
|
+
|
|
492
|
+
class Suppressions < Base
|
|
493
|
+
def list: (id stream_id) -> ApiObject
|
|
494
|
+
def create: (id stream_id, String | Array[String] emails) -> ApiObject
|
|
495
|
+
def delete: (id stream_id, String | Array[String] emails) -> ApiObject
|
|
496
|
+
end
|
|
497
|
+
|
|
498
|
+
class Webhooks < Base
|
|
499
|
+
TRIGGERS: Hash[Symbol, String]
|
|
500
|
+
def list: () -> ApiObject
|
|
501
|
+
def get: (id webhook_id) -> ApiObject
|
|
502
|
+
def create: (url: String, ?message_stream: id?, ?triggers: Hash[untyped, untyped]) -> ApiObject
|
|
503
|
+
def update: (id webhook_id, ?url: String?, ?triggers: Hash[untyped, untyped]?) -> ApiObject
|
|
504
|
+
def delete: (id webhook_id) -> ApiObject
|
|
505
|
+
end
|
|
506
|
+
|
|
507
|
+
class InboundRules < Base
|
|
508
|
+
MAX_PAGE_SIZE: Integer
|
|
509
|
+
def list: (?count: Integer?, ?offset: Integer?) -> ApiObject
|
|
510
|
+
def each: (?page_size: Integer) ?{ (ApiObject) -> void } -> Paginator
|
|
511
|
+
def create: (String rule) -> ApiObject
|
|
512
|
+
def delete: (id rule_id) -> ApiObject
|
|
513
|
+
end
|
|
514
|
+
|
|
515
|
+
class Stats < Base
|
|
516
|
+
FILTERS: Hash[Symbol, String]
|
|
517
|
+
ENDPOINTS: Hash[Symbol, String]
|
|
518
|
+
def summary: (**untyped filters) -> ApiObject
|
|
519
|
+
def sends: (**untyped filters) -> ApiObject
|
|
520
|
+
def bounces: (**untyped filters) -> ApiObject
|
|
521
|
+
def spam_complaints: (**untyped filters) -> ApiObject
|
|
522
|
+
def opens: (**untyped filters) -> ApiObject
|
|
523
|
+
def clicks: (**untyped filters) -> ApiObject
|
|
524
|
+
def opens_by_platform: (**untyped filters) -> ApiObject
|
|
525
|
+
def opens_by_email_client: (**untyped filters) -> ApiObject
|
|
526
|
+
def clicks_by_browser_family: (**untyped filters) -> ApiObject
|
|
527
|
+
def clicks_by_platform: (**untyped filters) -> ApiObject
|
|
528
|
+
end
|
|
529
|
+
|
|
530
|
+
class Servers < Base
|
|
531
|
+
COLORS: Array[String]
|
|
532
|
+
TRACK_LINKS: Array[String]
|
|
533
|
+
DELIVERY_TYPES: Array[String]
|
|
534
|
+
def list: (?count: Integer?, ?offset: Integer?) -> ApiObject
|
|
535
|
+
def each: (?page_size: Integer) ?{ (ApiObject) -> void } -> Paginator
|
|
536
|
+
def get: (id server_id) -> ApiObject
|
|
537
|
+
def create: (?params? params, **untyped fields) -> ApiObject
|
|
538
|
+
def update: (id server_id, ?params? params, **untyped fields) -> ApiObject
|
|
539
|
+
def delete: (id server_id) -> ApiObject
|
|
540
|
+
def issue_token: (id server_id, ?name: String?) -> ApiObject
|
|
541
|
+
end
|
|
542
|
+
|
|
543
|
+
class Domains < Base
|
|
544
|
+
def list: (?count: Integer?, ?offset: Integer?) -> ApiObject
|
|
545
|
+
def each: (?page_size: Integer) ?{ (ApiObject) -> void } -> Paginator
|
|
546
|
+
def get: (id domain_id) -> ApiObject
|
|
547
|
+
def create: (String name) -> ApiObject
|
|
548
|
+
def delete: (id domain_id) -> ApiObject
|
|
549
|
+
def verify_dkim: (id domain_id) -> ApiObject
|
|
550
|
+
def verify_spf: (id domain_id) -> ApiObject
|
|
551
|
+
end
|
|
552
|
+
end
|
|
553
|
+
|
|
554
|
+
module Webhook
|
|
555
|
+
MAX_EVENT_SIZE: Integer
|
|
556
|
+
MAX_INBOUND_SIZE: Integer
|
|
557
|
+
RECIPIENT_FORMAT: Regexp
|
|
558
|
+
MESSAGE_ID_FORMAT: Regexp
|
|
559
|
+
GUARDED_FIELDS: Array[String]
|
|
560
|
+
HUGE_NUMBER: Regexp
|
|
561
|
+
JSON_STRING: Regexp
|
|
562
|
+
JSON_OBJECT_START: Regexp
|
|
563
|
+
|
|
564
|
+
def self.construct_event: (String payload, signing_key: String, ?max_size: Integer) -> Event
|
|
565
|
+
def self.parse_event: (String payload, ?max_size: Integer) -> Event
|
|
566
|
+
def self.valid_signature?: (untyped event, signing_key: String) -> bool
|
|
567
|
+
def self.parse_inbound: (String payload, ?max_size: Integer) -> InboundMessage
|
|
568
|
+
|
|
569
|
+
class Event < ApiObject
|
|
570
|
+
TYPES: Hash[String, Symbol]
|
|
571
|
+
BOUNCE_CATEGORIES: Hash[String, Symbol]
|
|
572
|
+
def type: () -> Symbol
|
|
573
|
+
def sent?: () -> bool
|
|
574
|
+
def delivered?: () -> bool
|
|
575
|
+
def bounced?: () -> bool
|
|
576
|
+
def complained?: () -> bool
|
|
577
|
+
def opened?: () -> bool
|
|
578
|
+
def clicked?: () -> bool
|
|
579
|
+
def subscription_change?: () -> bool
|
|
580
|
+
def recipient: () -> String?
|
|
581
|
+
def message_id: () -> String
|
|
582
|
+
def email: () -> String?
|
|
583
|
+
def tag: () -> String
|
|
584
|
+
def metadata: () -> Hash[String, untyped]
|
|
585
|
+
def server_id: () -> Integer?
|
|
586
|
+
def stream_id: () -> String?
|
|
587
|
+
def occurred_at: () -> Time?
|
|
588
|
+
def bounce_category: () -> Symbol?
|
|
589
|
+
def suppressed?: () -> bool
|
|
590
|
+
def idempotency_key: () -> String
|
|
591
|
+
end
|
|
592
|
+
|
|
593
|
+
class InboundMessage < ApiObject
|
|
594
|
+
def attachments: () -> Array[InboundAttachment]
|
|
595
|
+
def header: (String | Symbol name) -> String?
|
|
596
|
+
def spam_score: () -> Float?
|
|
597
|
+
def inspect: () -> String
|
|
598
|
+
alias to_s inspect
|
|
599
|
+
def pretty_print: (untyped printer) -> void
|
|
600
|
+
end
|
|
601
|
+
|
|
602
|
+
class InboundAttachment
|
|
603
|
+
attr_reader name: String
|
|
604
|
+
attr_reader content_type: String
|
|
605
|
+
attr_reader content_id: String
|
|
606
|
+
attr_reader content: String
|
|
607
|
+
def initialize: (name: String, content_type: String, content_id: String, content: String) -> void
|
|
608
|
+
def inline?: () -> bool
|
|
609
|
+
def size: () -> Integer
|
|
610
|
+
def to_h: () -> Hash[Symbol, String]
|
|
611
|
+
def ==: (untyped other) -> bool
|
|
612
|
+
alias eql? ==
|
|
613
|
+
def hash: () -> Integer
|
|
614
|
+
def inspect: () -> String
|
|
615
|
+
alias to_s inspect
|
|
616
|
+
def pretty_print: (untyped printer) -> void
|
|
617
|
+
end
|
|
618
|
+
end
|
|
619
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: haskimail
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 1.0.0
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Dashamail
|
|
8
|
+
autorequire:
|
|
9
|
+
bindir: bin
|
|
10
|
+
cert_chain: []
|
|
11
|
+
date: 2026-11-11 00:00:00.000000000 Z
|
|
12
|
+
dependencies: []
|
|
13
|
+
description: Send transactional email, manage templates, streams, webhooks, suppressions,
|
|
14
|
+
servers and domains, read stats and verify webhooks with Haskimail. Zero runtime
|
|
15
|
+
dependencies.
|
|
16
|
+
email:
|
|
17
|
+
- support@haskimail.ru
|
|
18
|
+
executables: []
|
|
19
|
+
extensions: []
|
|
20
|
+
extra_rdoc_files: []
|
|
21
|
+
files:
|
|
22
|
+
- CHANGELOG.md
|
|
23
|
+
- LICENSE
|
|
24
|
+
- README.md
|
|
25
|
+
- SECURITY.md
|
|
26
|
+
- lib/haskimail.rb
|
|
27
|
+
- lib/haskimail/api_object.rb
|
|
28
|
+
- lib/haskimail/attachment.rb
|
|
29
|
+
- lib/haskimail/base_client.rb
|
|
30
|
+
- lib/haskimail/clients.rb
|
|
31
|
+
- lib/haskimail/configuration.rb
|
|
32
|
+
- lib/haskimail/errors.rb
|
|
33
|
+
- lib/haskimail/http/net_http_transport.rb
|
|
34
|
+
- lib/haskimail/http/response_parser.rb
|
|
35
|
+
- lib/haskimail/http/retry_policy.rb
|
|
36
|
+
- lib/haskimail/redacted.rb
|
|
37
|
+
- lib/haskimail/resources/account_resources.rb
|
|
38
|
+
- lib/haskimail/resources/base.rb
|
|
39
|
+
- lib/haskimail/resources/emails.rb
|
|
40
|
+
- lib/haskimail/resources/messages.rb
|
|
41
|
+
- lib/haskimail/resources/server_resources.rb
|
|
42
|
+
- lib/haskimail/resources/templates.rb
|
|
43
|
+
- lib/haskimail/test_addresses.rb
|
|
44
|
+
- lib/haskimail/util.rb
|
|
45
|
+
- lib/haskimail/version.rb
|
|
46
|
+
- lib/haskimail/webhook.rb
|
|
47
|
+
- sig/haskimail.rbs
|
|
48
|
+
- sig/haskimail/internal.rbs
|
|
49
|
+
homepage: https://haskimail.ru
|
|
50
|
+
licenses:
|
|
51
|
+
- MIT
|
|
52
|
+
metadata:
|
|
53
|
+
homepage_uri: https://haskimail.ru
|
|
54
|
+
documentation_uri: https://haskimail.ru/developer
|
|
55
|
+
changelog_uri: https://github.com/Dashamail/haskimail-ruby/blob/main/CHANGELOG.md
|
|
56
|
+
source_code_uri: https://github.com/Dashamail/haskimail-ruby
|
|
57
|
+
bug_tracker_uri: https://github.com/Dashamail/haskimail-ruby/issues
|
|
58
|
+
rubygems_mfa_required: 'true'
|
|
59
|
+
post_install_message:
|
|
60
|
+
rdoc_options: []
|
|
61
|
+
require_paths:
|
|
62
|
+
- lib
|
|
63
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
64
|
+
requirements:
|
|
65
|
+
- - ">="
|
|
66
|
+
- !ruby/object:Gem::Version
|
|
67
|
+
version: '3.1'
|
|
68
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
69
|
+
requirements:
|
|
70
|
+
- - ">="
|
|
71
|
+
- !ruby/object:Gem::Version
|
|
72
|
+
version: '0'
|
|
73
|
+
requirements: []
|
|
74
|
+
rubygems_version: 3.4.19
|
|
75
|
+
signing_key:
|
|
76
|
+
specification_version: 4
|
|
77
|
+
summary: Ruby SDK for the Haskimail transactional email API
|
|
78
|
+
test_files: []
|