こんにちは、皆さん!

今回はHerokuのDjangoアプリでメールを送る方法について紹介していこうと思います。具体的にはSendGridのヘルプを借りてメールを送ります。


トピック


Django内のコード

まずはDjango側でメールを送るためのコードやセットアップを書いていきましょう!

Herokuへデプロイするときのセットアップを少なくするために予め作ったDjangoアプリをHeroku上にデプロイする際に必要な設定をしたGithubのレポジトリからダウンロードしてスタートします。


DjangoアプリをHerokuにデプロイする方法について知りたい方はこちらの記事から参照してください↓


仮想環境を構築するためにvirtualenvwrapperというパッケージを使います。まだインストールされていない方はこちらから参照してください。


まずは仮想環境を作って、requirements.txt ファイル内のパッケージをインストールしましょう。

mkvirtualenv django_email_heroku_env
pip install -r requirements.txt

そしたら、settings.py ファイルを開き、一番下に下記の内容を追加します。

if app_stage == 'dev':
    EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend'
else:
    EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'

SENDGRID_API_KEY = os.environ.get('SENDGRID_API_KEY', 'api_key')
EMAIL_USE_TLS = True
EMAIL_HOST = 'smtp.sendgrid.net'
EMAIL_HOST_USER = 'apikey'
EMAIL_HOST_PASSWORD = SENDGRID_API_KEY
EMAIL_PORT = 587

USER_EMAIL = os.environ.get("USER_EMAIL", "example@example.com")

1行目のapp_stageという変数は現在の環境を教えてくれる変数として、Herokuへのデプロイのチュートリアルの中で解説しました。app_stage = os.environ.get("APP_STAGE", "dev")という感じで設定していて、Herokuの方で、環境変数をしっかりセットすることで、本番環境ではif文のelseの方に行けるようになっています。この設定ではローカルではメールを送信せず、ただコンソールでその内容を表示する形になっていて、本番環境のHerokuではメールを送信できるようにしています。USER_EMAILはメールが送信される先のユーザーのメールです。環境変数から簡単に変えれるような設計で今回はいきます。

今回はSendGridを使って、Herokuからメールを送信するようにしたいので、6行目のように SendGridのAPIキーを渡しています。

その他のメールの設定は基本的には上記のように統一ですので、これで大丈夫です。


次にDjangoアプリ内でメールを送信しようと思います。

今回はなるべく内容をシンプルにしたいので、Herokuコマンドからメールを送信できるようにします。

最初に新しいアプリモジュールを追加します。これを email_service としましょう。

python manage.py startapp email_service

忘れずに settings.py ファイルにこの新しく追加したアプリを追加しましょう。そしたら、settings.py ファイルの INSTALLED_APPS の部分は下記のようになるはずです。

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'email_service',
]

次に helpers.py ファイルを email_service フォルダー内に作ります。このファイルの中でメールを送信する関数を用意したいと思います。

from django.core.mail import EmailMultiAlternatives
from django_heroku.settings import USER_EMAIL

def send_email():
    subject, from_email, to = "件名:新しいメールです", 'no-reply@example.com', USER_EMAIL
    text_content = "Herokuからのメッセージです。\nメールの送信に成功しました。おめでとうございます。"
    html_content = "<h1>Herokuからのメッセージです。</h1><br><p>メールの送信に成功しました。おめでとうございます。</p>"
    msg = EmailMultiAlternatives(subject, text_content, from_email, [to])
    msg.attach_alternative(html_content, "text/html")
    msg.send()

subject は件名で、from_email は送信元のメアドで、to は送信先のメアドです。注意する点としては、クラスでオブジェクトを作るときの宛先は配列になっているということです。

ここではDjangoのメールクラスを利用して、テキストとHTMLのフォーマットのメールの両方を使っています。基本的にはHTMLのフォーマットで送信されますが、相手側のメールシステムがそれに対応していなかった場合はテキストの方が使われます。

そしたら、ルートディレクトリに task.py ファイルを作りましょう。最終的にはHerokuのコマンドからこのファイルを呼び出して、先ほど定義した関数が呼ばれるようにします。

from email_service.helpers import send_email

send_email()

こんな感じで先ほどの関数をインポートしてきて、ここで呼び出せばオッケーです。


ローカルで試す

では、早速ローカルで試してみましょう!

settings.py ファイルで設定したようにローカルではターミナルにメールの内容が表示されるはずです。

実行するためには settings.py ファイル内の内容を読み込んだ状態で send_email() 関数を呼び出せば良いです。

めんどくさいですが、settings.py ファイル内の内容を読み込ませるために、Djangoのコンソールを使います。

python manage.py shell

これが起動したら、次に下記のように関数をインポートして、そして呼び出します。

