Skip to content

Commit 7fb40c4

Browse files
authored
Relocate ActionMailer and deprecate its railtie method (#159)
1 parent 4476f96 commit 7fb40c4

28 files changed

+165
-353
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,10 @@ Unreleased Changes
1919

2020
* Issue - Do not skip autoload modules for `Aws::Rails.instrument_sdk_operations`.
2121

22+
* Issue - Add deprecation warning to `Aws::Rails.add_action_mailer_delivery_method` to instead use `ActionMailer::Base.add_delivery_method`.
23+
24+
* Feature - New namespace and class names for SES and SESV2 mailers. Existing namespace has temporarily been kept for backward compatibility. These now live in the `aws-actionmailer-ses` gem.
25+
2226
4.1.0 (2024-09-27)
2327
------------------
2428

Gemfile

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ source 'https://rubygems.org'
44

55
gemspec
66

7+
gem 'aws-actionmailer-ses', git: 'https://github.com/aws/aws-actionmailer-ses-ruby'
8+
79
group :development, :test do
810
gem 'pry'
911
end

README.md

Lines changed: 15 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -202,14 +202,24 @@ use the provided Rake task:
202202
rake dynamo_db:session_store:clean
203203
```
204204

205-
## Amazon Simple Email Service (SES) as an ActionMailer Delivery Method
205+
## ActionMailer delivery with Amazon Simple Email Service
206206

207-
This gem will automatically register SES and SESV2 as ActionMailer delivery methods.
208-
You simply need to configure Rails to use it in your environment configuration:
207+
This gem contains Mailer classes for Amazon SES and SESV2. To use these mailers
208+
as a delivery method, you need to register them with ActionMailer.
209+
You can create a Rails initializer `config/initializers/action_mailer.rb`
210+
with contents similar to the following:
209211

210212
```ruby
211-
# for e.g.: config/environments/production.rb
212-
config.action_mailer.delivery_method = :ses # or :sesv2
213+
options = { region: 'us-west-2' }
214+
ActionMailer::Base.add_delivery_method :ses, Aws::ActionMailer::SESMailer, **options
215+
ActionMailer::Base.add_delivery_method :ses_v2, Aws::ActionMailer::SESV2Mailer, **options
216+
```
217+
218+
In your environment configuration, set the delivery method to
219+
`:ses` or `:ses_v2`.
220+
221+
```ruby
222+
config.action_mailer.delivery_method = :ses # or :ses_v2
213223
```
214224

215225
## Amazon Simple Email Service (SES) as an ActionMailbox Method
@@ -297,32 +307,6 @@ You may also pass the following keyword arguments to both helpers:
297307
* `topic`: The _SNS_ topic used for each notification (default: `topic:arn:default`).
298308
* `authentic`: The `Aws::SNS::MessageVerifier` class is stubbed by these helpers; set `authentic` to `true` or `false` to define how it will verify incoming notifications (default: `true`).
299309

300-
### Override credentials or other client options
301-
302-
Client options can be overridden by re-registering the mailer with any set of
303-
SES or SESV2 Client options. You can create a Rails initializer
304-
`config/initializers/aws.rb` with contents similar to the following:
305-
306-
```ruby
307-
require 'json'
308-
309-
# Assuming a file "path/to/aws_secrets.json" with contents like:
310-
#
311-
# { "AccessKeyId": "YOUR_KEY_ID", "SecretAccessKey": "YOUR_ACCESS_KEY" }
312-
#
313-
# Remember to exclude "path/to/aws_secrets.json" from version control, e.g. by
314-
# adding it to .gitignore
315-
secrets = JSON.load(File.read('path/to/aws_secrets.json'))
316-
creds = Aws::Credentials.new(secrets['AccessKeyId'], secrets['SecretAccessKey'])
317-
318-
Aws::Rails.add_action_mailer_delivery_method(
319-
:ses, # or :sesv2
320-
credentials: creds,
321-
region: 'us-east-1',
322-
# some other config
323-
)
324-
```
325-
326310
### Using ARNs with SES
327311

328312
This gem uses [\`Aws::SES::Client#send_raw_email\`](https://docs.aws.amazon.com/sdk-for-ruby/v3/api/Aws/SES/Client.html#send_raw_email-instance_method)

aws-sdk-rails.gemspec

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,12 @@ Gem::Specification.new do |spec|
1515
spec.executables = ['aws_sqs_active_job']
1616

1717
# These will be removed in aws-sdk-rails ~> 5
18+
spec.add_dependency('aws-actionmailer-ses', '~> 0')
1819
spec.add_dependency('aws-record', '~> 2') # for Aws::Record integration
1920
spec.add_dependency('aws-sessionstore-dynamodb', '~> 3') # includes DynamoDB
2021

2122
# Require these versions for user_agent_framework configs
2223
spec.add_dependency('aws-sdk-s3', '~> 1', '>= 1.123.0')
23-
spec.add_dependency('aws-sdk-ses', '~> 1', '>= 1.50.0') # for ActionMailer
24-
spec.add_dependency('aws-sdk-sesv2', '~> 1', '>= 1.34.0') # for ActionMailer
2524
spec.add_dependency('aws-sdk-sns', '~> 1', '>= 1.61.0') # for ActionMailbox
2625
spec.add_dependency('aws-sdk-sqs', '~> 1', '>= 1.56.0') # for ActiveJob
2726

lib/action_dispatch/session/dynamo_db_store.rb

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,11 @@ module Session
1818
# @see https://docs.aws.amazon.com/sdk-for-ruby/aws-sessionstore-dynamodb/api/Aws/SessionStore/DynamoDB/Configuration.html
1919
class DynamoDbStore < ActionDispatch::Session::AbstractStore
2020
def initialize(app, options = {})
21-
Rails.logger.warn('** aws-sessionstore-dynamodb will no longer be a direct dependency of aws-sdk-rails ~> 5. ' \
22-
'To avoid disruption, please add aws-sessionstore-dynamodb ~> 3 to your Gemfile to enable ' \
23-
'this feature when upgrading to aws-sdk-rails ~> 5. **')
21+
Rails.logger.warn(<<~MSG)
22+
** aws-sessionstore-dynamodb will no longer be a direct dependency of aws-sdk-rails ~> 5.
23+
If you are using this feature, please add aws-sessionstore-dynamodb ~> 3 to your Gemfile to enable
24+
this feature when upgrading to aws-sdk-rails ~> 5. **
25+
MSG
2426
options[:config_file] ||= config_file
2527
options[:secret_key] ||= Rails.application.secret_key_base
2628
@middleware = Aws::SessionStore::DynamoDB::RackMiddleware.new(app, options)

lib/aws-sdk-rails.rb

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
# frozen_string_literal: true
22

3-
require_relative 'aws/rails/ses_mailer'
4-
require_relative 'aws/rails/sesv2_mailer'
53
require_relative 'aws/rails/railtie'
64
require_relative 'aws/rails/action_mailbox/engine'
75
require_relative 'aws/rails/notifications'
@@ -10,6 +8,7 @@
108

119
# remove this in aws-sdk-rails 5
1210
require 'aws-sessionstore-dynamodb'
11+
require 'aws-actionmailer-ses'
1312

1413
require_relative 'action_dispatch/session/dynamo_db_store' if defined?(Aws::SessionStore::DynamoDB::RackMiddleware)
1514

@@ -18,3 +17,10 @@ module Rails
1817
VERSION = File.read(File.expand_path('../VERSION', __dir__)).strip
1918
end
2019
end
20+
21+
# Remove these in aws-sdk-rails ~> 5
22+
Aws::Rails::SesMailer = Aws::ActionMailer::SES::Mailer
23+
Aws::Rails::Sesv2Mailer = Aws::ActionMailer::SESV2::Mailer
24+
# This is for backwards compatibility after introducing support for SESv2.
25+
# The old mailer is now replaced with the new SES (v1) mailer.
26+
Aws::Rails::Mailer = Aws::Rails::SesMailer

lib/aws/rails/railtie.rb

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,20 @@ class Railtie < ::Rails::Railtie
1212
Aws::Rails.use_rails_encrypted_credentials
1313
Aws::Rails.add_action_mailer_delivery_method
1414
Aws::Rails.add_action_mailer_delivery_method(:sesv2)
15+
16+
if %i[ses sesv2].include?(::Rails.application.config.action_mailer.delivery_method)
17+
::Rails.logger.warn(<<~MSG)
18+
** Aws::Rails.add_action_mailer_delivery_method will be removed in aws-sdk-rails ~> 5.
19+
If you are using this feature, please add your desired delivery methods in an initializer
20+
(such as config/initializers/action_mailer.rb):
21+
22+
options = { ... SES client options ... }
23+
ActionMailer::Base.add_delivery_method :ses, Aws::ActionMailer::SESMailer, **options
24+
ActionMailer::Base.add_delivery_method :ses_v2, Aws::ActionMailer::SESV2Mailer, **options
25+
26+
Existing Mailer classes have moved namespaces but will continue to work in this major version. **
27+
MSG
28+
end
1529
end
1630

1731
initializer 'aws-sdk-rails.insert_middleware' do |app|
@@ -64,8 +78,7 @@ def self.use_rails_encrypted_credentials
6478
# @param [Hash] client_options The options you wish to pass on to the
6579
# Aws::SES[V2]::Client initialization method.
6680
def self.add_action_mailer_delivery_method(name = :ses, client_options = {})
67-
# TODO: on the next major version, add a "mailer" param to this method
68-
# and use it to determine which mailer to use, keeping name free-form.
81+
# TODO: remove this method in aws-sdk-rails ~> 5
6982
ActiveSupport.on_load(:action_mailer) do
7083
if name == :sesv2
7184
add_delivery_method(name, Aws::Rails::Sesv2Mailer, client_options)

lib/aws/rails/ses_mailer.rb

Lines changed: 0 additions & 49 deletions
This file was deleted.

lib/aws/rails/sesv2_mailer.rb

Lines changed: 0 additions & 60 deletions
This file was deleted.

sample-app/Gemfile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ source "https://rubygems.org"
33
# Our gems
44
gem 'aws-sdk-rails', path: '../'
55
gem 'aws-sessionstore-dynamodb' #, path: '../../aws-sessionstore-dynamodb-ruby'
6+
gem 'aws-actionmailer-ses', git: 'https://github.com/aws/aws-actionmailer-ses-ruby', branch: 'init'
67

78
# Use Active Model has_secure_password [https://guides.rubyonrails.org/active_model_basics.html#securepassword]
89
gem 'bcrypt'

sample-app/README.md

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,4 +87,30 @@ To override changes, change this app's Gemfile to use the local path.
8787

8888
Start the service with `bundle exec rails server` and visit `http://127.0.0.1:3000/users`.
8989

90-
In the logs, you should see a notification for DynamoDB `update_item` with a `session_id`. This key should exist in your DynamoDB `sessions` table. Refreshing the page should update the session `updated_at` and/or `expired_at` and not create a new session.
90+
In the logs, you should see a notification for DynamoDB `update_item` with a `session_id`. This key should exist in your DynamoDB `sessions` table. Refreshing the page should update the session `updated_at` and/or `expired_at` and not create a new session.
91+
92+
## Action Mailer mailers
93+
94+
### Setup
95+
96+
The mailer was generated with `bundle exec rails generate mailer Test`.
97+
98+
An empty controller scaffold was generated with `bundle exec rails generate controller Mailer`.
99+
100+
`ApplicationMailer` was set to use `ENV['ACTION_MAILER_EMAIL']`.
101+
102+
`TestMailer` implemented SES and SESv2 mailer methods.
103+
104+
`MailerController` (and routes) were added to send mail.
105+
106+
`config/application.rb` added `require "action_mailer/railtie"`.
107+
108+
Delivery methods are configured in `config/initializers/action_mailer.rb`.
109+
110+
### Testing
111+
112+
Start the service with `ACTION_MAILER_EMAIL=<your email> bundle exec rails server`.
113+
114+
> **Important**: The email address in SES must be verified.
115+
116+
Visit `http://127.0.0.1:3000/send_ses_email` or `http://127.0.0.1:3000/send_ses_v2_email` and check your email.
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
class MailerController < ApplicationController
2+
def send_ses_email
3+
TestMailer.send_ses_email.deliver_now
4+
render plain: 'Email sent using SES'
5+
end
6+
7+
def send_ses_v2_email
8+
TestMailer.send_ses_v2_email.deliver_now
9+
render plain: 'Email sent using SES V2'
10+
end
11+
end
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
module MailerHelper
2+
end
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
class ApplicationMailer < ActionMailer::Base
2+
default from: ENV['ACTION_MAILER_EMAIL']
3+
layout 'mailer'
4+
end
5+

sample-app/app/mailers/test_mailer.rb

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
class TestMailer < ApplicationMailer
2+
def send_ses_email
3+
mail(
4+
to: ENV['ACTION_MAILER_EMAIL'],
5+
subject: 'Amazon SES Email',
6+
body: 'This is a test email from Amazon SES',
7+
delivery_method: :ses
8+
)
9+
end
10+
11+
def send_ses_v2_email
12+
mail(
13+
to: ENV['ACTION_MAILER_EMAIL'],
14+
subject: 'Amazon SES V2 Email',
15+
body: 'This is a test email from Amazon SES V2',
16+
delivery_method: :ses_v2
17+
)
18+
end
19+
end
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<!DOCTYPE html>
2+
<html>
3+
<head>
4+
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
5+
<style>
6+
/* Email styles need to be inline */
7+
</style>
8+
</head>
9+
10+
<body>
11+
<%= yield %>
12+
</body>
13+
</html>
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
<%= yield %>

sample-app/config/application.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
require "active_record/railtie"
88
# require "active_storage/engine"
99
require "action_controller/railtie"
10-
# require "action_mailer/railtie"
10+
require "action_mailer/railtie"
1111
# require "action_mailbox/engine"
1212
# require "action_text/engine"
1313
require "action_view/railtie"
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
options = {}
2+
ActionMailer::Base.add_delivery_method :ses, Aws::ActionMailer::SESMailer, **options
3+
ActionMailer::Base.add_delivery_method :ses_v2, Aws::ActionMailer::SESV2Mailer, **options

0 commit comments

Comments
 (0)