sleepingbird.net Home since May.11 2003
Copyright sleepingbird, 1993- All rights reserved.
Linux Server

TOP > Linux Server > Mail server (Postfix) > 自動応答メール (procmail)

自動応答メール (procmail)

Nov.20 2005
 メールを受信した場合、その内容に応じた返信メールを自動で送信したい。
 ネットで検索してみると、procmail というツールがあって、VineLinux にはインストール済みのようだ。

 考え方としては、
  1. 対象となる受信メールを .forward ファイルによって procmail に食わせてやる。
  2. procmail にはレシピと呼ばれる処理手順を書いた指示ファイル .procmailrc を用意する。
  3. 返信用メールを生成するには formail というツールを使う。
 と言うことらしい。

procmail のレシピの構文については、ここが大変参考になった。

formail のオプションは次のとおり
-b 偽のメールボックスヘッダ(「From 」で始まる行)をエスケープしない。
-p 接頭語
前に付ける引用記号を指定する。指定しない場合はデフォルトの「>」が使用される。
-Y 通常の Berkeley 版メールボックスフォーマットを想定し、Content-Length: フィールドを無視する。
-c 複数行にわたるヘッダーフィールドを連結する。標準(行単位で処理する)テキストユーティリティでメールを後処理するときに便利。
-z フィールド名と内容との間にスペースを入れる。スペースだけのフィールドは削除する。-x で取り出されたフィールドの前後のスペースを省く。
-f メールボックスのフォーマットにしたがっていない(「From 」行で始まらない)メールをそのまま通すよう formail に指示する。
-r オートリプライヘッダを生成する。通常、元のメッセージの(X- Loop: を除く)すべての既存フィールドを破棄する。残しておきたいフィールドは -i オプションで指定する必要がある。このオプションを -k と一緒に使用した場合は、-b を指定することでメール本文が「エスケープ」されるのを防止できる。
-k オートリプライヘッダを生成するとき、またはフィールドを取り出すときにメール本文も保持する。
-t ヘッダーに有効な返信アドレスを持つ送信者を信用する。このオプションはオートリプライヘッダをニュース記事から作成する場合に便利。このオプションがオンになっていない場合は、formail はヘッダー中のマシン生成アドレス(Return-Path:)を優先する傾向がある。
-s 入力を別々のメールメッセージに分割し、パイプを通して 1 つずつプログラムに渡す(各パートについて新しいプログラムが開始されます)。-s は最後に指定するオプションでなければならない。これに続く最初の引数はプログラム名であることが想定され、それ以外の引数はそれに沿って処理される。プログラムを削除した場合は、formail は分割されたメッセージを stdout 上に連結する。FILENO を参照。
-n [maxprocs]
formail に各プログラムが終了するのを待たずに次を開始するよう指示する(これは分割されたメールが並行処理されることを意味する)。Maxprocs は並行処理数の上限を任意指定することができる。
-e 新しいメッセージのヘッダーの前に空白行を必要としない(メッセージがどの行から始まってもよいということ)。
-d 分割するはずのメッセージが厳密にメールボックスのフォーマットに適合していな くてもよいと formail に指示する(ダイジェスト/記事の分割や非標準のメールボックスフォーマットを許可する)。このオプションは Content-Length: フィールドの認識を無効にする。
-B formail に BABYL rmail ファイルを分割していると想定させる。
-m minfields
新しいメッセージの開始部分を決定するまでに formail が見つけなければならない連続するヘッダーフィールドの数を指定することができる。デフォルトは 2。
-q formail に(検出はするものの)記述エラー、重複メッセージ、ミスマッチの Content-Length: フィールドについて何もしないように指示する。このオプションはデフォルトではオンになっている。メッセージを表示する場合は、-q- を使用する。
-D maxlen idcache
formail は現在のメッセージのメッセージ ID が既出かどうかをほぼ maxlen サイズの idcache ファイルを使用して検出する。メッセージが分割されていない場合は、重複が見つかったら検出成功を返す。分割されている場合、重複メッセージは出力されない。-r と一緒に使用された場合、formail はメールのメッセージ ID ではなく送信者のメールアドレスに注目する。
-x ヘッダーフィールド
ヘッダーからこのヘッダーフィールドの内容を取り出し1 行に表示する。
-X ヘッダーフィールド
-x と同じだが、フィールド名を保持する。
-a ヘッダーフィールド
指定のヘッダーフィールドをヘッダーに追加するが、同様のフィールドがない場合に限られる。Message-ID: または Resent-Message-ID: のどちらかのフィールド名をフィールドが空の状態で指定すると、formail がユニークな ID を作成する。
-A headerfield
どのような場合にも指定のヘッダーフィールドをヘッダーに追加する。
-i ヘッダーフィールド
-A と同じだが、同様のフィールドは「Old-」という接頭語を前に付けてリネームされる。ヘッダーフィールドがフィールド名だけで構成されている場合は、接頭語は付かない。
-I ヘッダーフィールド
-i と同じだが、同様のフィールドがある場合、元のフィールドが削除される。ヘッダーフィールドがフィールド名だけで構成されている場合は、そのフィールドは削除される。
-u ヘッダーフィールド
最初に現れたフィールドをユニークにし、それ以降に同じものが現れた場合に削除する。
-U ヘッダーフィールド
最後に現れたフィールドをユニークにし、それ以前に同じものが現れている場合に削除する。
-R 旧フィールド 新フィールド
すべての旧フィールド名を新フィールド名にリネームする。
+skip メールを分割する際に最初の skip メッセージを飛ばす。
-total メールを分割する際に最大の total メッセージを出力する。

