SendGridをSMTPで利用するためのAPI Keyの登録＋α

SMTPサーバをSendGridに乗り換えましょうということで、調べました。

何も問題がなければ、SMTPの接続情報を書き換えるだけです。何も問題がなければ。


参考にしました
-------------

- [SendGrid - SMTPの接続情報を教えてください。](https://support.sendgrid.kke.co.jp/hc/ja/articles/204187885-SMTP%E3%81%AE%E6%8E%A5%E7%B6%9A%E6%83%85%E5%A0%B1%E3%82%92%E6%95%99%E3%81%88%E3%81%A6%E3%81%8F%E3%81%A0%E3%81%95%E3%81%84-)


手順
-------------------

前提として、SendGridから本登録が終わっていて、IDとパスワードを払い出してもらっている必要があります。

今回は、APIキーを使った認証を使います。

登録時のIDとパスワードでもできますが、APIで送りたくなったときとかに使えるように、またいざというときにシュッと無効化できるAPIキーを使ったほうが良いはずです。面倒ですけど。

### SendGridのAPI Keyの作成

https://app.sendgrid.com/settings/api_keys を開きます。

![2018-03-22-21-38-03.png](https://qiita-image-store.s3.amazonaws.com/0/52527/b708079a-b437-fc3e-d26a-58526be09c64.png)

- Create API Keyをクリック

![2018-03-22-21-39-14.png](https://qiita-image-store.s3.amazonaws.com/0/52527/49c580ba-a60d-15cd-a001-3eb314fae80a.png)

- API Nameを指定する
- API Key Permissionは`Restricted Access`にする。

- ![2018-03-22-21-39-39.png](https://qiita-image-store.s3.amazonaws.com/0/52527/058bf927-0c8e-749f-4134-282f17380edc.png)

- Mail Sendのこの辺りをクリック。（押せないUIにしかみえないけど。）
  - APIとして使いたい場合は適宜権限を与えてください。
- その後、下のCreate & viewボタンをクリック

- ![2018-03-22-21-42-03.png](https://qiita-image-store.s3.amazonaws.com/0/52527/c4fee8e7-fa7b-5bc4-f419-90cdfc691fce.png)

- API Keyが表示される。この値は２度と表示されないので、注意。
  - API Keyの部分をクリックするとコピーされる。
  - Doneをクリック。（Doneボタンは1度コピーするまで押せない。）

![](doc-images/sendgrid-smtp-setting/2018-03-22-21-43-57.png)![2018-03-22-21-43-57.png](https://qiita-image-store.s3.amazonaws.com/0/52527/a1d2fbfb-ca83-1923-3bae-472503365477.png)

作った情報が追加されます。画面上で表示されているAPI-KEY IDは特に使いません。API KEYのほうだけ使います。


### 接続情報

以下のようになる。SSLを使う場合。

- Server: `smtp.sendgrid.net` (※固定)
- Port: `465` (※SSLの場合)
- Username: `apikey` (※固定)
- Password: {作成した API KEY}

usernameは`apikey`を指定します。生成したAPI-KEYでもAPI KEY IDでもないです。（少し躓いた）


お疲れ様でした。



おまけ
------------

以下、躓いた点です。


### テキスト形式で配信している人には迷惑な設定について

see: https://sendgrid.kke.co.jp/blog/?p=1521

SendGridがウリにしているトラッキング機能を実現するためにあれこれやっているようです。

1. text/plainなメールをHTMLへ改変（以下2つの機能がHTMLでないと実現できないため）
2. メール中のリンクをsendgridのリンクに改変（クリックトラッキング）
3. メール中に見えない画像を仕込み、メールを開いたことを検知する（オープントラッキング）


`Settings`>`Mail Settings`に`Plain Content`という項目を**有効化**にすると、1の挙動を抑制できます。

`Settings`>`Tracking`というメニューの場所に`Click Tracking`と`Open Tracking`があるので、無効化にすることで2,3の挙動を抑制できます。


### メールのフォーマットが壊れていると、SendGridがたくさん改行を入れてくる

see: [SendGrid-SMTPでメールを送信する際に気をつけることはありますか？](https://support.sendgrid.kke.co.jp/hc/ja/articles/206313205-SMTP%E3%81%A7%E3%83%A1%E3%83%BC%E3%83%AB%E3%82%92%E9%80%81%E4%BF%A1%E3%81%99%E3%82%8B%E9%9A%9B%E3%81%AB%E6%B0%97%E3%82%92%E3%81%A4%E3%81%91%E3%82%8B%E3%81%93%E3%81%A8%E3%81%AF%E3%81%82%E3%82%8A%E3%81%BE%E3%81%99%E3%81%8B-) 

ここにある(3)の事象に遭遇したのでメモ。

本事象に遭遇したときはDjango1.11を使っていましたが、動きを調べたところ、utf-8で送ろうとすると、ContentTransfer-Encodingが`8bit`になってしまう動きでした。これはSendGridが認めない動きのようです。
（Django2.0系は試してないが、メール回りはかなり書き変わっていたように見える。）

多分、ヘッダ消したり、本文をBase64にしたりすることでうまくいくかもしれませんが、~~Djangoに振り回されるのが面倒になって諦めて~~Pythonの標準ライブラリを使ったら普通に躓くことなくかけました。

EMAIL_BACKENDの恩恵はなくなりますが、ダミーのSMTPサーバは簡単に立てられるので・・・

``` python
import smtplib
from email.mime.text import MIMEText
from email.utils import formataddr,formatdate,make_msgid
from django.conf import settings

def send_mail(subject, content, from_email, to_emails, reply_email):
    msg = MIMEText(content, 'plain', 'utf-8')
    msg['From'] = sender_email
    msg['To'] = ','.join(to_emails) # array!
    msg['Reply-To']= reply_email
    msg['Subject'] = subject
    msg['Date'] = formatdate()
    msg['Message-ID'] = make_msgid()

    smtp_module = smtplib.SMTP_SSL if settings.EMAIL_USE_SSL else smtplib.SMTP

    with smtp_module(
        settings.EMAIL_HOST,
        settings.EMAIL_PORT,
    ) as server:
        server.login(settings.EMAIL_HOST_USER,settings.EMAIL_HOST_PASSWORD)
        server.send_message(msg)
```