web-dev-qa-db-ja.com

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

メールを受信するための postfix で構成される(Linux)メールサーバーがあります amavisd-new コンテンツフィルタリング(clamavSpamAssassinを使用)の場合、および dovecot 配信とIMAPの場合。

特定のメールボックスにメールが配信されるたびにスクリプトが実行されるように設定したいと思います。スクリプトは、メッセージのコンテンツやヘッダーについて何も知る必要はありません。私は少なくともいくつかのオプションを知っています:

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

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

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

提案?私が見落としているものはありますか?

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

4
glibdud

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プロセスに伝播します。

初期テストでは正常に動作します。これにより、フィルタリングされたメールのみが取得されます。これが私が目指していることです。

4
glibdud

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

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

1
BillThor