FILENO

 メールを分割する際に、formail はこの変数に出力されているメッセージに番号を割り当てる。FILENO を事前設定することにより、使用されている最初のメッセージの番号とゼロサプレスされた出力の幅を変更することができる。FILENO が設定されていない場合は、デフォルトの 000 が使用される。FILENO が空白でなく、数字以外のものが入っている場合は、FILENO の生成が無効になる。

 上記考え方の1のために、.forward に次のように記述しておく。
$ vi .forward

"|IFS=' ' && exec /usr/bin/procmail -f- || exit 75 #ユーザー名"

 このサーバーの .procmailrc の例
 Windows小道具集においてリンクされていないものについてフォームメールでリクエストがあった場合に、ダウンロード url を自動返信する。
条件
  1. フォームメールからの送信を対象とする。
  2. フリーメールが指定されていたら Subject の前に Reject: と追加してメールボックスへ保存。返信はしない。
  3. メール本文に記載されているキーワードしたがって返信メールを生成し、メールキューに投げる。

$ vi .procmail

PHOME=$HOME/procmail 設定ファイルのありか
LOGFILE=$PHOME/procmail.log ログファイル名
LOCKFILE=$PHOME/.lockfile ロックファイル名
MAILDIR=$HOME/ メールディレクトリ

LIST=$PHOME/freemail.txt フリーメールドメイン一覧リスト

SUBJECT=`formail -c -xSubject:` 送信メールから Subject 取得

:0
* ^Return-Path: <apache@qcp.jp> フォームメールからの送信を対象
{
:0 h f フリーメールが指定されていたら Subject の頭に Reject: を追加して終わり
* ? (formail -x From: | fgrep -iqf $LIST)
|formail -i "Subject: Reject: $SUBJECT"

:0 Ec Subject 名が対象メールであるものを処理
* ^Subject: TargetSubject
{
:0 B メール本文をチェック対象
* ^Title: .*Modules1.* KeyWord チェック
| (formail -rtA "Precedence: junk" \
-A "X-Loop: mailaddress@qcp.jp" \
-A "Content-Type: Text/Plain; charset=iso-2022-jp" \
-I "Subject: sleepingbird.net auto Reply Mail" \
-A "From:information <mailaddress@qcp.jp>" ;\
cat $PHOME/info.txt; \
cat $PHOME/Modules1.txt; \
cat $PHOME/signature.txt; \
) | $SENDMAIL -oi -t

:0 EB
* ^Title: .*Modules2.* 
| (formail -rtA "Precedence: junk" \
-A "X-Loop: mailaddress@qcp.jp" \
-A "Content-Type: Text/Plain; charset=iso-2022-jp" \
-I "Subject: sleepingbird.net auto Reply Mail" \
-A "From:information <mailaddress@qcp.jp>" ;\
cat $PHOME/info.txt; \
cat $PHOME/Modules2.txt; \
cat $PHOME/signature.txt; \
) | $SENDMAIL -oi -t

:0 EB
以下同様につづく
}
}

 注意事項
  1. フリーメール一覧リストファイルは UNIX 形式(改行コード=LF)。Windows で作成したファイルは CRLFとなるので一切マッチしなくなる。(ハマった(T_T))
  2. formail オプションに -t を使用する。これがない場合にはリプライが Return-Path: に設定されたアドレス(=apache)あてとして生成される。
    この指定により From: に設定されたアドレスあてとなる。
 なお、上記1を回避するために次のコマンドにより CR コードをファイルから削除できる。
$ perl -i.old -npe 's/\r\n/\n/' ファイル名
 Windows では改行コードの相互変換プログラムもある。

 なお、受信されたメール本文中に KeyWord が記述されていることを担保するために、フォームメールからの送信に限定している。
 実際の例はこちら