LoginSignup
21
9

More than 3 years have passed since last update.

Rails Action MailerでSendGrid Web APIを使用する

Last updated at Posted at 2019-06-15

GAEでメールを送信したい!
お、なんか、普通にSMTPで送信するより、web APIが推奨されているみたいだぞ

モチベーション

  • SendGridのWebAPIを使って、Railsからメールを送りたい
  • Railsを使っているのだから、ActionMailerに組み込むようか形をとりたい

前置き

最初は
Rails: SendGrid(Web API)とAction Mailerでメールを送信する
こちらのコードをまるっと利用させてもらう形でどうにかなりました。

しかし、こちらのコードだとcc、bccでメールを送ることができませんでした。
なので、下記のように変更しました。

コード概要

Gemfileにsendgrid-ruby を追加

Gemfile

gem 'sendgrid-ruby'

イニシャライズ

config/initializers/sendgrid.rb
ActionMailer::Base.add_delivery_method :sendgrid, Mail::SendGrid, api_key: ENV['SENDGRID_API_KEY']

deliver! メソッドをオーバーライド

app/lib/mail/send_grid.rb
module Mail
  class SendGrid
    def initialize(settings)
      @settings = settings
    end

    def deliver!(mail)
      ## to, cc, bcc はpersonalizationで設定する
      personalization = ::SendGrid::Personalization.new
      personalization.add_to(::SendGrid::Email.new(email: mail.to.first))
      personalization.subject = mail.subject

      Array(mail.bcc).each do |email|
        personalization.add_bcc(::SendGrid::Email.new(email: email))
      en
      Array(mail.cc).each do |email|
        personalization.add_cc(::SendGrid::Email.new(email: email))
      end

      ## from, subject, contentを設定
      sg_mail = ::SendGrid::Mail.new
      sg_mail.from = ::SendGrid::Email.new(email: mail.from.first)
      sg_mail.subject = mail.subject
      sg_mail.add_content(::SendGrid::Content.new(type: 'text/html', value: mail.body.raw_source))

      ## 送信するためのメールオブジェクト完成
      sg_mail.add_personalization(personalization)

      # API KEY 
      sg = ::SendGrid::API.new(api_key: @settings[:api_key])
      response = sg.client.mail._('send').post(request_body: sg_mail.to_json)
      response.status_code
    end
  end
end

つまづいたのはtoを定義するところでした。
最初はpersonalizationではなく SendGrid::Email で用意されているメソッドでtoをセットしていました。
しかし、このような実装だと、add_personalization をしたときに、toがうまくセットされていないような状態となり以下のようなエラーがレスポンスで返ってきました。

[54] pry(main)> response = sg.client.mail._('send').post(request_body: sg_mail.to_json)
=> #<SendGrid::Response:0x00005631ce39e238
 @body=
  "{\"errors\":[{\"message\":\"The to array is required for all personalization objects, and must have at least one email object with a valid email address.\",\"field\":\"personalizations.1.to\",\"help\":\"http://sendgrid.com/docs/API_Reference/Web_API_v3/Mail/errors.html#message.personalizations.to\"}]}",
 @headers=
  {"server"=>["nginx"],
   "date"=>["Fri, 14 Jun 2019 16:57:50 GMT"],
   "content-type"=>["application/json"],
   "content-length"=>["288"],
   "connection"=>["close"],
   "access-control-allow-origin"=>["https://sendgrid.api-docs.io"],
   "access-control-allow-methods"=>["POST"],
   "access-control-allow-headers"=>["Authorization, Content-Type, On-behalf-of, x-sg-elas-acl"],
   "access-control-max-age"=>["600"],
   "x-no-cors-reason"=>["https://sendgrid.com/docs/Classroom/Basics/API/cors.html"]},
 @status_code="400">

そのため、topersonalization でセットするようにしました。

参考

Rails: SendGrid(Web API)とAction Mailerでメールを送信する
github sendfrid-ruby example

21
9
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
21
9