Python 3.7.7 (default, Mar 10 2020, 15:43:33) 
[Clang 11.0.0 (clang-1100.0.33.17)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
(InteractiveConsole)
>>> from email_service.helpers import send_email
>>> send_email()
Content-Type: multipart/alternative;
 boundary="===============3417740709386980117=="
MIME-Version: 1.0
Subject: =?utf-8?b?5Lu25ZCN77ya5paw44GX44GE44Oh44O844Or44Gn44GZ?=
From: no-reply@example.com
To: example@example.com
Date: Thu, 16 Apr 2020 06:49:34 -0000
Message-ID: <158701977416.90640.11419175000443883276@CTLT-CLM-BOYYAO>

--===============3417740709386980117==
Content-Type: text/plain; charset="utf-8"
MIME-Version: 1.0
Content-Transfer-Encoding: 8bit

Herokuからのメッセージです。
メールの送信に成功しました。おめでとうございます。
--===============3417740709386980117==
Content-Type: text/html; charset="utf-8"
MIME-Version: 1.0
Content-Transfer-Encoding: 8bit

<h1>Herokuからのメッセージです。</h1><br><p>メールの送信に成功しました。おめでとうございます。</p>
--===============3417740709386980117==--

-------------------------------------------------------------------------------

このようにローカルではそのままターミナルにメールの内容が表示されます。打つコードは5行目のと6行目のやつです。


本番環境で試す

そしたら、ここまでの内容を保存して、Herokuにプッシュしましょう。

heroku create
git add -A
git commit -m "Completed email service"
git push heroku master

下記のようなエラーが出た場合:

remote:  !     Error while running '$ python manage.py collectstatic --noinput'.
remote:        See traceback above for details.
remote: 
remote:        You may need to update application code to resolve this error.
remote:        Or, you can disable collectstatic for this application:
remote: 
remote:           $ heroku config:set DISABLE_COLLECTSTATIC=1
remote: 
remote:        https://devcenter.heroku.com/articles/django-assets
remote:  !     Push rejected, failed to compile Python app.

このエラーを解消するためには下記のように環境変数を設定して、再度プッシュすれば大丈夫です。

heroku config:set DISABLE_COLLECTSTATIC=1

次に先ほど自分で追加した今どの環境にいるのかを教えてくれる環境変数と送信先のメアドの環境変数を足していきたいと思います。

heroku config:set APP_STAGE=prod
heroku config:set USER_EMAIL=youremail@example.com

そこまでやりましたら、一度、Herokuのウェブサイトに行き、必要なSendGridのアドオンを足しましょう!

Herokuでご自身のアプリを開きましたら、Resourcesを押しましょう!

Resourcesを押します

その出てきた先のページでSendGridと検索し、無料版のアドオンを追加しましょう!

アドオンの追加

そしたら、そのままSendGridを押して、リンク先で設定からAPI Keysを選択しましょう。

SendGridからAPI Keysを選択

右上の青いボタン、”Create API Key”を押して、適当に名前を付けてAPIキーを生成しましょう。

API Keyの作成

出てきたAPI Keyをコピーしましょう。

API Keyのコピー

そしたら、Herokuのアプリに戻り、Settingsを開き、”Reveal Config Vars”を押して、下記のように先ほどコピーしたAPI Keyを貼り付けて新しい環境変数を作ります。

API Keyを環境変数として足す

これでセットアップ完了になります。あとは先ほどローカルでやったのと同じようにPythonのコマンドを打ちます。ただ今回はHeroku上のものに対して行うので、heroku run を先に付けます。

heroku run python manage.py shell

そして、先ほどと同じように関数のインポートと呼び出しを行います。

Python 3.6.10 (default, Dec 23 2019, 04:30:25) 
[GCC 7.4.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
(InteractiveConsole)
>>> from email_service.helpers import send_email
>>> send_email()
>>> 

そうすると、先ほどUSER_EMAILで設定したメアドにメールが届いているはずです。

メールのスクショ

まとめ

今回はDjangoとHerokuでメールを送信する方法を紹介しました。

なるべくシンプルにできるようにビューやテンプレは一切触っていません。現実ではもっとそういう場所で使うことが予想されますが、そのときは helpers.py ファイル内のようなコードをビューなりなんなりに必要に応じて入れてもらえば動くはずです。

他にもHeroku Schedulerと合わせて好きな時間にメールを送ってもらうようにするなどのことを実践してみると面白いかなと思います。Heroku Schedulerに関しては下記の記事にまとめましたので、よかったら参考にしてみてください↓


皆さんの役に立つことを願います!
では、また次回まで✌
記事更新はツイッターで告知するので、ツイッターの方でもフォローお願いします!

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です