Amazon SES

2011年8月18日 (木)

Amazon SESをbotoを使ってPythonで操作する

前回の記事に引き続き、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

2011年8月17日 (水)

Amazon SESとメール配信の難しさについて調べたこと

Amazon SESについて簡単に調査、試用してみたので記事にしてみます。
記事は2回構成で、今回はAmazon SESの特徴をドキュメントベースに調査したものをまとめました。次回、実際にAmazon SESでプログラミングした記事をアップします。

■ 動機と調べたことの概要

メール配信のソリューションはいろいろなベンダーが、魅力的なサービスを展開していますが、初期費用が高かったり、ランニングも場合によってはけっこう高かったりと、やや高価な感が否めません。(そうではないものもあると思いますが)

そう思っていたところでAmazon SESを見つけたので調べてみました。(前からAmazon SES自体は知ってましたが、調べるのが今になってしましまいした・・・)

Amazon SESは初期費用はいらず従量課金の低コストで提供されるメール送信サービスです。1000通あたり0.1ドルと非常にリーズナブルです。

費用以外では、確実にメールを届ける配信性能を売りとしています。メールを送信すれば届くというのは意外と当たり前のようなことですが、大量にメールを送るときに確実にすべての受信者に届けるのはかなり難しいです。

なので、どの辺が難しいか、Amazon SESは何を配信性能とはどういうことなのかメール配信について初心者の自分の理解するのためにまとめてみました。

■ 確実にメール配信するために必要なこと

Eメールを使わないネットサービス、業務システムは少ないと思います。特にコンシューマ向けのPC、モバイル向けのWebサイトではメールマガジンなど大量にメールを送信しなければいけないケースが少なくないです。

メールを送る処理は1通の送信ならばそんなに難しくないですが、マーケティング要素が強い大量メールの配信というのはかなり難しいです。たとえば、以下のような要件をクリアしないといけません。

 ・バウンスメールの処理をきちんとしてISP等でブロックされないようにする
   例)存在しないメールアドレスに対してISPにメールを大量に送るとブロックされたりする

 ・送信できなかった場合の再送処理
   例)IPベースでISPでブロックされた場合、別のIPから送りなおすなど

 ・送信量の制御をしてISPの制御にひっかからないようにする
   例)モバイルのキャリア(ドコモ)などに短い時間で大量に送信すると
      送信ブロックをされることがあるなど

 ・複数台構成で信頼性の高いメール配信サーバを容易する

 ・SPF/Sender IDなどの設定

もう、なんかこれだけで大変そうです。おなかいっぱいですね。

■ スパムフィルタがメール配信を難しくする大きな原因

次に、なぜこんなにメール配信がこんな難しい要件になっているか、についてです。

その原因はどうやらISPのスパムフィルタにあるようです。つまり、届くべきメールまでスパム扱いされているということが原因のようです。

たとえば、情報ソースはやや古いですが、以下のような記事があります。

・メールの0.71~1.02%は「ただ消えて無くなる」~Microsoft研究者らが論文
 

上の記事では以下のような原因でメールは届かなくなるケースが多いとあります。

  •  ISPにて送信元のIPアドレスをフィルタリングしてホワイトリストにないか、ブラックリストに入っていたら、メールを除去
  •  (一か所から)一定量以上(おそらく大量)のメールが送信されている場合
  •  HTMLメールかつ特定の文面が含まれている場合

また、モバイルサイトを開発した人ならば見たことがある人も多いドコモの以下のページも参考になります。

http://www.nttdocomo.co.jp/service/communication/imode_mail/notice/mass_send/index.html

これによると、ドコモ側としては主として

  •  過剰なSMTPセッション数
  •  1セッション(短時間)の送信数
  •  大量の宛先不明を含むメール

などが検知されると、迷惑なメール配信業者という扱いをするようですね。

 

まとめると、

  •  メール不達の原因の大きなものはISPなどにスパム扱いされてしまいブロックされている
  •  短時間に大量のメール送信、宛先不明のアドレスに大量送信、をするとスパム扱いされやすい(下手するとブラックリストに入ってしまう)

ということのようですね。

■ Amazon SESの配信の信頼性を向上させる仕組み

ここで、やっとAmazon SESについて調べたことに入ります。(前置きが長いですね、すみません)

