NEWSニュース&ブログ

「AWS SES for python」を利用してメール送信する

この記事は最終更新から9年以上経過しています。内容が古くなっている可能性があります。

投稿日:2016/1/29

これからAWS SES始める人必見!「AWS SES for python」を利用してメール送信する

AWS上で構築したWebシステムからメールを送信したいという顧客要望はよくあります。
メールを送信する手段としてEC2上に送信メールサーバー(SMTPサーバー)を構築する方法もありますが、設定や運用のお守りが面倒だったりします。「たかだか通知メール、もっと楽にできないの!」という軽い気持ちでSimple Email Service(Amazon SES)を検証してみることにしました。

前提条件

・検証端末にPythonがインストールされていること(本検証ではPython3.4を使用)
・検証端末にMicrosoft Visual Studio Community 2015がインストールされていること

事前準備

AWS SESの設定を行う前にいくつか準備を行いました。

1.IAMユーザー作成

Pythonプログラムからメール送信時に必要なアクセスキーとシークレットキーを発行する為、
IAMユーザーを作成します。
Policyには以下のアクセス許可を付与しました。
・SESの参照権限(AmazonSESFullAccess)

2.アクセスキーとシークレットキーの事前登録

プログラム内に直接アクセスキーとシークレットキーを指定してもよいのですが、
今回はCLI構成ファイルに設定します。

2-1.下記ページからAWSコマンドラインインターフェースをダウンロードします。

※今回はWindows64Bit版を使用します。https://aws.amazon.com/jp/cli/

2-2.ダウンロード後、インストールを行います。(AWSCLI64.msi)

2-3.インストールが終わったらコマンドプロンプトを管理者モードで起動して“aws configure”と入力したら
  下記項目に値を入力します。

AWS Access Key ID: 事前準備1で作成したアクセスキー
AWS Secret Access Key: 事前準備1で作成したシークレットキー
Default region name: なし
Default output format: なし

3.メール送信テスト用プログラムの作成

今回はDjangoフレームワークを利用したPythonプログラムからメールの送信テストを行います。
開発ツールはMicrosoft VisualStudioCommunity2015を使用します。

3-1.Djangoプロジェクトの作成

・Microsoft Visual StudioにてDjango Web Projectを作成します。

3-2.AmazonSESの検証で必要なPythonパッケージの追加

 ・下記Pythonパッケージを追加します。

①boto(easy_installにて実施)

②django-ses(pipにて実施) ※入力値はboto django-sesで入力(下記画像参照)

③djangorestframework(pipにて実施)

④django-cors-headers(pipにて実施)
※Pythonパッケージの追加はソリューションエクスプローラの対象環境を右クリック後のメニューから
 Install python packageを選択して行います。


・ソリューションエクスプローラの状態は下記のようになります。


3-3.テストプログラムのコーディング

・簡単な送信画面を作成します。
  [ソリューションフォルダ]\app\templates\appにSendMail.htmlを追加します。


コードは下記のように設定します。

{% extends "app/layout.html" %}
{% block content %}
<h2>{{ title }}.</h2>
<form action="/sendMail/" method="post">
    {% csrf_token %}
    <div><input type="button" value="Test Mail Send" onclick="if (confirm('Send Mail?')) { submit(); }"></div>
</form>
{% endblock %}

[ソリューションフォルダ]\app\templates\app\layout.htmlを下記コードに書き換えます。

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>{{ title }} - My Django Application</title>
    {% load staticfiles %}
    <link rel="stylesheet" type="text/css" href="{% static 'app/content/bootstrap.min.css' %}" />
    <link rel="stylesheet" type="text/css" href="{% static 'app/content/site.css' %}" />
    <script src="{% static 'app/scripts/modernizr-2.6.2.js' %}"></script>
</head>
<body>
    <div class="container body-content">
{% block content %}{% endblock %}
        <hr/>
        <footer>
            <p>&copy; {{ year }} - My Django Application</p>
        </footer>
    </div>
    <script src="{% static 'app/scripts/jquery-1.10.2.js' %}"></script>
    <script src="{% static 'app/scripts/bootstrap.js' %}"></script>
    <script src="{% static 'app/scripts/respond.js' %}"></script>
{% block scripts %}{% endblock %}

</body>
</html>

[プロジェクトフォルダ]\urls.pyを下記コードに書き換えます。

"""
Definition of urls for DjangoSendMailProject.
"""
from datetime import datetime
from django.conf.urls import patterns, url
from app.forms import BootstrapAuthenticationForm
from rest_framework import routers
from app.views import SendMailView

# Uncomment the next lines to enable the admin:
#from django.conf.urls import include
#from django.contrib import admin
#admin.autodiscover()

urlpatterns = patterns('',
    url(r'^$', 'app.views.sendmailform', name='sendmailform'),
    url(r'^sendMail/', SendMailView.as_view()),
)

[ソリューションフォルダ]\app\views.pyを下記コードに書き換えます。

from django.shortcuts import render
from django.http import HttpRequest
from django.template import RequestContext
from datetime import datetime
from django.conf import settings
from rest_framework import viewsets
from rest_framework.decorators import detail_route
from django.http import HttpResponse
from django.views.generic.base import View
#AWS SESとの接続
from boto.ses.connection import SESConnection 
# SESConnection の引数にAWS_ACCESS_KEY_IDとAWS_SECRET_ACCESS_KEYを設定
#してもよいのですが、今回は事前準備2であらかじめ設定する方法にします。
conn = SESConnection() 
#簡易送信フォーム
def sendmailform(request):
    """Test Mail page."""
    assert isinstance(request, HttpRequest)
    return render(
        request,
        'app/SendMail.html',
        context_instance = RequestContext(request, { 'title':'Test Mail page', })
    )
