質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Apache

Apacheは、Apache HTTP Serverの略で、最も人気の高いWebサーバソフトウェアの一つです。安定性が高いオープンソースソフトウェアとして商用サイトから自宅サーバまで、多くのプラットフォーム向けに開発・配布されています。サーバーソフトウェアの不具合(NCSA httpd)を修正するパッチ(a patch)を集積、一つ独立したソフトウェアとして開発されました。

SMTP

SMTP(Simple Mail Transfer Protocol)はIPネットワークでemailを伝送する為のプロトコルです。

Ruby on Rails

Ruby on Railsは、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

Postfix

Postfixは、電子メールサーバソフトウェアで、 メールを配送するシステムMTAの一種です。

Q&A

5回答

8045閲覧

サーバーからのメールの一斉配信機能において、無効なメールアドレスに何度も送りつけるのを防ぐ機能を実装したい

kento2543

総合スコア163

Apache

Apacheは、Apache HTTP Serverの略で、最も人気の高いWebサーバソフトウェアの一つです。安定性が高いオープンソースソフトウェアとして商用サイトから自宅サーバまで、多くのプラットフォーム向けに開発・配布されています。サーバーソフトウェアの不具合(NCSA httpd)を修正するパッチ(a patch)を集積、一つ独立したソフトウェアとして開発されました。

SMTP

SMTP(Simple Mail Transfer Protocol)はIPネットワークでemailを伝送する為のプロトコルです。

Ruby on Rails

Ruby on Railsは、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

Postfix

Postfixは、電子メールサーバソフトウェアで、 メールを配送するシステムMTAの一種です。

0グッド

4クリップ

投稿2015/08/13 06:48

現在運営しているwebサービスにメールの一斉配信機能をつけようと思っております。

webサービスの方は
・apache
・rails
で運用しております。

メール一斉配信機能をつけるにあたり、一番懸念していることは無効なメールアドレスに何度も送りつけてしまうことです。

これを防ぐためにはどういったことをしてあげればよいのでしょうか?
(質問1)

無効なメールアドレスを手作業で消していくのではなく、機械的に消していって欲しいです。
※消すといっても、論理削除などを考えております。

また、メールの一斉配信において、ゆくゆくはターゲットを絞り込んでの配信などをしていきたいのですが、こういうのはpostfixなどで出来ますでしょうか?(postfixで出来る場合は、入れるべきライブラリを、それ以外の場合は、どういうソフトウェアがよいか教えて頂けませんか?)
(質問2)

有償でメールの一斉配信が簡単にできるソフトはたくさんありますが、
社内の技術力アップも踏まえ、今回はオープンソースのソフトウェアを用いて社内開発していきたいと考えております。

とはいえど、社内にメール配信機能を実装したことがある方がいないため、手探り状態です。
お手数ですが、ご教示頂けると幸いです。

宜しくお願いします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答5

0

幾つかの回答で、バウンスメール(エラーメールとかリターンメールと呼ばれたりもする)を元にメールの送信失敗を検出する方法が示されていますが、バウンスメールから元の送信先メールアドレスを導出する方法について。

メール送信時の Return-Path を次のような形式にします(MTA が postfix 場合)。

bounce+{送信先メールアドレスごとに一意な値}@oreore.example.com

{送信先メールアドレスごとに一意な値} は、送信先メールアドレスごとに採番されたIDのようなものでもいいし、送信先メールアドレスを適当にエンコードした文字列でも良いです。

{送信先メールアドレスごとに一意な値} の前の + は、MTA(Postfix とか qmail とか)によって異なりますが、拡張メールアドレスと呼ばれるもので、bounce+extext の部分がどのような文字であったとしても、同じ宛先として扱うことができる機能です。

これを利用することで、bounce+ から始まるすべてのメールを1つのプログラムで処理させることができるので、前述のように + 以降の部分に元の送信先アドレスが特定出来る情報を埋め込んでおけば、バウンスメールから直ちに元の送信先アドレスを特定することができます(バウンスメールの中身を解析しなくても、バウンスメールで返ってきたことだけなら簡単に判断できる、ということです)。


バウンスメールをプログラムで処理させる方法ですが、大抵の MTA ではメールの受信時に特定のプログラムにメールを渡すことができるようになっています。

