2

我正在尝试实现一个帮助台应用程序,为此我需要编写一个 PHP 脚本来处理所有传入和传出的电子邮件。将 Postfix 视为 MTA,我发现这篇文章解释了如何对传入的电子邮件执行此操作:Postfix - 如何处理传入的电子邮件?. 它建议使用 Postfix 的mailbox_command配置,它就像一个魅力。我想知道外发电子邮件是否存在类似的情况?

4

2 回答 2

1

为了将所有外发邮件的副本发送到您的脚本,您需要:

  • 一个过滤器
  • 一个内容过滤器
  • 收件人_bcc_maps

最后一个选项是最简单的(您将邮件密送到服务器上的邮箱,脚本可以在其中处理邮件)。

但是:如果您的脚本已经生成了电子邮件,为什么还要再次将它们输入到您的脚本中呢?Postfix 并没有做太多,只是添加了一个 message-id 标头和一些其他无聊的标头...

于 2016-12-05T07:59:05.677 回答
-1

您可以在传入邮件上指定内容过滤器 - 这样做您需要通过以下方式修改您的 master.cf 文件:

...
submission inet n - n - - smtpd
  ...
  -o content_filter=yourfilter:
...
yourfilter unix - n n - - pipe
  user=[user on which the script will be executed]
  argv=php /path/to/your/script.php --sender='${sender}' --recipient='${recipient}'

接下来,您需要编写 script.php 以正确使用已提供的参数(--sender=... 和--recipient=...)接收邮件,并且邮件正文将是从标准输入提供。

这是一个如何从标准输入接收电子邮件的示例(我使用这个,稍后使用 Zend\Mail\Message::fromString() 创建 Message 对象):

    /**
     * Retrieves raw message from standard input
     * @throws \RuntimeException if calling controller was not executed on console
     * @return string raw email message retrieved from standard input
     */
     protected function retrieveMessageFromStdin() { 
        $request = $this->getRequest();
        if (!$request instanceof ConsoleRequest)
            throw new \RuntimeException('Action can be used only as console action !');

        $stdin = fopen('php://stdin', 'r');
        $mail_contents = "";
        while (!feof($stdin)) {
            $line = fread($stdin, 1024);
            $mail_contents .= $line;
        }
        fclose($stdin);
        $mail_contents = preg_replace('~\R~u', "\r\n", $mail_contents);
        return $mail_contents;
    }

根据参数 - 我使用 ZF2,因此您应该阅读如何在那里编写控制台应用程序或使用不同的技术,更符合您的框架。

非常重要的是,如果您希望在邮箱中接收邮件 - 您还需要将电子邮件“重新注入”回 postfix。我这样做的方式如下:

    /**
     * Reinjects message to sendmail queue
     *
     * @param array $senders            array of senders to be split into several sender addresses passed to sendmail (in most cases it is only 1 address)
     * @param array $recipients         array of recipients to be split into several recipient addresses passed to sendmail
     * @param string $sendmaiLocation   sendmailLocation string full path for sendmail (should be taken from config file)
     * @return number                   return value for sendmail
     */
     public function reinject(array $senders, array $recipients, string $sendmaiLocation) {
        foreach ($senders as $addresses)
            $senderAddress .= " " . $addresses;
        foreach ($recipients as $addresses)
            $recipientAddress .= " " . $addresses;
        $sendmail = $sendmaiLocation . " -G -i -f '" . $senderAddress . "' -- '" . $recipientAddress . "'";
        $handle = popen($sendmail, 'w');
        fwrite($handle, $this->toString());
        return pclose($handle);
    }

基本上您可以使用上述功能并根据您的需要进行自定义。然后您可以稍后使用我之前提到的命令行参数中的参数执行它。

希望这可以帮助 :)

于 2017-01-24T22:33:10.683 回答