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

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


## モチベーション
- SendGridのWebAPIを使って、Railsからメールを送りたい
- Railsを使っているのだから、ActionMailerに組み込むようか形をとりたい

## 前置き

最初は
[Rails: SendGrid(Web API)とAction Mailerでメールを送信する](https://techracho.bpsinc.jp/yamada/2018_12_22/67222)
こちらのコードをまるっと利用させてもらう形でどうにかなりました。

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

## コード概要

**Gemfileにsendgrid-ruby を追加**

```ruby:Gemfile

gem 'sendgrid-ruby'
```

**イニシャライズ**

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


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

```ruby: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">
```

そのため、`to` は`personalization` でセットするようにしました。

## 参考
[Rails: SendGrid(Web API)とAction Mailerでメールを送信する](https://techracho.bpsinc.jp/yamada/2018_12_22/67222)
[github sendfrid-ruby example](https://github.com/sendgrid/sendgrid-ruby/blob/master/examples/helpers/mail/example.rb)