Amazon SESにはメール配信の信頼性を向上させるためにAmazon SES自体を外部ISPからの信頼性を損ねないよう、ISPのスパムフィルタにひっかからないようにする仕組みがあるとのことです。

具体的には、主に以下の手段で配信されるメールを高品質であるよう保ちます。

  1.  Amazon SESのフィルタリングによりスパムメールの可能性が高いメールは外部へ配信しない。
  2.  ユーザにメール品質向上のためのフィードバック情報を提供し、品質向上できるようにする。
  3.  ユーザには急激なメール送信の増加をさせず、段階的にユーザのメール送信量を増やすようにし、継続的に高品質なメールを配信するユーザのみ大量メール配信できるようにする。

まず(1)ですが、スパムメールやその他低品質なメールはAmazon SES自体がそれらのメールを外部に送信しないばかりか、ひどい場合はアカウントの停止もあるとのことで、徹底して低品質なメールを外部に出さないようにしています。

次に(2)では、ユーザに対してバウンスメールの数、苦情メールの数など統計情報を提供し、ユーザ自身がそれらの統計情報を元にメールの品質を向上できるようにします。(具体的なAPIは次の記事で紹介します)

最後の(3)ですが、たとえば、プロダクション環境では最初は24時間に1000通のみの配信ができますが、高品質なメール配信を続けるとその制限が徐々に緩和され、10日間かけて10,000通程度メールが送れるようになります。その間、Amazon SESはそのユーザから送られるメールについて高品質なメールを送りつづけているか評価し、制限の緩和を判断するようです。
(参考:http://docs.amazonwebservices.com/ses/latest/DeveloperGuide/)

これらのことを実施することにより、Amazon SES自体から発信されるメールが各ISPのブロックにかからないようになり、高い配信性能が保たれるということのようです。

■ 他サービスとの比較や気になる点

Amazon SESは「開発者のみなさんも品質向上に協力してね!」という姿勢が他社のサービスと比較すると強く感じます。セルフサービス要素が強い感じ。

国内にある他のメール配信サービス業者などでは、基本的には法人による契約なので、Amazon SESと同様の取り組みなどは必要ないのだと思います。

他のメール配信業者はより高価ですが、配信性能だけではなく、開封情報の取得や不達の管理や、ドコモ等キャリアへのメール配信など、Amazon SESにはない機能も備えているので、実は単純には価格では比較できるものではなく、それぞれの用途によって使い分けましょう、という話になるのかと思います。当たり前ですが。

実運用を見据えると、やはり国内用途ではドコモ、au、ソフトバンクの携帯メールへの配信は大丈夫かな、というのが気になります。たとえば、配信性能は満たしたとしても、配信の高速化(並列化)などはどれくらいできるのだろうか、、、など。機会があったら調べてみたいと思います。

■ まとめと次回

Amazon SES自体はまだベータ版で、導入例などもどれくらいあるかわからないので、当社でも実戦投入はまだ先なのかなとは思いますが、初期費用なく、ランニングも少ない、そして簡単なAPIで使え、配信性能もよい、ということでいつか実戦投入を模索したいな、と思います。

次回は実際にAmazon SESのAPIを使ってプログラミングをしてみたまとめなどを書きたいと思います。

■ おまけ ~中途採用のお知らせ~

フレクトではAWSやSalesforceを使ったソリューション事業の拡大をしております。クラウド環境を使った開発に興味がある人はぜひご連絡いただければと思います。以下、採用ページです。

http://www.flect.co.jp/recruit/index.html

採用情報

株式会社フレクトでは、事業拡大のため、
・Salesforce/Force.comのアプリケーション開発
・HerokuやAWSなどのクラウドプラットフォーム上での
Webアプリケーション開発
エンジニア、マネージャーを募集中です。

未経験でも、これからクラウドをやってみたい方、
是非ご応募下さい。

フレクト採用ページへ

会社紹介

株式会社フレクトは、
認定コンサルタント
認定上級デベロッパー
認定デベロッパー
が在籍している、セールスフォースパートナーです。
また、heroku partnersにも登録されています。
herokuパートナー
株式会社フレクトのSalesforce/Force.com
導入支援サービス
弊社の認定プロフェッショナルが支援致します。
・Visualforce/Apexによるアプリ開発
・Salesforceと連携するWebアプリ開発
も承っております。
セールスフォースご検討の際は、
お気軽にお問合せください。

2017年12月

          1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
31            
ブログ powered by TypePad