2010年3月にオープンソースソフトウェアとして公開して以来、多くのユーザ様・企業様にダウンロードし、 ご利用いただきましたbounceHammerは、2016年2月29日(月)を持ちまして製品ライフサイクルの終了(EOL: End Of Life) となりました。長きにわたりbounceHammerをご使用いただき誠に有り難う御座いました。 開発元では後継となるバウンスメール解析ライブラリとして、より高精度で高速なSisimai(シシマイ) を二条項BSDライセンスで公開しています。
2010/11/08
通知関係の連絡を電子メールで配信するWebサービスでは、無料でサイトが利用できるかわりに広告も表示される、 あるいは定期的に広告を含んだメールを受け取る、というユーザ側が負担すべき部分があります。
しかし、特に携帯電話では多いと思いますが、ユーザがメールアドレスを変更したり、 ドメイン指定拒否の設定解除を忘れていたりして、 配信したメールが到達できないという状態にあるユーザも多々いるのではないでしょうか。
多くのユーザは自分のメールアドレスを変更しても、登録しているサイト側で変更手続きを 忘れてしまっているでしょう。サイト運営側としては登録アドレスの変更もしてほしい所ですが、 メールはバウンスしてしまうので、その旨を通知する手段としてはユーザのログイン後の 画面ぐらいしかなさそうです。
前置きが長くなりましたが、Webサービスの中でbounceHammerが解析した結果を照合する簡単な例を紹介します。 HTTP-APIはブラウザでも動作の確認ができます。
bounceHammerのHTTP-APIはJSONで出力します。 これはWebサイト側でJavascriptでも処理できるようにするためです。 bounceHammerが出力する解析結果のデータはYAMLでもJSONでも同一の 内容・フィールド名(Key)ですので、既にYAMLを読み込んで照合するコードを書いている場合は、 ほぼ修正する事なく再利用できるでしょう。
メールアドレスの照合は、 YAMLファイルでアドレス照合 でも紹介しているように、解析結果のYAMLファイルを読込んで逐一照合する方法もあります。 しかし、Webサービスの画面内に表示させるためだけに大量の解析結果を含むYAMLファイルを 読込ませるのは非効率的です。
そこで、指定したメールアドレスに一致する解析結果だけを取得できるAPIを使うと、 ユーザ毎に必要なデータだけを取得し、必要な部分だけをユーザの画面に表示させる という効率的な照合が可能です。
最も簡易なAPIを使ったアドレス照合用のサンプルコードは、 bounceHammerのソースアーカイブ/examples/request-to-api.* に同梱しています。
Perl, PHP, Python, Rubyの四種類を用意していますが、JSONを読込める・JSONを読込めるライブラリ がある言語であればなんでも実装できるでしょう。
つまり、Webサイト側がどのような言語で書かれていてもJSONが読込めればアドレス照合機能を実装できる、 というわけです。ここではHTTPベースの API(search)を使ってみます。
#!/usr/local/bin/perl use strict; use warnings; use LWP::UserAgent; use JSON::Syck; use Time::Piece; my $maildomain = 'example.jp'; # Webサイトのメールドメイン my $bounce = {}; # テンプレートに渡すORページに表示する元データ用 my $message = q(); # 表示する文言 my $siteuser = ユーザデータのオブジェクトを作る; my $httphost = 'http://192.0.2.25/bouncehammer/a.cgi'; my $useragent = new LWP::UserAgent(); my $response = $useragent->request( HTTP::Request->new( GET' => $httphost.'/search/recipient/'.$siteuser->mailaddress() )); my $metadata = JSON::Syck::Load($response->content()) || []; foreach my $j ( @$metadata ) { if( $j->{senderdomain} eq $maildomain ) { $bounce = { 'reason' => $j->{reason}, 'date' => Time::Piece->new( $j->{bounced})->cdate() ), 'from' => $j->{addresser} }; } } $message .= '登録されているメールアドレス' . $siteuser->mailaddress(); $message .= 'は、' . $bounce->{from} . 'から' . $bounce->{date}; $message .= 'に配信した際に' . $bounce->{reason} ' . 'のエラーで'; $message .= '配信できませんでした。'; ... テンプレートに渡す処理またはページの描画など;
上記のコードでは解析データのaddresser(配信したメールのFromアドレス) を検査しています。これはサイトをたくさん運営していて、ユーザがその複数に登録 している場合、今ログインしているサイトとは別のサイトが配信した結果の解析データ を間違って表示しないようにするためです。
Webサイトがひとつ(Fromアドレスも一種類)であれば、前掲のコード例のようにわざわざif() で検査しなくてもよいでしょう。逆にたくさんのサイト・たくさんのFromドメイン・Fromアドレスがある 場合は、foreachで廻すのは合理的ではありませんので、その場合はメッセージトークンを 作って、その値で検索してください。メッセージトークンについての説明は データ構造 の一番下、メッセージトークンの項目をご覧ください。
こではHTTPベースの
API(select)
を使います。APIで照合するために必要なトークン文字列を
sprintf, md5_hex()で予め作成しています。
#!/usr/local/bin/perl use strict; use warnings; use LWP::UserAgent; use JSON::Syck; use Digest::MD5; use Time::Piece; my $mailfrom = 'info@example.jp'; # Webサイトのメールアドレス my $bounce = {}; # テンプレートに渡すORページに表示する元データ用 my $message = q(); # 表示する文言 my $siteuser = ユーザデータのオブジェクトを作る; my $httphost = 'http://192.0.2.25/bouncehammer/a.cgi'; my $token = Digest::MD5::md5_hex(sprintf("\x02%s\x1e%s\x03", $mailfrom,$siteuser->mailaddress)); my $useragent = new LWP::UserAgent(); my $response = $useragent->request( HTTP::Request->new( 'GET' => $httphost.'/select/'.$token )); my $metadata = JSON::Syck::Load($response->content()) || []; if( scalar @$metadata ) { $bounce = { 'reason' => $metadata->[0]->{reason}, 'date' => Time::Piece->new($metadata->[0]->{bounced})->cdate(), 'from' => $metadata->[0]->{addresser} }; } $message .= '登録されているメールアドレス' . $siteuser->mailaddress(); $message .= 'は、' . $bounce->{from} . 'から' . $bounce->{date}; $message .= 'に配信した際に' . $bounce->{reason} ' . 'のエラーで'; $message .= '配信できませんでした。'; ... テンプレートに渡す処理またはページの描画など;
上記のコードも、最初に例示したコードとほぼ同じです。多数のWebサイトがあって、 更に多数のFrom(ドメイン・アドレス)があり、それらから配信されるメールのバウンス 記録がひとつのbounceHammerのデータベースに蓄積されている場合は、メッセージトークン で検索をする方が余計なデータベース負荷をかけずにすみます。
BOUNCEHAMMER.JP |
Copyright 2009-2016 Cubicroot Co. Ltd.
(Kyoto, Japan) All Rights Reserved.
Powered by Linode - Xen VPS Hosting.
Blue Retro Rusted Grunge Icons by Icons Etc.