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