GAEでメールを送信したい!
お、なんか、普通にSMTPで送信するより、web APIが推奨されているみたいだぞ
モチベーション
- SendGridのWebAPIを使って、Railsからメールを送りたい
- Railsを使っているのだから、ActionMailerに組み込むようか形をとりたい
前置き
最初は
Rails: SendGrid(Web API)とAction Mailerでメールを送信する
こちらのコードをまるっと利用させてもらう形でどうにかなりました。
しかし、こちらのコードだとcc、bccでメールを送ることができませんでした。
なので、下記のように変更しました。
コード概要
Gemfileにsendgrid-ruby を追加
gem 'sendgrid-ruby'
イニシャライズ
ActionMailer::Base.add_delivery_method :sendgrid, Mail::SendGrid, api_key: ENV['SENDGRID_API_KEY']
deliver! メソッドをオーバーライド
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">
そのため、to
はpersonalization
でセットするようにしました。
参考
Rails: SendGrid(Web API)とAction Mailerでメールを送信する
github sendfrid-ruby example