Action Mailer ifルート

3 min read読了の目安(約3000字

本エントリは iCARE Advent Calendar 2020 の20日目の記事です。

なにこれ?

先日、Railsで開発しているサービスで使用されているメール配信用のgemが二年ほど更新されておらず、メール配信サービス(SendGrid)側の一部機能が使用できなくなっていたので別のgemに入れ替えました。
入れ替えたgemはSendGridが公式に配信しているgem(sendgrid-ruby)ではなく、ActionMailerでメール配信リクエストを送信することを想定したgem(sendgrid-actionmailer)です(内部ではsendgrid-rubyを使用しています)
ですが、もともとAction Mailerは内部でmailというgemを使っており、配信方法がpluggableになっています。
なので、delivery methodをsendgrid-rubyを使って独自の配信方法に変更してみたいと思います。

環境

・ ruby 2.6.5
・ rails 5.0.7
・ sendgrid-ruby 6.3.7
・ mail 2.6.6

API Keyの作成

サイドメニューの Setting の API Keys から遷移して、 Create API Key のボタンをクリックしてよしなに権限をもたせてAPI Keyを作成します。

gemの追加

Gemfile
gem 'sendgrid-ruby'

delivery_methodの変更

app/mailers/send_grid_mail.rb
class SendGridMail

  def initialize(settings)
    @settings = settings
  end

  def deliver!(mail)
    personalization = SendGrid::Personalization.new
    personalization.add_to(SendGrid::Email.new(email: mail.to.first))
    personalization.subject = mail.subject

    send_grid_mail = SendGrid::Mail.new
    send_grid_mail.from = SendGrid::Email.new(email: mail.from.first)
    send_grid_mail.subject = mail.subject
    send_grid_mail.add_content(SendGrid::Content.new(type: 'text/html', value: mail.body.raw_source))
    send_grid_mail.add_personalization(personalization)

    send_grid = SendGrid::API.new(api_key: @settings[:api_key])
    begin
      response = send_grid.client.mail._('send').post(request_body: send_grid_mail.to_json)
    rescue Exception => e
      # Sentryへ通知
      Raven.capture_exception(e)
    end
  end
end
config/environments/development.rb
  ActionMailer::Base.add_delivery_method :sendgrid, SendGridMail
  config.action_mailer.delivery_method = :sendgrid
  config.action_mailer.sendgrid_settings = {
    api_key: ENV['SENDGRID_API_KEY_FOR_SEND_MAIL']
  }

使ってみる

app/mailers/test_mailer.rb
class TestMailer < ApplicationMailer
  def send_mail(to='to@example.com', from='from@example.com', subject='件名:テストメール', body='はじめてのメール')
    @body = body
    @title = subject
    mail(to: to, from: from, subject: subject)
  end
end
app/views/test_mailer/send_mail.html.erb
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
  <head>
    <meta name="viewport" content="width=device-width"/>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
    <title><%= @title %></title>
  </head>
  <body>
    <%= raw @body %>
  </body>
</html>

最後に

iCAREではTech Blogも毎月投稿されているので是非みてください!
またMeet Upも開催しているのでご興味ある方はお気軽にご参加ください!