前回の記事に引き続き、Amazon SESについてです。
今回はPythonでbotoを使って実際にAmazon SESを使ってメールを送信したり、メール送信結果の統計情報を取得してみようと思います。
■ botoを利用する
botoはAmazon SESなどAmazon Web Servicesのプロダクト群のAPIを操作できるPython用のライブラリです。
インストール方法については以前、Amazon S3を操作する方法の記事で書いたので、以下を参照してください。
http://blog.flect.co.jp/cto/2011/08/pythonamazon-s3-d36b.html
■ Amazon SESを使えるようにする
botoを使う前にAmazon SESのページへ行き、サービス利用を申し込んでおいてください。
申し込んだ直後に利用できる環境はサンドボックス環境と呼ばれる環境です。1日に200通までの送信、および認証されたメールアドレスにしか送受信できない、という制限があります。サンドボックス環境で十分に検証をしたら、以下からプロダクション環境利用の申請をします。
https://aws-portal.amazon.com/gp/aws/html-forms-controller/contactus/SESAccessRequest
■ SESへの接続
では、これから実際に使ってみます。
環境変数としてAWS_ACCESS_KEY_ID、AWS_SECRET_ACCESS_KEYをあらかじめセットしておけばプログラム中にアクセスキー、秘密キーを記述する必要はありません。以下のような感じで接続できます。
from boto.ses.connection import SESConnection
conn = SESConnection()
ホストの指定も以下のように一応できますが、現状では東海岸しかホストされていないので、あまり指定する意味はないです。
# SESへの接続用オブジェクト作成。現在は東海岸しかホストされていない。
conn = SESConnection(host='email.us-east-1.amazonaws.com')
■ メールアドレスの認証
先ほども記載した通り、Amazon SESでは認証されたメールアドレスしか、送受信できません。
Amazon SESにはVerifyEmailAddressというAPIが用意されていて、これを使うことでメールアドレスの認証ができます。以下のようにして呼び出します。
conn = SESConnection()
conn.verify_email_address('o-masaoki@flect.co.jp')
このAPIを呼び出すと、対象のメールアドレスに認証確認のメールが届き、メール本文内のURLをクリックすると認証成功となります。ListVefiriedEmailAddressesというAPIを呼び出すことで認証済みのメールアドレスのリストを取得できます。たとえば、以下のようにすると呼び出せます。
# 認証済みアドレスの取得(細かいチェック省いています)
response = conn.list_verified_email_addresses()
result = response['ListVerifiedEmailAddressesResponse']['ListVerifiedEmailAddressesResult']
addresses = result['VerifiedEmailAddresses']
for address in addresses:
print address
■ メールの送信
メールの送信はSendEmail APIを使います。使い方は以下のような感じです。
#!/usr/bin/env python
# -*- coding:utf-8 -*-
from boto.ses.connection import SESConnection
# SESへの接続用オブジェクト作成。
conn = SESConnection()
# 送信先のtoのアドレスリスト
to_addresses = [
'o-masaoki+sestest01@flect.co.jp',
'o-masaoki+sestest02@flect.co.jp',
'o-masaoki+sestest03@flect.co.jp',
]
# reply to headerにセットするアドレス
reply_addresses = ['o-masaoki@flect.co.jp']
# SendMail APIを呼び出す
conn.send_email('o-masaoki@flect.co.jp' # from
,u'テスト' # subject
,u'本文のテスト' # body
,to_addresses # toのアドレスリスト
,cc_addresses=[] # ccのアドレスリスト
,bcc_addresses=[] # bccのアドレスリスト
,reply_addresses=reply_addresses # Reply-toヘッダの設定
,return_path='masaoki.ohashi@gmail.com' # bounceメールを返す場所
)
上記のサンプルは日本語が書かれていますが、送信元のプログラムがMac OS
X、受信側のメーラーがGMailという環境では日本語がUTF-8で表示されました。他の環境ではダメかもしれません。SendEmail APIのリファレンスは以下ですが、主要なパラメータについて上記サンプル中のコメントに説明を記載しておきました。
http://docs.amazonwebservices.com/ses/latest/APIReferene/index.html?API_SendEmail.html
SendEmail APIはパラメータにReply-toやbounceメールを指定すると、自動的にメールのヘッダに付与してくれます。文字コードのエンコードの指定やヘッダの細かい制御等を行うにはSendRawEmailというAPIがあります。これについてはまたの機会に書きたいと思います。
■ 統計情報の取得
前回の記事で、ユーザはバウンスメール数などの統計情報のフィードバックを見られる旨を記載しましたが、それが次に説明するGetSendStatistics APIです。この機能と次に説明するQuotaの機能が、Amazon SESのすごく特徴的なところで、Amazon SESの配信性能の仕組みを支えている部分のひとつになります。
まず、GetSendStatistics APIです。このAPIでは15分インターバルで集計される送信メールの統計情報(15分ごとの統計情報のグループをDataPointと言うようです)を取得できます。サンプルは以下の通りです。
#!/usr/bin/env python
# -*- coding:utf-8 -*-
from boto.ses.connection import SESConnection
# SESへの接続用オブジェクト作成。現在は東海岸しかホストされていない。
conn = SESConnection(host='email.us-east-1.amazonaws.com')
# 15分間隔ポイントで統計情報を作成している
response = conn.get_send_statistics()
result = response['GetSendStatisticsResponse']['GetSendStatisticsResult']
points = result['SendDataPoints']
for p in points:
print '----------------------'
print 'time of data point : %s' % p['Timestamp']
# 配信を試みたメール数(配信数)
print 'delivery attempts : %s' % p['DeliveryAttempts']
# 何かしらの原因で不達になったバウンスメール数
print 'bounces : %s' % p['Bounces']
# 苦情として連絡されたメール数(受信者から拒否されたメール数)
print 'complaints : %s' % p['Complaints']
# Amazon SESサービスにより拒否されたメール数。SESのフィルタリングにひっかかったものと思われる。
print 'rejects : %s' % p['Rejects']
print '----------------------'
取得できるのは配信試行数(DeliveryAttempts)、バウンスメール数(Bounces)、受信側から拒否された数(Complaints)、Amazon SESのフィルタリングにより送信拒否となった数(Rejects)の4つの数値とDataPointのタイムスタンプが取得できます。上記のサンプルプログラムだと以下のように出力されます。
----------------------
time of data point : 2011-08-15T02:38:00Z
delivery attempts : 17
bounces : 0
complaints : 0
rejects : 0
----------------------
time of data point : 2011-08-11T15:23:00Z
delivery attempts : 1
bounces : 0
complaints : 0
rejects : 0
----------------------
time of data point : 2011-08-17T15:38:00Z
delivery attempts : 3
bounces : 0
complaints : 0
rejects : 0
----------------------
ユーザはこれを見て、bounces、complaints, rejectsを減らすことによって配信メールの品質を向上させていく必要があります。Amazon SESにはじかれたメールはAPI経由で、バウンスメールはReturn-Pathのメールから判断できるので、それらの内容をよく確認し、配信リストの修正、品質向上に取り組むといいと思います。
■ 配信割当量(Quota)情報の取得
サンドボックス環境だと固定の数値、プロダクション環境だと、送信したメール数、品質によって徐々にアップしていきます。取得できるAPIはGetSendQuotaで、以下のように使います。
# SESへの接続まではGetSendStatisticsのサンプルと同じです。
response = conn.get_send_quota()
result = response['GetSendQuotaResponse']['GetSendQuotaResult']
# 24時間以内に送信できるメール数
print 'max 24 hour send : %s' % result['Max24HourSend']
# 24時間以内に送信したメール数
print 'sent last hour send : %s' % result['SentLast24Hours']
# 1秒間に送信できるメール数
print 'max send rate : %s' % result['MaxSendRate']
上記のサンプルの通り、24時間以内に送信できるメール数、実際に24時間以内に送信したメール数、それと1秒間に何通送信できるか、という割当情報が取得できます。GetSendStatistics APIで品質チェックをして、品質向上と配信数の向上に努めたら、徐々にこの割当がアップしていくようです。なんだか、レベル上げみたいですね。
■ まとめ
前回の記事に引き続き、今回はAmazon SESのAPIをbotoライブラリを使ってPythonでプログラミングする場合の使い方をまとめました。ただ送信するだけではなく、SESからフィードバックをもらい、より高品質なメール配信ができるようにしてもらいたい、というAWS側からの意思みたいなものを感じるAPIですね。
AWSはまだまだ使っていないプロダクトも多いので、今後もいろいろいじってみて実運用につなげていきたいと思います。
■ おまけ ~中途採用のお知らせ~
フレクトではAWSやSalesforceを使ったソリューション事業の拡大をしております。クラウド環境を使った開発に興味がある人はぜひご連絡いただければと思います。以下、採用ページです。
http://www.flect.co.jp/recruit/index.html