読者です 読者をやめる 読者になる 読者になる

メールを送るにはdjango-mailerが便利かも

Django

django-mailerは、メール送信をする際にメッセージのキューイングを行うためのDjangoアプリケーション。

Djangoアプリケーションからメールを送る際には通常django.core.mailを使うが、django-mailerの利点としては、

  • 送信したメールのログがデーターベースに残る。
    • なので、本番環境でも開発環境でも何を送信したかを簡単に確認できて便利。
  • 一時的にSMTPに接続できなかった場合に再試行を行うことができる。
  • 送信対象から除外するアドレスを指定できる。

といったところ。メールを即時に送るわけではないので、

  • パスワードリセット
  • 会員登録時のメールアドレスの確認

といった用途には向かないかもしれない。

django-mailerはPyPIに登録されているので、

$ pip install django-mailer

でインストールして、settings.pyに

INSTALLED_APPS = (
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.sites',
    'django.contrib.admin',
    'mailer',
)

のようにmailerを追加すれば簡単に利用できる。

送信するメッセージ・送信済みメッセージをデータベースに保存しておく仕組みになっているので、INSTALLED_APPSにmailerを追加した後に、

$ python manage.py syncdb
Creating table mailer_message
Creating table mailer_dontsendentry
Creating table mailer_messagelog

で必要なテーブルを作っておく。

送信側は、

try:
    import mailer
except ImportError:
    from django.core import mail as mailer

mailer.send_mail("subject", "body", "from_addr@example.com", ["recipient1@example.com", "recipient2@example.com"])

のように使う。

django.core.mail.send_mailは呼び出した時点でSMTPサーバーに接続するが、mailer.send_mailの方はデーターベースにキューイングするだけなので実際の送信は行われない。実際にメールを送信するには、manage.pyでsend_mailコマンドを呼び出す。

$ python manage.py send_mail

cronにこのコマンドを仕込んでおいて、何分かおきに送信を行うということになるだろう。

SMTPのエラーなどで一時的に送信が失敗したメッセージを再送信するには、retry_deferredコマンドで通常のキューに戻した後、再度send_mailコマンドで送信する。

$ python manage.py retry_deferred

django-mailerの特徴として、DontSendEntryというあるアドレスをメールの送信対象から除外する機能がある。DontSendEntryに入っているメールアドレスにはsend_mailコマンドを実行しても、実際にはメールは送信されない。テスト用のメールアドレスや送信エラーとなったアドレスなどを登録しておくと便利だと思う。

DontSendEntryは普通のDjangoモデルなので、

import datetime
from mailer.models import DontSendEntry

to_addr = 'dont_send@example.com'

if not DontSendEntry.objects.has_address(to_addr):
    entry = DontSendEntry(to_address=to_addr, when_added=datetime.datetime.now())
    entry.save()

のようにして追加する。手動で登録するならばadminを使えば簡単。