mail-ses 0.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 +7 -0
- data/CHANGELOG.md +4 -0
- data/LICENSE +22 -0
- data/README.md +121 -0
- data/VERSION +1 -0
- data/lib/mail-ses.rb +4 -0
- data/lib/mail/ses.rb +87 -0
- data/spec/mail_ses_spec.rb +167 -0
- data/spec/spec_helper.rb +18 -0
- metadata +123 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: a729c8707418afffdc7f0c411a4f92b66d236db4ed0d1e41940c1ab00cecdb6c
|
4
|
+
data.tar.gz: 45fd00d6204d3dd2764b78f5ee250f4cbf17f01a4dd6cf8671d9d55530eb9f68
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: aaddce5f599c511aa774e9d8daba34e2142b88ebcee3048cbcac32c5e5c09ea653e627fc0087ea76f5086e3a6de40b881a7de46b79336b523ff7a466674faffa
|
7
|
+
data.tar.gz: 89973fc7a007b2058e5c33f819519b06e8962e93439880799d74454ed6b52ca86dafef7adfffccd745c8fe3b70f4fcb05a66dec5b763f2c12783e1c032cbe017
|
data/CHANGELOG.md
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2018 TableCheck Inc.
|
2
|
+
|
3
|
+
AWS::SES originally copyright (c) 2011 Drew V. Blas <drew.blas@gmail.com>
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,121 @@
|
|
1
|
+
[](http://badge.fury.io/rb/mail-ses)
|
2
|
+
[](https://travis-ci.org/tablecheck/mail-ses)
|
3
|
+
|
4
|
+
# Mail::SES
|
5
|
+
|
6
|
+
Mail::SES is a mail delivery method handler for Amazon SES (Simple Email Service) which can be used with Rails' [Action Mailer](https://guides.rubyonrails.org/action_mailer_basics.html).
|
7
|
+
|
8
|
+
This gem is inspired by [Drew Blas' AWS::SES gem](https://github.com/drewblas/aws-ses),
|
9
|
+
but uses the official [AWS SDK v3 for SES](https://docs.aws.amazon.com/ses/latest/DeveloperGuide/send-using-sdk-ruby.html) under-the-hood.
|
10
|
+
By passing parameters through to the SDK, this gem supports greater flexibility with less code (including IAM instance profiles, retry parameters, etc.)
|
11
|
+
|
12
|
+
### Compatibility
|
13
|
+
|
14
|
+
* TBD
|
15
|
+
|
16
|
+
### Shameless Plug
|
17
|
+
|
18
|
+
ActionMailer::SES is sponsored by [TableCheck](http://corp.tablecheck.com/), Japan's leading restaurant management app. If **you** are a ninja-level Javascript/Ruby coder, designer, project manager, etc. and are eager to work in Tokyo with other ninjas, Japan in a dynamic environment, please get in touch at [careers@tablecheck.com](mailto:careers@tablecheck.com).
|
19
|
+
|
20
|
+
## Getting Started
|
21
|
+
|
22
|
+
In your `Gemfile`:
|
23
|
+
|
24
|
+
```ruby
|
25
|
+
gem 'mail-ses'
|
26
|
+
```
|
27
|
+
|
28
|
+
Next, make a new initializer at `config/initializers/mail_ses.rb`:
|
29
|
+
|
30
|
+
```ruby
|
31
|
+
ActionMailer::Base.add_delivery_method :ses, Mail::SES,
|
32
|
+
region: 'us-east-1',
|
33
|
+
access_key_id: 'abc',
|
34
|
+
secret_access_key: '123'
|
35
|
+
```
|
36
|
+
|
37
|
+
Finally, in the appropriate `config/environments/*.rb`:
|
38
|
+
|
39
|
+
```ruby
|
40
|
+
config.action_mailer.delivery_method = :ses
|
41
|
+
```
|
42
|
+
|
43
|
+
## Advanced Usage
|
44
|
+
|
45
|
+
### AWS SES Client Options
|
46
|
+
|
47
|
+
Any options supported by the `Aws::SES::Client` class can be passed into the initializer, for example:
|
48
|
+
|
49
|
+
```ruby
|
50
|
+
ActionMailer::Base.add_delivery_method :ses, Mail::SES,
|
51
|
+
region: 'us-east-1',
|
52
|
+
session_token: 'foobar',
|
53
|
+
retry_limit: 5,
|
54
|
+
retry_max_delay: 10
|
55
|
+
```
|
56
|
+
|
57
|
+
In addition, the shortcut option `:use_iam_profile (Boolean)` which activates the IAM instance profile.
|
58
|
+
|
59
|
+
```ruby
|
60
|
+
ActionMailer::Base.add_delivery_method :ses, Mail::SES,
|
61
|
+
region: 'us-east-1',
|
62
|
+
use_iam_profile: true
|
63
|
+
```
|
64
|
+
|
65
|
+
### Default Mail Options
|
66
|
+
|
67
|
+
In the initializer you can set `:mail_options (Hash)` which are default options to pass-through to each mail sent:
|
68
|
+
|
69
|
+
```ruby
|
70
|
+
ActionMailer::Base.add_delivery_method :ses, Mail::SES,
|
71
|
+
# ...
|
72
|
+
mail_options: {
|
73
|
+
source_arn: 'arn:aws:ses:us-east-1:123456789012:identity/example.com',
|
74
|
+
tags: [
|
75
|
+
{ name: 'MessageTagName', value: 'MessageTagValue' },
|
76
|
+
],
|
77
|
+
}
|
78
|
+
```
|
79
|
+
|
80
|
+
### AWS Error Handling
|
81
|
+
|
82
|
+
To handle errors from AWS API, in the initializer you can set `:error_handler (Proc)` which takes two args:
|
83
|
+
the error which was raised, and the raw_email options hash. This is useful for notifying your bug tracking service.
|
84
|
+
Setting `:error_handler` causes the error to be swallowed unless it is raised again in the handler itself.
|
85
|
+
|
86
|
+
```ruby
|
87
|
+
ActionMailer::Base.add_delivery_method :ses, Mail::SES,
|
88
|
+
# ...
|
89
|
+
error_handler: ->(error, raw_email) do
|
90
|
+
Bugsnag.notify(error){|r| r.add_tab('email', { email: raw_email })}
|
91
|
+
raise error
|
92
|
+
end
|
93
|
+
```
|
94
|
+
|
95
|
+
### Send Email as a Standalone
|
96
|
+
|
97
|
+
You can send one-off mails using the `Mail::SES` object and `#deliver` method.
|
98
|
+
|
99
|
+
```ruby
|
100
|
+
mail = Mail.new(args)
|
101
|
+
|
102
|
+
ses = Mail::SES.new(region: 'us-east-1',
|
103
|
+
access_key_id: 'abc',
|
104
|
+
secret_access_key: '123')
|
105
|
+
|
106
|
+
options = { source_arn: 'arn:aws:ses:us-east-1:123456789012:identity/example.com' }
|
107
|
+
|
108
|
+
ses.deliver!(mail, options) #=> returns AWS API response
|
109
|
+
|
110
|
+
mail.message_id #=> "00000138111222aa-33322211-cccc-cccc-cccc-ddddaaaa0680-000000@email.amazonses.com"
|
111
|
+
```
|
112
|
+
|
113
|
+
Please also see the [AWS SDK v3 for SES](https://docs.aws.amazon.com/ses/latest/DeveloperGuide/send-using-sdk-ruby.html) for alternate approaches.
|
114
|
+
|
115
|
+
## Statistics, Verified Addresses, Bounce Rate, etc.
|
116
|
+
|
117
|
+
Please use the official [AWS SDK v3 for SES](https://docs.aws.amazon.com/ses/latest/DeveloperGuide/send-using-sdk-ruby.html).
|
118
|
+
|
119
|
+
## Copyright
|
120
|
+
|
121
|
+
Copyright (c) 2018 TableCheck Inc. See LICENSE for further details.
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.1.0
|
data/lib/mail-ses.rb
ADDED
data/lib/mail/ses.rb
ADDED
@@ -0,0 +1,87 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
module Mail
|
3
|
+
# Mail delivery method handler for AWS SES
|
4
|
+
class SES
|
5
|
+
VERSION = File.read(File.join(File.dirname(__FILE__), '../../VERSION')).strip.freeze
|
6
|
+
|
7
|
+
RAW_EMAIL_ATTRS = %i[ source
|
8
|
+
source_arn
|
9
|
+
from_arn
|
10
|
+
return_path_arn
|
11
|
+
tags
|
12
|
+
configuration_set_name ].freeze
|
13
|
+
|
14
|
+
attr_reader :client
|
15
|
+
|
16
|
+
# Initializes the Mail::SES object.
|
17
|
+
#
|
18
|
+
# options - The Hash options (optional, default: {}):
|
19
|
+
# :mail_options - (Hash) Default AWS options to set on each mail object.
|
20
|
+
# :error_handler - (Proc<Error, Hash>) Handler for AWS API errors.
|
21
|
+
# :use_iam_profile - Shortcut to use AWS IAM instance profile.
|
22
|
+
# All other options are passed-thru to Aws::SES::Client.
|
23
|
+
def initialize(options = {})
|
24
|
+
@mail_options = options.delete(:mail_options) || {}
|
25
|
+
@error_handler = options.delete(:error_handler)
|
26
|
+
self.class.validate_error_handler(@error_handler)
|
27
|
+
options = self.class.build_client_options(options)
|
28
|
+
@client = Aws::SES::Client.new(options)
|
29
|
+
end
|
30
|
+
|
31
|
+
# Delivers a Mail object via SES.
|
32
|
+
#
|
33
|
+
# mail - The Mail object to deliver (required).
|
34
|
+
# options - The Hash options which override any defaults set in :mail_options
|
35
|
+
# in the initializer (optional, default: {}). Refer to
|
36
|
+
# Aws::SES::Client#send_raw_email
|
37
|
+
def deliver!(mail, options = {})
|
38
|
+
self.class.validate_mail(mail)
|
39
|
+
options = @mail_options.merge(options || {})
|
40
|
+
raw_email_options = self.class.build_raw_email_options(mail, options)
|
41
|
+
begin
|
42
|
+
response = client.send_raw_email(raw_email_options)
|
43
|
+
mail.message_id = "#{response.to_h[:message_id]}@email.amazonses.com"
|
44
|
+
response
|
45
|
+
rescue StandardError => e
|
46
|
+
@error_handler ? @error_handler.call(e, raw_email_options.dup) : raise(e)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
class << self
|
51
|
+
def validate_error_handler(error_handler)
|
52
|
+
raise ArgumentError.new(':error_handler must be a Proc') if error_handler && !error_handler.is_a?(Proc)
|
53
|
+
end
|
54
|
+
|
55
|
+
def validate_mail(mail)
|
56
|
+
unless mail.is_a?(Mail::Message)
|
57
|
+
raise ArgumentError.new('mail must be an instance of Mail::Message class')
|
58
|
+
end
|
59
|
+
|
60
|
+
Mail::CheckDeliveryParams.check(mail)
|
61
|
+
|
62
|
+
if mail.has_attachments? && mail.text_part.nil? && mail.html_part.nil?
|
63
|
+
raise ArgumentError.new('Attachment provided without message body')
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
def build_client_options(options)
|
68
|
+
options[:credentials] = Aws::InstanceProfileCredentials.new if options.delete(:use_iam_profile)
|
69
|
+
options
|
70
|
+
end
|
71
|
+
|
72
|
+
def build_raw_email_options(message, options = {})
|
73
|
+
output = slice_hash(options, *RAW_EMAIL_ATTRS)
|
74
|
+
output[:source] ||= message.from.first
|
75
|
+
output[:destinations] = [message.to, message.cc, message.bcc].flatten.compact
|
76
|
+
output[:raw_message] = { data: Base64.encode64(message.to_s) }
|
77
|
+
output
|
78
|
+
end
|
79
|
+
|
80
|
+
protected
|
81
|
+
|
82
|
+
def slice_hash(hash, *keys)
|
83
|
+
keys.each_with_object({}) { |k, h| h[k] = hash[k] if hash.key?(k) }
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
@@ -0,0 +1,167 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require 'spec_helper'
|
3
|
+
|
4
|
+
RSpec.describe Mail::SES do
|
5
|
+
let(:ses_options) { { stub_responses: true } }
|
6
|
+
|
7
|
+
let(:ses) do
|
8
|
+
described_class.new(ses_options)
|
9
|
+
end
|
10
|
+
|
11
|
+
let(:mail) do
|
12
|
+
Mail.new do
|
13
|
+
from 'from@abc.com'
|
14
|
+
to %w[to1@def.com to2@xyz.com]
|
15
|
+
cc %w[cc1@xyz.com cc2@def.com]
|
16
|
+
bcc %w[bcc1@abc.com bcc2@def.com]
|
17
|
+
body 'This is the body'
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
describe '::VERSION' do
|
22
|
+
it { expect(described_class::VERSION).to match(/\A\d+\.\d+\.\d+/) }
|
23
|
+
end
|
24
|
+
|
25
|
+
describe '#initialize' do
|
26
|
+
it 'accepts valid :error_handler' do
|
27
|
+
expect(described_class.new(ses_options)).to be_a(Mail::SES)
|
28
|
+
end
|
29
|
+
|
30
|
+
it 'accepts valid :error_handler' do
|
31
|
+
expect(described_class.new(ses_options.merge(error_handler: ->(a, b) {}))).to be_a(Mail::SES)
|
32
|
+
end
|
33
|
+
|
34
|
+
it 'rejects invalid :error_handler' do
|
35
|
+
expect { described_class.new(ses_options.merge(error_handler: 'foobar')) }.to raise_error(ArgumentError, ':error_handler must be a Proc')
|
36
|
+
end
|
37
|
+
|
38
|
+
it 'handles :use_iam_profile option' do
|
39
|
+
allow_any_instance_of(Aws::InstanceProfileCredentials).to receive(:get_credentials).and_return('{}')
|
40
|
+
ses = described_class.new(ses_options.merge(use_iam_profile: true))
|
41
|
+
expect(ses.client.config.credentials).to be_a(Aws::InstanceProfileCredentials)
|
42
|
+
end
|
43
|
+
|
44
|
+
it 'passes through options to AWS' do
|
45
|
+
ses = described_class.new(ses_options.merge(log_level: :debug, retry_limit: 5))
|
46
|
+
expect(ses.client.config.log_level).to eq :debug
|
47
|
+
expect(ses.client.config.retry_limit).to eq 5
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
describe '#deliver!' do
|
52
|
+
it 'validates that mail is a Mail' do
|
53
|
+
expect { ses.deliver!(foo: :bar) }.to raise_error(ArgumentError, 'mail must be an instance of Mail::Message class')
|
54
|
+
end
|
55
|
+
|
56
|
+
it 'validates integrity of Mail' do
|
57
|
+
expect { ses.deliver!(Mail.new) }.to raise_error(ArgumentError, 'SMTP From address may not be blank: nil')
|
58
|
+
expect { ses.deliver!(Mail.new { from 'foo@bar.com' }) }.to raise_error(ArgumentError, 'SMTP To address may not be blank: []')
|
59
|
+
end
|
60
|
+
|
61
|
+
it 'validates attachment without body' do
|
62
|
+
mail.body = nil
|
63
|
+
mail.add_file __FILE__
|
64
|
+
expect { ses.deliver!(mail) }.to raise_error(ArgumentError, 'Attachment provided without message body')
|
65
|
+
end
|
66
|
+
|
67
|
+
context 'when options set' do
|
68
|
+
before { allow_any_instance_of(Mail::Message).to receive(:to_s).and_return('Fixed message body') }
|
69
|
+
let(:ses_options) { { stub_responses: true, mail_options: { source: 'foo@bar.com', source_arn: 'sa1' } } }
|
70
|
+
|
71
|
+
let(:exp) do
|
72
|
+
{
|
73
|
+
source: 'foo@bar.com',
|
74
|
+
source_arn: 'sa2',
|
75
|
+
destinations: %w[to1@def.com to2@xyz.com cc1@xyz.com cc2@def.com bcc1@abc.com bcc2@def.com],
|
76
|
+
raw_message: {
|
77
|
+
data: "Rml4ZWQgbWVzc2FnZSBib2R5\n"
|
78
|
+
}
|
79
|
+
}
|
80
|
+
end
|
81
|
+
|
82
|
+
it 'allows pass-thru and override of default options' do
|
83
|
+
expect(ses.client).to receive(:send_raw_email).with(exp)
|
84
|
+
ses.deliver!(mail, source_arn: 'sa2')
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
it 'sets mail.message_id' do
|
89
|
+
ses.deliver!(mail)
|
90
|
+
expect(mail.message_id).to eq('MessageId@email.amazonses.com')
|
91
|
+
end
|
92
|
+
|
93
|
+
it 'returns the AWS response' do
|
94
|
+
expect(ses.deliver!(mail)).to be_a(Seahorse::Client::Response)
|
95
|
+
end
|
96
|
+
|
97
|
+
context 'error handling' do
|
98
|
+
before { allow_any_instance_of(Aws::SES::Client).to receive(:send_raw_email).and_raise(RuntimeError.new('test')) }
|
99
|
+
|
100
|
+
context 'when :error_handler not set' do
|
101
|
+
it 'raises the error' do
|
102
|
+
expect { ses.deliver!(mail) }.to raise_error(RuntimeError, 'test')
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
context 'when :error_handler set' do
|
107
|
+
let(:ses_options) { { stub_responses: true, error_handler: ->(a, b) {} } }
|
108
|
+
|
109
|
+
it 'calls the error handler' do
|
110
|
+
expect(ses_options[:error_handler]).to receive(:call).and_call_original
|
111
|
+
ses.deliver!(mail)
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
describe '::build_raw_email_options' do
|
118
|
+
let(:options) { {} }
|
119
|
+
subject { described_class.build_raw_email_options(mail, options) }
|
120
|
+
before { allow_any_instance_of(Mail::Message).to receive(:to_s).and_return('Fixed message body') }
|
121
|
+
|
122
|
+
context 'without options' do
|
123
|
+
let(:exp) do
|
124
|
+
{
|
125
|
+
source: 'from@abc.com',
|
126
|
+
destinations: %w[to1@def.com to2@xyz.com cc1@xyz.com cc2@def.com bcc1@abc.com bcc2@def.com],
|
127
|
+
raw_message: {
|
128
|
+
data: "Rml4ZWQgbWVzc2FnZSBib2R5\n"
|
129
|
+
}
|
130
|
+
}
|
131
|
+
end
|
132
|
+
|
133
|
+
it { expect(subject).to eq(exp) }
|
134
|
+
end
|
135
|
+
|
136
|
+
context 'with options' do
|
137
|
+
let(:options) do
|
138
|
+
{ source: 'source@source.com',
|
139
|
+
source_arn: 'source_arn',
|
140
|
+
from_arn: 'from_arn',
|
141
|
+
return_path_arn: 'return_path_arn',
|
142
|
+
tags: [{ name: 'Name', value: 'Value' }],
|
143
|
+
configuration_set_name: 'configuration_set_name',
|
144
|
+
other: 'other' }
|
145
|
+
end
|
146
|
+
|
147
|
+
let(:exp) do
|
148
|
+
{
|
149
|
+
source: 'source@source.com',
|
150
|
+
source_arn: 'source_arn',
|
151
|
+
from_arn: 'from_arn',
|
152
|
+
return_path_arn: 'return_path_arn',
|
153
|
+
tags: [
|
154
|
+
{ name: 'Name', value: 'Value' }
|
155
|
+
],
|
156
|
+
configuration_set_name: 'configuration_set_name',
|
157
|
+
destinations: %w[to1@def.com to2@xyz.com cc1@xyz.com cc2@def.com bcc1@abc.com bcc2@def.com],
|
158
|
+
raw_message: {
|
159
|
+
data: "Rml4ZWQgbWVzc2FnZSBib2R5\n"
|
160
|
+
}
|
161
|
+
}
|
162
|
+
end
|
163
|
+
|
164
|
+
it { expect(subject).to eq(exp) }
|
165
|
+
end
|
166
|
+
end
|
167
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require 'rubygems'
|
3
|
+
require 'bundler/setup'
|
4
|
+
require 'rspec'
|
5
|
+
|
6
|
+
Bundler.setup
|
7
|
+
|
8
|
+
require 'mail-ses'
|
9
|
+
|
10
|
+
RSpec.configure do |config|
|
11
|
+
config.disable_monkey_patching!
|
12
|
+
|
13
|
+
config.default_formatter = 'doc' if config.files_to_run.one?
|
14
|
+
|
15
|
+
config.order = :random
|
16
|
+
|
17
|
+
Kernel.srand config.seed
|
18
|
+
end
|
metadata
ADDED
@@ -0,0 +1,123 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: mail-ses
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Johnny Shields
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2018-08-17 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: aws-sdk-ses
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.8'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.8'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: mail
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 2.2.5
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: 2.2.5
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rake
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '1'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '1'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rspec
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '3.8'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '3.8'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: rubocop
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: 0.57.0
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: 0.57.0
|
83
|
+
description: Ruby Mail delivery method handler for Amazon SES
|
84
|
+
email: info@tablecheck.com
|
85
|
+
executables: []
|
86
|
+
extensions: []
|
87
|
+
extra_rdoc_files: []
|
88
|
+
files:
|
89
|
+
- CHANGELOG.md
|
90
|
+
- LICENSE
|
91
|
+
- README.md
|
92
|
+
- VERSION
|
93
|
+
- lib/mail-ses.rb
|
94
|
+
- lib/mail/ses.rb
|
95
|
+
- spec/mail_ses_spec.rb
|
96
|
+
- spec/spec_helper.rb
|
97
|
+
homepage: https://github.com/tablecheck/mail-ses
|
98
|
+
licenses:
|
99
|
+
- MIT
|
100
|
+
metadata: {}
|
101
|
+
post_install_message:
|
102
|
+
rdoc_options: []
|
103
|
+
require_paths:
|
104
|
+
- lib
|
105
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
106
|
+
requirements:
|
107
|
+
- - ">="
|
108
|
+
- !ruby/object:Gem::Version
|
109
|
+
version: '0'
|
110
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
111
|
+
requirements:
|
112
|
+
- - ">="
|
113
|
+
- !ruby/object:Gem::Version
|
114
|
+
version: '0'
|
115
|
+
requirements: []
|
116
|
+
rubyforge_project:
|
117
|
+
rubygems_version: 2.7.3
|
118
|
+
signing_key:
|
119
|
+
specification_version: 4
|
120
|
+
summary: Ruby Mail delivery method handler for Amazon SES
|
121
|
+
test_files:
|
122
|
+
- spec/mail_ses_spec.rb
|
123
|
+
- spec/spec_helper.rb
|