shimookaです。
今回はメールの自動振り分けによく使われるprocmailについて書いてみました。
procmailとは?
procmailは古くからあるメールフィルタソフトです。主にメールの振り分けを行うために利用されます。
procmailは2001/09/10にリリースされたver.3.22が最新版となっていて、最も広く普及しているMDAの一つです。多くのLinuxディストリビューションでもrpm・devパッケージが用意されています。また、Postfixのパッケージなどでは、あらかじめ設定が用意されていたりします。
procmailの基本的な使い方
procmailを使ってメールを振り分ける場合、$HOMEディレクトリ直下に「.procmailrc」というファイルを作成し、振り分け条件や条件にマッチした場合の処理を記述します。
.procmailrcの書式は以下の通りで、procmailではレシピ(recipe)と呼んでいるようです。
:0 [フラグ] [:[ローカルロックファイル名]]
[条件]
[条件]
:
[処理内容]
フラグには条件の対象の制限(メールヘッダ、ボディ)やレシピの実行可否などを指定します。条件にはマッチさせる正規表現を記述します。なお、条件は1行に1つ、行頭は「*」である必要があります。処理内容には、メール転送やパイプを使って外部コマンドにメール内容を引き渡すことも可能です。以下は、.procmailの簡単なサンプルです。
SHELL=/bin/sh
# サービス用サーバからのメール、かつ、Subjectの先頭が文字列"[ALERT]"
# である場合、何はともあれ、携帯に転送する。。。 orz
# (ただし、日本語メールは考慮していない)
:0H:
* ^From: user\@example\.com
* ^Subject: \[ALERT\]
!example@xxxxxx.ne.jp
# デフォルトの転送先。
# 書かなければ、$MAILDIRへ(通常はローカルのメールボックス)
:0
!myaddress@example.com
.procmailrcファイルの具体例ですが、一番知られている例はspamassassinとの組み合わせでしょうか。以下のような感じです。
SHELL=/bin/sh
LOGFILE=$HOME/.procmailrc.log
SPAM=$HOME/imap/SPAM_Trash
DOUBT=$HOME/imap/doubt
:0fw: spamassassin.lock
| spamassassin
:0H:
* ^X-Spam-Level: \*\*\*\*\*\*\*\*\*\*+
* ^X-Spam-Flag: YES
/dev/null
:0H:
* ^X-Spam-Flag: YES
$SPAM
:0H:
* ^X-Spam-Level: \*\*\*\*\*\*\*\*
$SPAM
:0
* ^Subject:.*\[SPAM\]
$SPAM
なお、.procmailrcの詳しい書式については、procmailrc(5)もしくはJM Projectのページを参照してください。
procmailでエラーメール処理を考えてみる
いきなり話が飛びますが、多くのサービスで「メールを使ってユーザーに通知する」ということを行っていると思います。メルマガもそうですね。しかし、メールアドレスが変わったとか登録時の入力ミスなど、様々な理由で配信できないメールの処理に頭を悩ませることになりがちです。
ここで、procmailを使ったエラーメール処理を考えてみると、エラーとなった送信先アドレスを抽出することはできそうです。ただし、メールヘッダだけエラーメールかどうかの判断が難しいので、メールBodyで判断することになります。
SHELL=/bin/sh
ADDRESSES_FILE=$HOME/error_addresses.log
:0 Bi
* ^.*The Postfix program
* ^.* said: 5[0-5][0-9]
* ^.*\.\.\. Unknown user
* Final-Recipient: rfc822; \/.*
| echo "$MATCH" >> $ADDRESSES_FILE
:0 Bi
* ^\/<[^>]+>:
* ^User Not Found
| echo "$MATCH" | sed -e "s/.*<\([^>]\{1,\}\)>.*/\\1/g" >> $ADDRESSES_FILE
かなりベタベタなレシピですが、これをエラーメール受信専用のアカウントの.procmailrcとして用意しておけば、送信先アドレスをうまく抽出することができます。その後は、出力したファイルをバッチでDBに登録するなどが可能になります。また、上の例はパイプでファイルに出力していますが、そのままDB登録用のコマンドに渡してしまうことも可能と思います。
ただし、送信先のMTAによってメッセージが変わったりしますので、残念ながら、実際には上記だけで全て対応できません。もし、もっとスマートな方法をご存じの方は、コメントやトラックバックなどで教えて下さい ;-)
まとめ
自宅サーバなどでimapを使っている方は、メール振り分けなどですでにprocmailを使っているかも知れませんね。ただ、メールの振り分けだけではなく、パイプで外部コマンドに渡してやると様々な処理ができます。その組み合わせ次第で、もっと簡単に面白いことができるんじゃないかと思っています。
是非、一度お試しを:-)
参考URL
以下のサイトを参考にさせていただきました。改めて感謝いたします。