特定のユーザーが電子メールを受信するたびにスクリプトを実行するにはどうすればよいでしょうか?

特定のユーザーが電子メールを受信するたびにスクリプトを実行するにはどうすればよいでしょうか?

私は(Linux)メールサーバーを持っています。postfixメールを受信するため、amavisd-newコンテンツフィルタリング(clamavおよびを使用SpamAssassin)の場合、およびdovecot配信と IMAP 用。

特定のメールボックスにメールが届くたびにスクリプトが実行される設定にしたいと思います。スクリプトは、必ずしもメッセージの内容やヘッダーについて知る必要はありません。少なくとも 2 つのオプションを知っています。

  1. 使用postfixの組み込みフィルタリング。ヘッダー チェックを設定して、このメールボックス宛てのすべてのメールをスクリプトに再ルーティングし、スクリプトから に返しますpostfix。ここでの欠点は、すべてがamavisのフィルタリングの前に行われるため、配信前にブロックされてしまうメールに対してもスクリプトが実行されることです。また、メールを に適切に返さないと、パフォーマンスが低下したり、メールが失われるリスクもありますpostfix

  2. 私のスクリプトをコンテンツ フィルターとして に追加しますamavis。これは、以前のものと比較してパフォーマンスが向上する可能性があり、これに適した場所のように思えます。残念ながら、メッセージに対して go/no-go の決定が行われる前に実行されるという問題が依然としてあります。さらに、amavisこれを実際にどのように行うべきかを詳しく説明したドキュメントを見つけることができず、conf ファイルも決定的ではありません。

最終dovecot配信ステップは、フィルタリングされたメールのみを取得するのに最適な場所のようですが、それが機能する方法があるかどうかはわかりません。

何か提案はありますか? 何か見落としている点はありますか?

編集:追加するのを忘れましたが、ポーリングタイプのソリューション (ログの監視、IMAP クライアント スクリプトなど) は避けたいと思います。

答え1

十分に良い解決策となる可能性のある別のオプションを見つけました。それは、 から に渡されるメッセージをハイジャックすることpostfixですdovecot

についてpostfixは、 の次の行を変更しますmaster.cf

dovecot      unix   -        n      n       -       -   pipe
  flags=DRhu user=vmail:mail argv=/usr/lib/dovecot/dovecot-lda -d $(user)@$(domain)

に:

dovecot      unix   -        n      n       -       -   pipe
  flags=DRhu user=vmail:mail argv=/scripts/emaildeliverycheck.py $(user)@$(domain)

次に、/scripts/emaildeliverycheck.py次のように作成します (Python 3.4)。

#!/usr/bin/python3

from sys import argv, stdin, exit
from subprocess import Popen, check_call, CalledProcessError

# Define recipients that should trigger the script here
notifyusers = ('[email protected]',
               '[email protected]')

recipient = argv[1]

if recipient in notifyusers:
    # Run the script. Use Popen so that we don't have to wait for the 
    # script to finish
    Popen(['/scripts/myscript.py', recipient])

try:
    # Now pass the email to dovecot-lda. Use check_call because we *do* 
    # want to wait for it to finish
    check_call(['/usr/lib/dovecot/dovecot-lda', '-d', recipient], stdin=stdin)
except CalledProcessError as error:
    # Propagate any error codes back to Postfix
    exit(error.returncode)

Postfix のpipeプロセスは、最終的な配信用の電子メールを に直接渡すのではなく、上記のスクリプトに渡しますdovecot-lda。スクリプトは受信者 (コマンド ラインで渡されるため、メッセージを確認する必要はまったくありません) をリストと照合し、一致する場合は別のスクリプトを起動します。次に、メッセージを にパイプします。 はdovecot-lda、メッセージを Postfix から直接取得していないことを認識できないはずです。そして、終了ステータスをpipeプロセスに伝えます。

初期テストでは問題なく動作します。これにより、フィルタリング後のメールのみが取得されます。これが私の目的です。

答え2

私はprocmailローカル配信エージェントとして使用しています。これにより、ユーザーに適用可能なルールを使用して、広範囲のフィルタリングが可能になります。postfix を設定して、procmail を使用してフィルタリングを行い、必要に応じて電子メールを配信できるようにする必要があります。

procmailヘッダー、コンテンツ、またはその両方にフィルターを適用する広範な機能を備えています。任意のプログラムをフィルターとして使用できるため、指定したユーザーに送信される各電子メールに対してスクリプトをトリガーできます。

関連情報