例えば、postfix ならユーザーのホームディレクトリに .forword というファイルを次のような内容で作成しておけば、メールの受信時にそのプログラムを実行させることができます。

|/path/to/program

bounce というユーザーを作成し、そのホームディレクトリに .forword.forword+default だったかもしれない)というファイルを上のような内容で作成しておけば、送信したメールがバウンスメールとして帰ってくるたびにそのプログラムが実行されるようになります。

bounce ユーザーを作らなくてもトランスポートマップとかでどうにかする方法も考えられますけれども)

投稿2015/08/14 06:59

ngyuki

総合スコア4514

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

メールを送信する際にリターン先メールアドレスも設定しておきます。
届いたリターンメールをCRON等で定期チェックしてメールアドレスを抽出し、3回送れなかったらそれ以降は送らないなどの処置とします。
リターンメールを返すかどうかは相手のサーバー次第ですのであて先不明(ドメインは有るがメールアドレスが無い場合など)の場合は何も返ってこない場合が多いです。と言うのは、リターンメールによるサーバーの負荷やトラフィック増大を防ぐ理由によるものです。また、リターンメールの書式は相手サーバーの自由ですのでメールアドレス自動抽出プログラムは高い頻度で見直す必要が有るかも知れません。
そもそも相手先が存在しない場合(ドメインが無いなど)は送信先が存在しないのでリターンメールが返ってくることは有りません。(サーバーによっては送信元サーバーが送信者に何らかのメッセージを返すかもしれません)。送信元サーバーでメールキューに保留となり、何回かの送信リトライ後の数日後にはキューは消去されますがこれもチェックする必要があるでしょう。メールキューの確認は通常ルート権限が必要です。
リターンメールには様々なエラーコードが付加されてきます。これもチェックして適切な振り分けを行った方がいいでしょう。
不完全なまま運用を開始するとあなたの収容されているサーバーがスパムメール送信元と同じ扱いになってしまう恐れがあり、周囲のサーバーも巻き込んでブロックリスト(ブラックリスト)に登録されてしまい、あなたのサーバーからのメールは相手サーバーが拒否するようになってしまうかもしれません。
https://ja.wikipedia.org/wiki/DNSBL
例えば SPAMHAUS(https://www.spamhaus.org/)にブラックリストとしてあなたのサーバー(IPアドレス)が登録されてしまった場合で、受信元がスパムメール防止策の一つとしてSPAMHAUSを参照していた場合、メールは受け取り拒否されてしまいます。この場合は、SPAMHAUSへ登録解除申請を行います。通常数日後には解除されます。SPAMHAUS以外にも同様なサービスはすぐに100団体以上見つかります。例えばこちらで自サーバーのIPアドレスを入れて、ブラックリスト登録されていないか一括チェックできます。http://whatismyipaddress.com/blacklist-check
この様なサービスは色々あり、「blacklist check」で検索するといくつか見つかります。
つまり、エラーコードを見て受け取り拒否されているか否か、理由も確認する必要があります。
と、実装する機能が多岐にわたります。
よって、送信先が少なければ問題は起きにくいでしょうけど、十分注意いただくことをお願いしたいです。
私もこれら問題を全て経験してきました。結局メール送信ASPを使う方がコストが安いことに気づき、今現在はメール一斉送信の運用は有りませんが、その時が来たら外部サービスを使用するつもりです。

投稿2015/08/13 16:32

編集2015/08/13 16:35
rik

総合スコア1151

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

kento2543

2015/08/14 07:06

色々と有益な情報有り難うございます。 一度勉強のためにも自社構築を試みて、コスト面等も考え、 メール送信ASP等も視野にいれ、考えていきたいと思います。 先人の方々の知恵を拝借でき、非常に助かります。
guest

0

perl製ですが、こんなツールもあります。
ひょっとしてお役に立ちませんか?
bouncehammer

投稿2015/08/13 12:34

pi-chan

総合スコア5936

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

kento2543

2015/08/13 14:52

URLの共有有り難うございます。 すべてを見きれておりませんが、すごく役立ちそうです。 社内でこういったツールを作れたらなって思ってましたが、 既存のツールを使うのもありですね。 参考にさせて頂きます!
guest

0

メールの不達にはいろいろなパターンがありますが、

  1. ドメインが存在しない。または期限が切れている
  2. ドメインが存在しているがユーザーが存在していない
  3. メールボックスがいっぱいである
  4. 送信したメールが大きすぎる

3,4についてはいずれ回復するかもしれないので無効にする必要はない。
1,2については無効にする

ruby についても下記記事を見る限り、php と仕組みは同じようなので、php で検証コードを書きますね。

Rubyでメールを送る

php

1<?php 2 3ini_set('display_errors', 1); 4error_reporting(E_ALL); 5 6require_once('PHPMailer/class.phpmailer.php'); 7 8function send($strRecipient) 9{ 10 mb_language("japanese"); 11 mb_internal_encoding("UTF-8"); 12 13 $mail = new \PHPMailer(); 14 $mail->CharSet = "iso-2022-jp"; 15 $mail->Encoding = "7bit"; 16 17 $mail->AddAddress($strRecipient); 18 $mail->From = "送信アドレス"; 19 $mail->FromName = mb_encode_mimeheader( 20 mb_convert_encoding( 21 "送信アドレス" 22 , "JIS" 23 , "UTF-8" 24 ) 25 ); 26 $mail->Subject = mb_encode_mimeheader('テスト送信'); 27 $mail->Body = mb_convert_encoding( 28 'テスト送信' 29 , "JIS" 30 , "UTF-8" 31 ); 32 33 if (!$mail->Send()) { 34 echo $strRecipient . ":" . $mail->ErrorInfo . "\n"; 35 } else { 36 echo $strRecipient . ":" . "success\n"; 37 } 38} 39 40$email = array( 41 'valid_user@exist_domain' 42 , 'invalid_user@exist_domain' 43 , 'invalid_user@invalid_domain' 44); 45 46foreach ($email as $strRecipient) { 47 send($strRecipient); 48}

いずれも「送信成功」になってしまいます。

プログラムで送信時に取得できるのはあくまで、sendmailやpostfix などのミドルウェアに処理を渡したことについて成功したか失敗かを取得します。

精度の高い仕組みにするには、送信アドレスに帰ってくるエラーメールを定期的にメールボックスをチェックし、エラーメールの本文を解析して該当の送信先アドレスを無効にするという仕組みになります。

投稿2015/08/13 08:11

退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

kento2543

2015/08/13 12:29

ソースコードと共に、わかりやすい解説有り難うございます。 phpもしくはrubyでのソースコード内ではメールの不達を検知することは難しいということですよね? Kousukeさんが仰られていた「送信アドレスに帰ってくるエラーメールを定期的にメールボックスをチェックし、エラーメールの本文を解析して該当の送信先アドレスを無効にするという仕組み」というのを一度考えてみたいと思います。
退会済みユーザー

退会済みユーザー

2015/08/13 12:31

> phpもしくはrubyでのソースコード内ではメールの不達を検知することは難しいということですよね? 難しいではなく、不可能です。
kento2543

2015/08/13 14:48

不可能なんですね。有り難うございます。
guest

0

メールは送付してみないと実際に届くかどうかわかりません。ただ、キャリアからスパムアカウントとして扱われたりしてユーザーに届かないこともありうるので、いきなり論理削除をするのもまずいでしょう。

  1. 送付してみてエラーが発生したらエラーカウントをインクリメント
  2. 送付してみて成功したらエラーカウントを0にする
  3. エラーカウントが一定数を超えたアカウントを論理削除

というのはいかがでしょうか?

SMTPもエラーコードが定義されています。4xxや5xxです。これらに該当するコードが送信時に返ってきたら上記のカウント処理を行ってみてはいかがでしょうか?

参考: SMTP/POP3 プロトコルエラー応答一覧

投稿2015/08/13 07:08

退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2015/08/13 08:00 編集

上記の回答に対するツッコミのつもりで書いたんですが、わかりにくかったですね。回答に差し替えます。
退会済みユーザー

退会済みユーザー

2015/08/13 07:53

こちら回答ですよね。コメントになってしまってます。
kento2543

2015/08/13 12:31

ご回答有り難うございます。 エラーカウントをインクリメントして一定数以上になると論理削除というやり方は非常に興味深く、勉強になりました。 これらを参考にメール配信機能実装に取り組もうと思います。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問