diff --git a/.reek b/.reek index ddb112d50fc..e0981a31334 100644 --- a/.reek +++ b/.reek @@ -15,6 +15,7 @@ DuplicateMethodCall: FeatureEnvy: exclude: - ActiveJob::Logging::LogSubscriber#json_for + - Aws::SES::Base#deliver - track_registration - append_info_to_payload - generate_slo_request diff --git a/Gemfile.lock b/Gemfile.lock index 4bf4b3f6f4e..9bf4c32b2c0 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -248,7 +248,7 @@ GEM erubi (1.6.1) erubis (2.7.0) eventmachine (1.2.5) - excon (0.57.0) + excon (0.58.0) execjs (2.7.0) factory_girl (4.8.0) activesupport (>= 3.0.0) diff --git a/config/application.yml.example b/config/application.yml.example index 753692138e3..aa4a7a0f3a7 100644 --- a/config/application.yml.example +++ b/config/application.yml.example @@ -144,7 +144,7 @@ production: lockout_period_in_minutes: '10' logins_per_ip_limit: '20' logins_per_ip_period: '8' - mandrill_api_token: '123abc' + mandrill_api_token: '' # Empty string to switch to SES newrelic_license_key: 'xxx' newrelic_browser_key: '' newrelic_browser_app_id: '' diff --git a/config/environments/production.rb b/config/environments/production.rb index d21707a4ad7..7db4ddd91b3 100644 --- a/config/environments/production.rb +++ b/config/environments/production.rb @@ -22,8 +22,10 @@ config.action_mailer.default_options = { from: Figaro.env.email_from } config.action_mailer.delivery_method = if Figaro.env.disable_email_sending == 'true' :test - else + elsif Figaro.env.mandrill_api_token.present? :mandrill + else + :ses end routes.default_url_options[:protocol] = :https diff --git a/config/initializers/ses_delivery_method.rb b/config/initializers/ses_delivery_method.rb new file mode 100644 index 00000000000..18ce2b81620 --- /dev/null +++ b/config/initializers/ses_delivery_method.rb @@ -0,0 +1,2 @@ +require Rails.root.join('lib', 'aws', 'ses.rb') +ActionMailer::Base.add_delivery_method :ses, Aws::SES::Base diff --git a/lib/aws/ses.rb b/lib/aws/ses.rb new file mode 100644 index 00000000000..a5d0b9639b2 --- /dev/null +++ b/lib/aws/ses.rb @@ -0,0 +1,24 @@ +## +# ActionMailer delivery method for SES inspired by https://github.com/drewblas/aws-ses +# +module Aws + module SES + class Base + def initialize(*); end + + def deliver(mail) + response = ses_client.send_raw_email(raw_message: { data: mail.to_s }) + mail.message_id = "#{response.message_id}@email.amazonses.com" + response + end + + alias deliver! deliver + + private + + def ses_client + @ses_client ||= Aws::SES::Client.new(region: Figaro.env.aws_region) + end + end + end +end diff --git a/spec/lib/aws/ses_spec.rb b/spec/lib/aws/ses_spec.rb new file mode 100644 index 00000000000..98fb1a87f8a --- /dev/null +++ b/spec/lib/aws/ses_spec.rb @@ -0,0 +1,41 @@ +require 'rails_helper' + +describe Aws::SES::Base do + let(:mail) do + Mail.new( + to: 'asdf@example.com', + cc: 'ghjk@example.com', + body: 'asdf1234' + ) + end + let(:ses_response) do + response = double + allow(response).to receive(:message_id).and_return('123abc') + response + end + let(:ses_client) { instance_double(Aws::SES::Client) } + + before do + allow(ses_client).to receive(:send_raw_email).and_return(ses_response) + allow(Aws::SES::Client).to receive(:new).and_return(ses_client) + end + + describe '#deliver!' do + it 'sends the message to the correct recipients' do + raw_mail_data = mail.to_s + + subject.deliver!(mail) + + expect(ses_client).to have_received(:send_raw_email).with( + raw_message: { + data: raw_mail_data, + } + ) + end + + it 'sets the message id on the mail argument' do + subject.deliver!(mail) + expect(mail.message_id).to eq('123abc@email.amazonses.com') + end + end +end