SendGrid

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

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

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

参考にしました

手順

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

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

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

SendGridのAPI Keyの作成

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

2018-03-22-21-38-03.png

  • Create API Keyをクリック

2018-03-22-21-39-14.png

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

  • 2018-03-22-21-39-39.png

  • Mail Sendのこの辺りをクリック。(押せないUIにしかみえないけど。)

    • APIとして使いたい場合は適宜権限を与えてください。
  • その後、下のCreate & viewボタンをクリック

  • 2018-03-22-21-42-03.png

  • Secret Keyが表示されるのでクリックするとコピーされる。

    • ちゃんと保存してから、Doneをクリック。(Doneボタンは1度コピーするまで押せない。)

2018-03-22-21-43-57.png

作った情報が追加されます。API-KEYは特に使いません。(API-SECRETに含まれてます。)

接続情報

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

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

usernameはapikeyを指定します。生成したAPI-KEYではないです。(少し躓いた)

お疲れ様でした。

おまけ

以下、躓いた点です。

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

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

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

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

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

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

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

see: SendGrid-SMTPでメールを送信する際に気をつけることはありますか?

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

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

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

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

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)