# 通知系メール送信
class SendMailView(View):
    def post(self, request):
        # 送信先のアドレスリスト(複数設定可能) 
        to_addresses = [ 'XXXX@XXXX.jp' ]
        # SendMail APIを呼び出す
        conn.send_email( 'XXXX@XXXX.jp'    # 送信元アドレス
                                ,'テスト'           # メールの件名
                                ,'本文のテスト'     # メールの本文
                                ,to_addresses     # 送信先のアドレスリスト 
                               ) 
        return HttpResponse('ok')

[プロジェクトフォルダ]\ settings.pyに下記赤枠のコードを追加します。

・Microsoft Visual StudioでF5キーを押して下記画面が表示されるのを確認します。

AWS SESの設定その1

事前準備が長くなりましたが、ここからAWS SESの設定になります。



1.リージョンの変更

AWSマネジメントコンソールにログインします。
AWS SESはTokyoリージョンではサポートされていない(本執筆時時点)ため、リージョンを東京から一番近そうな米国東部(バージニア北部)に変更します。

2.SESの設定

AWSマネジメントコンソールからアプリケーションサービスのSESをクリック後、下記画面が表示されます。
AWS SESには申請を行わなくても簡単な動作テストが行えるSand Box環境がありますので、まずはそれでメール送信テストをしてみます。左メニューのEmail Addressesをクリックします。

3.Sand Box環境設定

Sand Box環境でメール送信を行う場合、送信元アドレスに加えて送信先アドレスも登録する必要がありますので両方を登録します。Verify a New Email アドレスをクリックして送信元アドレスと送信先アドレスを登録します。

4.検証成功ページ

送信元アドレスと送信先アドレスを登録するとそれぞれのアドレスに下記のようなメール(※下記は一部抜粋)が送られ、本文にあるリンクをクリックすると検証成功ページに飛びます。両アドレスとも検証成功ページに遷移することを確認します。

5.ステータス確認

念のため、StatusがVerifiedになっていることも確認します。

テスト実行その1

AWS SES(Sand Box環境)の設定が完了したので、動作確認を行ってみます。

1.メール送信テスト用プログラムを起動

事前準備2で作成したメール送信テスト用プログラムを起動し、Test Mail Sendボタンをクリック後、表示されるダイアログでOKをクリックします。

2.メール送信確認

OK画面に遷移したら送信完了です。送信先メールを確認し、メールが送信されたことを確認できました。

AWS SESの設定その2

Sand Box環境は簡単な動作テストが行える環境のため、下記のような制約があります。
・24時間あたりのメール送信最大件数は200件
・最大送信レートは1秒あたり1件
・送信先アドレスも事前登録する必要がある。
 システムで1日200件しかメールが送れないのは少ないので申請を行ってリミッターを解除します。

1.SES Home画面

SES Home画面左メニューのSending Statisticsをクリック後、Request a Sending Limit Increaseボタンをクリックします。

2.項目設定・送信

下記画面に遷移するので必要な項目を入力して送信ボタンを押します。

《項目説明》*は必須
・CC:リミッター解除報告を行うEmailアドレスを登録します。
・内容*:「サービス制限の増加」(固定)
・制限タイプ*:「SES送信制限」(固定)
・リージョン*:※今回は「米国東部(バージニア北部)」で申請しました。
・制限*:今回は1日あたりのメールの送信最大数を解除しますので、「希望する1日あたりの送信クォータ」で申請しました。
・新しい制限値*:1日あたりのメール送信最大数 ※今回は「20000」で申請しました。
・メールの種類:システムの用途にしたがって選択してください。
        ※今回は「システム通知」で申請しました。
・ウェブサイトのURL:任意です。※今回は設定しませんでした。

・私は AWS サービス利用規約AUP に準拠してメールを送信します:「はい」(固定)
・私は明確にリクエストされた受信者にのみメールを送信します:「はい」(固定)
・バウンスや苦情を処理するプロセスがあります:「はい」(固定)※いいえだと申請が通らない可能性があります。
・申請理由の説明*:正直に書きましょう。
         例)現在弊社で開発中のシステムを利用するユーザーを1000人と見込んでおり、
           利用するユーザーに一日何度かメール通知を行う可能性があるためです。
・お問い合わせ言語*:「日本語」(固定)
・連絡方法*:Web(固定)

3.AWSからのリミッター解除連絡

申請後、1~2日くらいでAmazonから下記のようなリミッター解除の返信(※下記は一部抜粋)がきます。
返信がきたら解除完了です。

テスト実行その2

リミッター解除後、views.py内の送信先をSand Boxに登録されていない送信先アドレスに変更してテスト実行その1と同じ動作確認を行ったところ、下記のようにメールを受け取ることができました。

最後に

軽い気持ちではじめた検証ですが、設定してみるとわからないことも多く、知識を得るための有意義な検証でした。AWS SESは今回の検証のようにMTAのセットアップなしのLocal環境からでもサクッとメールが送れたりするので面白いなと思います。Microsoft Visual Studioで簡単に送信アプリも作れますので是非みなさんもお試しください。