mailtrap 1.2.1 → 2.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 +4 -4
- data/.rubocop.yml +8 -0
- data/CHANGELOG.md +20 -0
- data/Gemfile.lock +1 -1
- data/README.md +21 -79
- data/lib/mailtrap/action_mailer/delivery_method.rb +3 -1
- data/lib/mailtrap/attachment.rb +50 -0
- data/lib/mailtrap/client.rb +117 -0
- data/lib/mailtrap/errors.rb +35 -0
- data/lib/mailtrap/mail/base.rb +2 -2
- data/lib/mailtrap/version.rb +1 -1
- data/lib/mailtrap.rb +1 -1
- data/mailtrap.gemspec +3 -1
- metadata +6 -6
- data/lib/mailtrap/sending/attachment.rb +0 -52
- data/lib/mailtrap/sending/client.rb +0 -64
- data/lib/mailtrap/sending.rb +0 -22
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 7529f2a048f1670c6eb22f04a9308e17fb3072a0bcacdff87f3772e45f792201
|
|
4
|
+
data.tar.gz: bc71abbd0af5a9c79d719aaaa69671aa836ec00f3a42c1c94991605ab803494d
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: ad794ce35f915afd6ff52da55278c21146630f8f05a5f544477dbeb53c9eb7cf3277632b0f3584c909c6b3d8f2bd339c575f1d32da5065b86f88450053e716c1
|
|
7
|
+
data.tar.gz: f5b564ce76bc6d9157c5e58654cbfe54ee7f1cf169b53b2d3856ecf8fda1cd7b1fef6becc6eac2ed6bf3bbbed29eb63b8bcfb8c58fb237e37d4b68e43a78a020
|
data/.rubocop.yml
CHANGED
|
@@ -31,3 +31,11 @@ Style/StringLiterals:
|
|
|
31
31
|
Style/StringLiteralsInInterpolation:
|
|
32
32
|
Enabled: true
|
|
33
33
|
EnforcedStyle: double_quotes
|
|
34
|
+
|
|
35
|
+
Style/FrozenStringLiteralComment:
|
|
36
|
+
Exclude:
|
|
37
|
+
- 'examples/**/*'
|
|
38
|
+
|
|
39
|
+
Style/TrailingCommaInHashLiteral:
|
|
40
|
+
Exclude:
|
|
41
|
+
- 'examples/**/*'
|
data/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,23 @@
|
|
|
1
|
+
## [2.0.0] - 2024-03-20
|
|
2
|
+
|
|
3
|
+
- Added arguments for `Mailtrap::Client`
|
|
4
|
+
- `bulk` to use Mailtrap bulk sending API
|
|
5
|
+
- `sandbox` to use Mailtrap sandbox API
|
|
6
|
+
- `inbox_id` required when using Mailtrap sandbox API
|
|
7
|
+
|
|
8
|
+
- Removed Sending namespace, affected classes:
|
|
9
|
+
- `Mailtrap::Sending::Client` -> `Mailtrap::Client`
|
|
10
|
+
- `Mailtrap::Sending::Error` -> `Mailtrap::Error`
|
|
11
|
+
- `Mailtrap::Sending::AttachmentContentError` -> `Mailtrap::AttachmentContentError`
|
|
12
|
+
- `Mailtrap::Sending::AuthorizationError` -> `Mailtrap::AuthorizationError`
|
|
13
|
+
- `Mailtrap::Sending::MailSizeError` -> `Mailtrap::MailSizeError`
|
|
14
|
+
- `Mailtrap::Sending::RateLimitError` -> `Mailtrap::RateLimitError`
|
|
15
|
+
- `Mailtrap::Sending::RejectionError` -> `Mailtrap::RejectionError`
|
|
16
|
+
|
|
17
|
+
## [1.2.2] - 2023-11-01
|
|
18
|
+
|
|
19
|
+
- Improved error handling
|
|
20
|
+
|
|
1
21
|
## [1.2.1] - 2023-04-12
|
|
2
22
|
|
|
3
23
|
- Set custom user agent
|
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
|
@@ -6,6 +6,8 @@ This Ruby gem offers integration with the [official API](https://api-docs.mailtr
|
|
|
6
6
|
|
|
7
7
|
Quickly add email sending functionality to your Ruby application with Mailtrap.
|
|
8
8
|
|
|
9
|
+
(This client uses API v2, for v1 refer to [this documentation](https://mailtrap.docs.apiary.io/))
|
|
10
|
+
|
|
9
11
|
## Installation
|
|
10
12
|
|
|
11
13
|
Add this line to your application's Gemfile:
|
|
@@ -40,95 +42,35 @@ mail = Mailtrap::Mail::Base.new(
|
|
|
40
42
|
)
|
|
41
43
|
|
|
42
44
|
# create client and send
|
|
43
|
-
client = Mailtrap::
|
|
45
|
+
client = Mailtrap::Client.new(api_key: 'your-api-key')
|
|
44
46
|
client.send(mail)
|
|
45
47
|
```
|
|
46
48
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
```ruby
|
|
50
|
-
require 'mailtrap'
|
|
51
|
-
require 'base64'
|
|
52
|
-
|
|
53
|
-
mail = Mailtrap::Mail::Base.new(
|
|
54
|
-
from: { email: 'mailtrap@example.com', name: 'Mailtrap Test' },
|
|
55
|
-
to: [
|
|
56
|
-
{ email: 'your@email.com', name: 'Your name' }
|
|
57
|
-
],
|
|
58
|
-
cc: [
|
|
59
|
-
{ email: 'cc@email.com', name: 'Copy To' }
|
|
60
|
-
],
|
|
61
|
-
bcc: [
|
|
62
|
-
{ email: 'bcc@email.com', name: 'Hidden Recipient' }
|
|
63
|
-
],
|
|
64
|
-
subject: 'You are awesome!',
|
|
65
|
-
text: "Congrats for sending test email with Mailtrap!",
|
|
66
|
-
category: "Integration Test",
|
|
67
|
-
attachments: [
|
|
68
|
-
{
|
|
69
|
-
content: Base64.encode64('Attachment content'), # base64 encoded content or IO string
|
|
70
|
-
filename: 'attachment.txt'
|
|
71
|
-
}
|
|
72
|
-
],
|
|
73
|
-
headers: {
|
|
74
|
-
'X-MT-Header': 'Custom header'
|
|
75
|
-
},
|
|
76
|
-
custom_variables: {
|
|
77
|
-
year: 2022
|
|
78
|
-
}
|
|
79
|
-
)
|
|
80
|
-
|
|
81
|
-
data = File.open('/path/to/image.jpg').read
|
|
82
|
-
encoded = Base64.encode64(data).gsub(/\n/,"")
|
|
83
|
-
|
|
84
|
-
mail.add_attachment(content: encoded, filename: 'image.png')
|
|
85
|
-
|
|
86
|
-
client = Mailtrap::Sending::Client.new(api_key: 'your-api-key')
|
|
87
|
-
client.send(mail)
|
|
88
|
-
```
|
|
49
|
+
Refer to the [`examples`](examples) folder for other examples.
|
|
89
50
|
|
|
90
|
-
|
|
51
|
+
- [Full](examples/full.rb)
|
|
52
|
+
- [Email template](examples/email_template.rb)
|
|
53
|
+
- [ActionMailer](examples/action_mailer.rb)
|
|
91
54
|
|
|
92
|
-
|
|
93
|
-
require 'mailtrap'
|
|
55
|
+
### Content-Transfer-Encoding
|
|
94
56
|
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
template_uuid: '2f45b0aa-bbed-432f-95e4-e145e1965ba2',
|
|
102
|
-
template_variables: {
|
|
103
|
-
'user_name' => 'John Doe'
|
|
104
|
-
}
|
|
105
|
-
)
|
|
57
|
+
`mailtrap` gem uses Mailtrap API to send emails. Mailtrap API does not try to
|
|
58
|
+
replicate SMTP. That is why you should expect some limitations when it comes to
|
|
59
|
+
sending. For example, `/api/send` endpoint ignores `Content-Transfer-Encoding`
|
|
60
|
+
(see `headers` in the [API documentation](https://railsware.stoplight.io/docs/mailtrap-api-docs/67f1d70aeb62c-send-email)).
|
|
61
|
+
Meaning your recipients will receive emails only in the default encoding which
|
|
62
|
+
is `quoted-printable`, if you send with Mailtrap API.
|
|
106
63
|
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
64
|
+
For those who does need to use `7bit` or any other encoding, SMTP provides
|
|
65
|
+
better flexibility in that regard. Go to your _Mailtrap account_ → _Email Sending_
|
|
66
|
+
→ _Sending Domains_ → _Your domain_ → _SMTP/API Settings_ to find the SMTP
|
|
67
|
+
configuration example.
|
|
111
68
|
|
|
112
|
-
|
|
69
|
+
## Migration guide v1 → v2
|
|
113
70
|
|
|
114
|
-
|
|
115
|
-
```ruby
|
|
116
|
-
config.action_mailer.delivery_method = :mailtrap
|
|
117
|
-
config.action_mailer.mailtrap_settings = {
|
|
118
|
-
api_key: ENV.fetch('MAILTRAP_API_KEY')
|
|
119
|
-
}
|
|
120
|
-
```
|
|
121
|
-
And continue to use ActionMailer as usual.
|
|
71
|
+
Change `Mailtrap::Sending::Client` to `Mailtrap::Client`.
|
|
122
72
|
|
|
123
|
-
|
|
124
|
-
```ruby
|
|
125
|
-
mail(
|
|
126
|
-
to: 'your@email.com',
|
|
127
|
-
subject: 'You are awesome!',
|
|
128
|
-
category: 'Test category',
|
|
129
|
-
custom_variables: { test_variable: 'abc' }
|
|
130
|
-
)
|
|
131
|
-
```
|
|
73
|
+
If you use classes which have `Sending` namespace, remove the namespace like in the example above.
|
|
132
74
|
|
|
133
75
|
## Development
|
|
134
76
|
|
|
@@ -5,6 +5,8 @@ module Mailtrap
|
|
|
5
5
|
class DeliveryMethod
|
|
6
6
|
attr_accessor :settings
|
|
7
7
|
|
|
8
|
+
ALLOWED_PARAMS = %i[api_key api_host api_port bulk sandbox inbox_id].freeze
|
|
9
|
+
|
|
8
10
|
def initialize(settings)
|
|
9
11
|
self.settings = settings
|
|
10
12
|
end
|
|
@@ -18,7 +20,7 @@ module Mailtrap
|
|
|
18
20
|
private
|
|
19
21
|
|
|
20
22
|
def client
|
|
21
|
-
@client ||= Mailtrap::
|
|
23
|
+
@client ||= Mailtrap::Client.new(**settings.slice(*ALLOWED_PARAMS))
|
|
22
24
|
end
|
|
23
25
|
end
|
|
24
26
|
end
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'base64'
|
|
4
|
+
require 'json'
|
|
5
|
+
|
|
6
|
+
module Mailtrap
|
|
7
|
+
class Attachment
|
|
8
|
+
attr_accessor :type, :filename, :disposition, :content_id
|
|
9
|
+
attr_reader :content
|
|
10
|
+
|
|
11
|
+
def initialize(content:, filename:, type: nil, disposition: nil, content_id: nil)
|
|
12
|
+
self.content = content
|
|
13
|
+
@type = type
|
|
14
|
+
@filename = filename
|
|
15
|
+
@disposition = disposition
|
|
16
|
+
@content_id = content_id
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def as_json
|
|
20
|
+
{
|
|
21
|
+
'content' => content,
|
|
22
|
+
'type' => type,
|
|
23
|
+
'filename' => filename,
|
|
24
|
+
'disposition' => disposition,
|
|
25
|
+
'content_id' => content_id
|
|
26
|
+
}.compact
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def content=(content)
|
|
30
|
+
if content.respond_to?(:read)
|
|
31
|
+
@content = encode(content)
|
|
32
|
+
else
|
|
33
|
+
raise AttachmentContentError unless base64?(content)
|
|
34
|
+
|
|
35
|
+
@content = content
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
private
|
|
40
|
+
|
|
41
|
+
def encode(io)
|
|
42
|
+
string = io.read.encode('UTF-8') unless io.respond_to?(:binmode?) && io.binmode?
|
|
43
|
+
Base64.encode64(string).gsub(/\n/, '')
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def base64?(string)
|
|
47
|
+
string.is_a?(String) && Base64.strict_encode64(Base64.decode64(string)) == string
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'json'
|
|
4
|
+
require 'net/http'
|
|
5
|
+
require 'uri'
|
|
6
|
+
|
|
7
|
+
module Mailtrap
|
|
8
|
+
class Client
|
|
9
|
+
SENDING_API_HOST = 'send.api.mailtrap.io'
|
|
10
|
+
BULK_SENDING_API_HOST = 'bulk.api.mailtrap.io'
|
|
11
|
+
SANDBOX_API_HOST = 'sandbox.api.mailtrap.io'
|
|
12
|
+
API_PORT = 443
|
|
13
|
+
|
|
14
|
+
attr_reader :api_key, :api_host, :api_port, :bulk, :sandbox, :inbox_id
|
|
15
|
+
|
|
16
|
+
# Initializes a new Mailtrap::Client instance.
|
|
17
|
+
#
|
|
18
|
+
# @param [String] api_key The Mailtrap API key to use for sending. Required.
|
|
19
|
+
# If not set, is taken from the MAILTRAP_API_KEY environment variable.
|
|
20
|
+
# @param [String, nil] api_host The Mailtrap API hostname. If not set, is chosen internally.
|
|
21
|
+
# @param [Integer] api_port The Mailtrap API port. Default: 443.
|
|
22
|
+
# @param [Boolean] bulk Whether to use the Mailtrap bulk sending API. Default: false.
|
|
23
|
+
# If enabled, is incompatible with `sandbox: true`.
|
|
24
|
+
# @param [Boolean] sandbox Whether to use the Mailtrap sandbox API. Default: false.
|
|
25
|
+
# If enabled, is incompatible with `bulk: true`.
|
|
26
|
+
# @param [Integer] inbox_id The sandbox inbox ID to send to. Required if sandbox API is used.
|
|
27
|
+
def initialize( # rubocop:disable Metrics/ParameterLists
|
|
28
|
+
api_key: ENV.fetch('MAILTRAP_API_KEY'),
|
|
29
|
+
api_host: nil,
|
|
30
|
+
api_port: API_PORT,
|
|
31
|
+
bulk: false,
|
|
32
|
+
sandbox: false,
|
|
33
|
+
inbox_id: nil
|
|
34
|
+
)
|
|
35
|
+
raise ArgumentError, 'api_key is required' if api_key.nil?
|
|
36
|
+
raise ArgumentError, 'api_port is required' if api_port.nil?
|
|
37
|
+
|
|
38
|
+
api_host ||= select_api_host(bulk: bulk, sandbox: sandbox)
|
|
39
|
+
raise ArgumentError, 'inbox_id is required for sandbox API' if sandbox && inbox_id.nil?
|
|
40
|
+
|
|
41
|
+
@api_key = api_key
|
|
42
|
+
@api_host = api_host
|
|
43
|
+
@api_port = api_port
|
|
44
|
+
@bulk = bulk
|
|
45
|
+
@sandbox = sandbox
|
|
46
|
+
@inbox_id = inbox_id
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def send(mail)
|
|
50
|
+
raise ArgumentError, 'should be Mailtrap::Mail::Base object' unless mail.is_a? Mail::Base
|
|
51
|
+
|
|
52
|
+
request = post_request(request_url, mail.to_json)
|
|
53
|
+
response = http_client.request(request)
|
|
54
|
+
|
|
55
|
+
handle_response(response)
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
private
|
|
59
|
+
|
|
60
|
+
def select_api_host(bulk:, sandbox:)
|
|
61
|
+
raise ArgumentError, 'bulk mode is not applicable for sandbox API' if bulk && sandbox
|
|
62
|
+
|
|
63
|
+
if sandbox
|
|
64
|
+
SANDBOX_API_HOST
|
|
65
|
+
elsif bulk
|
|
66
|
+
BULK_SENDING_API_HOST
|
|
67
|
+
else
|
|
68
|
+
SENDING_API_HOST
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def request_url
|
|
73
|
+
"/api/send#{sandbox ? "/#{inbox_id}" : ""}"
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
def http_client
|
|
77
|
+
@http_client ||= Net::HTTP.new(api_host, api_port).tap { |client| client.use_ssl = true }
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
def post_request(path, body)
|
|
81
|
+
request = Net::HTTP::Post.new(path)
|
|
82
|
+
request.body = body
|
|
83
|
+
request['Authorization'] = "Bearer #{api_key}"
|
|
84
|
+
request['Content-Type'] = 'application/json'
|
|
85
|
+
request['User-Agent'] = 'mailtrap-ruby (https://github.com/railsware/mailtrap-ruby)'
|
|
86
|
+
|
|
87
|
+
request
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
def handle_response(response) # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength
|
|
91
|
+
case response
|
|
92
|
+
when Net::HTTPOK
|
|
93
|
+
json_response(response.body)
|
|
94
|
+
when Net::HTTPBadRequest
|
|
95
|
+
raise Mailtrap::Error, json_response(response.body)[:errors]
|
|
96
|
+
when Net::HTTPUnauthorized
|
|
97
|
+
raise Mailtrap::AuthorizationError, json_response(response.body)[:errors]
|
|
98
|
+
when Net::HTTPForbidden
|
|
99
|
+
raise Mailtrap::RejectionError, json_response(response.body)[:errors]
|
|
100
|
+
when Net::HTTPPayloadTooLarge
|
|
101
|
+
raise Mailtrap::MailSizeError, ['message too large']
|
|
102
|
+
when Net::HTTPTooManyRequests
|
|
103
|
+
raise Mailtrap::RateLimitError, ['too many requests']
|
|
104
|
+
when Net::HTTPClientError
|
|
105
|
+
raise Mailtrap::Error, ['client error']
|
|
106
|
+
when Net::HTTPServerError
|
|
107
|
+
raise Mailtrap::Error, ['server error']
|
|
108
|
+
else
|
|
109
|
+
raise Mailtrap::Error, ["unexpected status code=#{response.code}"]
|
|
110
|
+
end
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
def json_response(body)
|
|
114
|
+
JSON.parse(body, symbolize_names: true)
|
|
115
|
+
end
|
|
116
|
+
end
|
|
117
|
+
end
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative 'attachment'
|
|
4
|
+
require_relative 'client'
|
|
5
|
+
|
|
6
|
+
module Mailtrap
|
|
7
|
+
class AttachmentContentError < StandardError; end
|
|
8
|
+
|
|
9
|
+
class Error < StandardError
|
|
10
|
+
attr_reader :messages
|
|
11
|
+
|
|
12
|
+
def initialize(messages)
|
|
13
|
+
@messages = messages
|
|
14
|
+
|
|
15
|
+
super(messages.join(', '))
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
# AuthorizationError is raised when invalid token is used.
|
|
20
|
+
class AuthorizationError < Error; end
|
|
21
|
+
|
|
22
|
+
# MailSizeError is raised when mail is too large.
|
|
23
|
+
class MailSizeError < Error; end
|
|
24
|
+
|
|
25
|
+
# RateLimitError is raised when client performing too many requests.
|
|
26
|
+
class RateLimitError < Error; end
|
|
27
|
+
|
|
28
|
+
# RejectionError is raised when server refuses to process the request. Use
|
|
29
|
+
# error message to debug the problem.
|
|
30
|
+
#
|
|
31
|
+
# *Some* possible reasons:
|
|
32
|
+
# * Account is banned
|
|
33
|
+
# * Domain is not verified
|
|
34
|
+
class RejectionError < Error; end
|
|
35
|
+
end
|
data/lib/mailtrap/mail/base.rb
CHANGED
|
@@ -59,11 +59,11 @@ module Mailtrap
|
|
|
59
59
|
end
|
|
60
60
|
|
|
61
61
|
def attachments=(attachments)
|
|
62
|
-
@attachments = attachments.map { |attachment| Mailtrap::
|
|
62
|
+
@attachments = attachments.map { |attachment| Mailtrap::Attachment.new(**attachment) }
|
|
63
63
|
end
|
|
64
64
|
|
|
65
65
|
def add_attachment(content:, filename:, type: nil, disposition: nil, content_id: nil)
|
|
66
|
-
attachment = Mailtrap::
|
|
66
|
+
attachment = Mailtrap::Attachment.new(
|
|
67
67
|
content: content,
|
|
68
68
|
filename: filename,
|
|
69
69
|
type: type,
|
data/lib/mailtrap/version.rb
CHANGED
data/lib/mailtrap.rb
CHANGED
data/mailtrap.gemspec
CHANGED
|
@@ -23,7 +23,9 @@ Gem::Specification.new do |spec|
|
|
|
23
23
|
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
|
24
24
|
spec.files = Dir.chdir(File.expand_path(__dir__)) do
|
|
25
25
|
`git ls-files -z`.split("\x0").reject do |f|
|
|
26
|
-
(f == __FILE__) || f.match(
|
|
26
|
+
(f == __FILE__) || f.match(
|
|
27
|
+
%r{\A(?:(?:bin|test|spec|features|examples)/|\.(?:git|github|travis|circleci)|appveyor)}
|
|
28
|
+
)
|
|
27
29
|
end
|
|
28
30
|
end
|
|
29
31
|
spec.require_paths = ['lib']
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: mailtrap
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version:
|
|
4
|
+
version: 2.0.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Railsware Products Studio LLC
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date:
|
|
11
|
+
date: 2024-03-28 00:00:00.000000000 Z
|
|
12
12
|
dependencies: []
|
|
13
13
|
description: Official mailtrap.io API client
|
|
14
14
|
email:
|
|
@@ -32,12 +32,12 @@ files:
|
|
|
32
32
|
- lib/mailtrap/action_mailer.rb
|
|
33
33
|
- lib/mailtrap/action_mailer/delivery_method.rb
|
|
34
34
|
- lib/mailtrap/action_mailer/railtie.rb
|
|
35
|
+
- lib/mailtrap/attachment.rb
|
|
36
|
+
- lib/mailtrap/client.rb
|
|
37
|
+
- lib/mailtrap/errors.rb
|
|
35
38
|
- lib/mailtrap/mail.rb
|
|
36
39
|
- lib/mailtrap/mail/base.rb
|
|
37
40
|
- lib/mailtrap/mail/from_template.rb
|
|
38
|
-
- lib/mailtrap/sending.rb
|
|
39
|
-
- lib/mailtrap/sending/attachment.rb
|
|
40
|
-
- lib/mailtrap/sending/client.rb
|
|
41
41
|
- lib/mailtrap/version.rb
|
|
42
42
|
- mailtrap.gemspec
|
|
43
43
|
homepage: https://github.com/railsware/mailtrap-ruby
|
|
@@ -63,7 +63,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
63
63
|
- !ruby/object:Gem::Version
|
|
64
64
|
version: '0'
|
|
65
65
|
requirements: []
|
|
66
|
-
rubygems_version: 3.
|
|
66
|
+
rubygems_version: 3.4.10
|
|
67
67
|
signing_key:
|
|
68
68
|
specification_version: 4
|
|
69
69
|
summary: Official mailtrap.io API client
|
|
@@ -1,52 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require 'base64'
|
|
4
|
-
require 'json'
|
|
5
|
-
|
|
6
|
-
module Mailtrap
|
|
7
|
-
module Sending
|
|
8
|
-
class Attachment
|
|
9
|
-
attr_accessor :type, :filename, :disposition, :content_id
|
|
10
|
-
attr_reader :content
|
|
11
|
-
|
|
12
|
-
def initialize(content:, filename:, type: nil, disposition: nil, content_id: nil)
|
|
13
|
-
self.content = content
|
|
14
|
-
@type = type
|
|
15
|
-
@filename = filename
|
|
16
|
-
@disposition = disposition
|
|
17
|
-
@content_id = content_id
|
|
18
|
-
end
|
|
19
|
-
|
|
20
|
-
def as_json
|
|
21
|
-
{
|
|
22
|
-
'content' => content,
|
|
23
|
-
'type' => type,
|
|
24
|
-
'filename' => filename,
|
|
25
|
-
'disposition' => disposition,
|
|
26
|
-
'content_id' => content_id
|
|
27
|
-
}.compact
|
|
28
|
-
end
|
|
29
|
-
|
|
30
|
-
def content=(content)
|
|
31
|
-
if content.respond_to?(:read)
|
|
32
|
-
@content = encode(content)
|
|
33
|
-
else
|
|
34
|
-
raise AttachmentContentError unless base64?(content)
|
|
35
|
-
|
|
36
|
-
@content = content
|
|
37
|
-
end
|
|
38
|
-
end
|
|
39
|
-
|
|
40
|
-
private
|
|
41
|
-
|
|
42
|
-
def encode(io)
|
|
43
|
-
string = io.read.encode('UTF-8') unless io.respond_to?(:binmode?) && io.binmode?
|
|
44
|
-
Base64.encode64(string).gsub(/\n/, '')
|
|
45
|
-
end
|
|
46
|
-
|
|
47
|
-
def base64?(string)
|
|
48
|
-
string.is_a?(String) && Base64.strict_encode64(Base64.decode64(string)) == string
|
|
49
|
-
end
|
|
50
|
-
end
|
|
51
|
-
end
|
|
52
|
-
end
|
|
@@ -1,64 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require 'json'
|
|
4
|
-
require 'net/http'
|
|
5
|
-
require 'uri'
|
|
6
|
-
|
|
7
|
-
module Mailtrap
|
|
8
|
-
module Sending
|
|
9
|
-
class Client
|
|
10
|
-
API_HOST = 'send.api.mailtrap.io'
|
|
11
|
-
API_PORT = 443
|
|
12
|
-
|
|
13
|
-
attr_reader :api_key, :api_host, :api_port
|
|
14
|
-
|
|
15
|
-
def initialize(api_key: ENV.fetch('MAILTRAP_API_KEY'), api_host: API_HOST, api_port: API_PORT)
|
|
16
|
-
@api_key = api_key
|
|
17
|
-
@api_host = api_host
|
|
18
|
-
@api_port = api_port
|
|
19
|
-
end
|
|
20
|
-
|
|
21
|
-
def send(mail)
|
|
22
|
-
raise ArgumentError, 'should be Mailtrap::Mail::Base object' unless mail.is_a? Mail::Base
|
|
23
|
-
|
|
24
|
-
request = post_request('/api/send', mail.to_json)
|
|
25
|
-
response = http_client.request(request)
|
|
26
|
-
|
|
27
|
-
handle_response(response)
|
|
28
|
-
end
|
|
29
|
-
|
|
30
|
-
private
|
|
31
|
-
|
|
32
|
-
def http_client
|
|
33
|
-
@http_client ||= Net::HTTP.new(api_host, api_port).tap { |client| client.use_ssl = true }
|
|
34
|
-
end
|
|
35
|
-
|
|
36
|
-
def post_request(path, body)
|
|
37
|
-
request = Net::HTTP::Post.new(path)
|
|
38
|
-
request.body = body
|
|
39
|
-
request['Authorization'] = "Bearer #{api_key}"
|
|
40
|
-
request['Content-Type'] = 'application/json'
|
|
41
|
-
request['User-Agent'] = 'mailtrap-ruby (https://github.com/railsware/mailtrap-ruby)'
|
|
42
|
-
|
|
43
|
-
request
|
|
44
|
-
end
|
|
45
|
-
|
|
46
|
-
def handle_response(response)
|
|
47
|
-
case response.code
|
|
48
|
-
when '200'
|
|
49
|
-
json_response(response.body)
|
|
50
|
-
when '400'
|
|
51
|
-
raise Mailtrap::Sending::Error, json_response(response.body)[:errors]
|
|
52
|
-
when '401'
|
|
53
|
-
raise Mailtrap::Sending::AuthorizationError, json_response(response.body)[:errors]
|
|
54
|
-
else
|
|
55
|
-
raise Mailtrap::Sending::Error, ['server error']
|
|
56
|
-
end
|
|
57
|
-
end
|
|
58
|
-
|
|
59
|
-
def json_response(body)
|
|
60
|
-
JSON.parse(body, symbolize_names: true)
|
|
61
|
-
end
|
|
62
|
-
end
|
|
63
|
-
end
|
|
64
|
-
end
|
data/lib/mailtrap/sending.rb
DELETED
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require_relative 'sending/attachment'
|
|
4
|
-
require_relative 'sending/client'
|
|
5
|
-
|
|
6
|
-
module Mailtrap
|
|
7
|
-
module Sending
|
|
8
|
-
class AttachmentContentError < StandardError; end
|
|
9
|
-
|
|
10
|
-
class Error < StandardError
|
|
11
|
-
attr_reader :messages
|
|
12
|
-
|
|
13
|
-
def initialize(messages)
|
|
14
|
-
@messages = messages
|
|
15
|
-
|
|
16
|
-
super(messages.join(', '))
|
|
17
|
-
end
|
|
18
|
-
end
|
|
19
|
-
|
|
20
|
-
class AuthorizationError < Error; end
|
|
21
|
-
end
|
|
22
|
-
end
|