使用 PHP 处理退回电子邮件?

Posted

技术标签:

【中文标题】使用 PHP 处理退回电子邮件?【英文标题】:Bounce Email handling with PHP? 【发布时间】:2010-11-03 22:42:29 【问题描述】:

这是我的场景:

我有 2 个电子邮件帐户:admin@domain.com 和bounce@domain.com。

我想使用 admin@domain.com 向我的所有用户发送电子邮件,然后“回复”bounce@domain.com(直到这里,我的 php 脚本可以处理它)。

当邮件无法发送时,发送到bounce@domain.com,错误信息可能是553(不存在的电子邮件...)等。

我的问题是:如何通过处理脚本将所有这些退回电子邮件(无法发送的电子邮件)定向到bounce@domain.com 以检查退回错误代码?

我应该为“处理脚本”使用什么编程语言?

“处理脚本”是什么样的?能给个样品吗?

换句话说:

我应该遵循哪些程序来处理退回邮件?

【问题讨论】:

【参考方案1】:

最好的场景是能够对反弹的类型进行分类:软、硬……

我们使用的是BounceStudio。您需要编译它并添加 php 库......一点也不难。您拥有该产品的免费和付费版本

一旦我们检测到kind of bounce,我们就会使用 PEAR::MAIL::MIME 来搜索我们之前添加到电子邮件中的自定义标题,让我们说:

X-user-id: XXXXX
X-campaign-id: YYYYYY 
X-recipient-id: SSSSSSSSS

通过这种方式,我们可以知道我们发送电子邮件的真实收件人。

希望对您有所帮助!所以你可以帮助我达到 500 分:P

【讨论】:

很高兴看到你达到 500 :) 他们似乎不再有免费版本了。【参考方案2】:

为什么不创建一个bounce@domain.com 并使用php 到read those emails 并做任何你想做的事?

在您发表评论后编辑:请查看我的链接,该链接有一个 php 脚本,该脚本将教您如何使用 php 打开和电子邮件信箱并阅读电子邮件。您可以使用此脚本来检查错误消息。

【讨论】:

你的意思是,我创建了一个目录,存储了bounce@domain.com 的所有电子邮件。然后,编写一个php脚本,定期检查该文件夹并检查错误代码? no... 创建一个新的 idbounce@domain.com 。将电子邮件详细信息提供给 php 脚本并使用 cron 使其定期运行。 PHP可以用来开pop 3个账户(查看上面的代码)。无需存储电子邮件。您的脚本应该会自动打开邮箱并处理新电子邮件。 这就是为什么我需要一个程序,我对处理这个退回电子邮件的事情是全新的。我什至无法从哪里开始,如何“向 php 脚本提供电子邮件详细信息”?我需要帮助...帮助...我... 你说你不是php新手。你有没有检查我发布的链接?检查链接中的 php 代码并询问其中的任何具体疑问。您只需提供电子邮件 ID、端口详细信息等。【参考方案3】:

让电子邮件退回到真正是电子邮件地址的地址(带有登录详细信息等)。

制作一个每 x 分钟运行一次的 php 脚本(例如使用 cron 作业)。此 php 脚本必须执行以下操作。 - 从邮箱中检索所有电子邮件(例如使用Zend Mail) - 检查消息中的错误(例如,使用正则表达式搜索) - 做任何必要的事情。

如果您想具体了解谁被退回,您可以使用用户特定的退回地址。 (例如参见this site)

【讨论】:

Zend Mail的链接坏了,这里是新链接framework.zend.com/manual/current/en/modules/…【参考方案4】:

也许答案有点晚了,但你总是可以尝试一些新的东西。 上周我有一个这样的任务,并使用了 Chris Fortune 编写的 BOUNCE HANDLER 类,它将反弹分割成关联数组 - http://www.phpclasses.org/browse/file/11665.html

这将在您使用某些邮件程序连接到 POP3 以从中获取退回邮件后使用,然后将其解析为碎片,如果具有您搜索的状态,请执行必要的操作。

干杯。

【讨论】:

【参考方案5】:

如果您为bounce@domain.com 设置了 POP3 邮箱,则可以使用 PHP 编写的 POP3 客户端脚本来检索邮件并检查无法投递的邮件。

【讨论】:

【参考方案6】:

您可以使用imap_open 从 PHP 访问您的邮件。

此功能也适用于 POP3,但并非每个功能都可以在这里使用。不过我猜 2018 年大多数电子邮件客户端应该支持 IMAP。

这个函数也可以用来打开流到 POP3 和 NNTP 服务器,但某些功能和特性仅在 IMAP 上可用 服务器。

这里有一个小例子,如何遍历你的电子邮件:

  /* connect to server */
  $hostname = "$your-server:$your-portINBOX";
  $username = 'my-username';
  $password = '123';

  /* try to connect */
  $inbox = imap_open($hostname,$username,$password) or die('Cannot connect to mailbox: ' . imap_last_error());

  /* grab emails */
  $emails = imap_search($inbox,'ALL');

  /* if emails are returned, cycle through each... */
  if($emails) 
    /* for every email... */
    foreach($emails as $email_number) 

        $message = imap_body($inbox,$email_number,2);
        $head    = imap_headerinfo($inbox, $email_number,2);
        // Here you can handle your emails
        // ...
        //  ...
      
  

就我而言,我知道从Mailer-Daemon@myserver.com 发送邮件总是失败。所以我可以识别这样的反弹:

if($head->from[0]->mailbox == 'Mailer-Daemon')

  // We have a bounce mail here!

你说:

当邮件无法发送时,它被发送到bounce@domain.com, 错误消息可能是 553(不存在的电子邮件...)等。

因此,如果您的退回电子邮件的主题为“邮件传递失败:错误 553”,那么您可以通过以下主题识别它们:

if($head->subject == 'Mail delivery failed: Error 553')

  // We have a bounce mail here!

失败的电子邮件地址不在标头中,因此您需要使用一些智能代码从$message 变量中解析它。

【讨论】:

谢谢!这个答案对我帮助很大。注意:我必须在主机名参数中的端口之后添加/imap/ssl/novalidate-cert,才能使连接正常工作。【参考方案7】:

您始终可以使用 http://cloudmailin.com 之类的东西通过 http 将退回的电子邮件转发到您的 php 服务器,但是您最好使用专门用于发送电子邮件并使用其 api 检索退回详细信息的服务。

【讨论】:

【参考方案8】:

我在为此寻找 PHP 解决方案时运气不佳,但我遇到了这个产品,它可以满足我的需要。

它作为本机应用程序 mac/win 运行,但它可以完成这项工作。

http://www.maxprog.com/site/software/internet-marketing/email-bounce-handler_sheet_us.php

【讨论】:

【参考方案9】:

我正在寻找同一个问题的答案。问题的部分更多,选项也更多。

为了处理退回的电子邮件,我找到了一个PHP class,它完全使用 PHP,如果您有一个 PHP 驱动的站点,则不需要编译或额外的软件安装。它非常易于使用。

如果您使用 cPanel 或 InterWorx/SiteWorx,您可以配置一些地址以使用脚本(例如 PHP 脚本)来处理接收到的电子邮件,这样您就可以借助提到的类。当然,您也可以创建普通的电子邮件帐户,通过 POP3 或 IMAP 检索邮件,然后进行解释。我认为第一个更好,因为它是直接的,您不必使用其他渠道,例如 IMAP。当然如果你不会配置你的邮件服务器,或者不知道怎么做,那么前者更适合你。

祝你好运! :)

【讨论】:

【参考方案10】:

在php邮件命令http://php.net/mail

你使用第五个参数并添加“-f”。

所以,你使用“-f mybouncebox@mydomain.com”作为参数

phpList newsletter manager 使用它来管理退回邮件。

一旦退回邮件填满邮箱,您就可以将它们弹出并处理它们。这是处理它们的最简单方法,而不是在它们到达时处理它们。

【讨论】:

【参考方案11】:

这是使用 IMAP 处理退回邮件的固定解决方案。

我将 Mail 实例的 Return-Path 标头更改为专用的bounce@xxxxxx.us

我认为唯一可行的方法是以下,它通过 POP3 检查专用收件箱,并可以根据收到的消息处理每封电子邮件。

$inst=pop3_login('mail.xxxxxx.us','110','bounce@xxxxxx.us','pass');
$stat=pop3_stat($inst);
//print_r($stat);
if($stat['Unread']>0)
    echo "begin process<br><br>";
    $list=pop3_list($inst);
    //print_r($list);
    foreach($list as $row)
        if(strpos($row['from'],'MAILER-DAEMON')!==FALSE)
            $msg=imap_fetchbody($inst,$row['msgno'],'1');
            if(strpos($msg,'550')!==FALSE)
                echo "handle hard bounce".$msg."<br><br>";
                //WHATEVER HERE TO PROCESS BOUNCE
               
        
        else
            $msg=imap_fetchbody($inst,$row['msgno'],'1');
            echo "not from my server. could be spam, etc.".$msg."<br><br>";
            //PROBABLY NO ACTION IS NEEDED
           
        //AFTER PROCESSING
        //imap_delete ( resource $imap_stream , int $msg_number [, int $options = 0 ] )
        //commented out because I havent implemented yet. see IMAP documentation
       
   
else
    echo "no unread messages";  



//imap_close ( resource $imap_stream [, int $flag = 0 ] )
//commented out because I havent implemented yet. see IMAP documentation.
//flag: If set to CL_EXPUNGE, the function will silently expunge the mailbox before closing, removing all messages marked for deletion. You can achieve the same thing by using imap_expunge()




function pop3_login($host,$port,$user,$pass,$folder="INBOX",$ssl=false) 
 
    $ssl=($ssl==false)?"/novalidate-cert":""; 
    return (imap_open(""."$host:$port/pop3$ssl"."$folder",$user,$pass)); 
 
function pop3_stat($connection)        
 
    $check = imap_mailboxmsginfo($connection); 
    return ((array)$check); 
 
function pop3_list($connection,$message="") 
 
    if ($message) 
     
        $range=$message; 
     else  
        $MC = imap_check($connection); 
        $range = "1:".$MC->Nmsgs; 
     
    $response = imap_fetch_overview($connection,$range); 
    foreach ($response as $msg) $result[$msg->msgno]=(array)$msg; 
        return $result; 
 
function pop3_retr($connection,$message) 
 
    return(imap_fetchheader($connection,$message,FT_PREFETCHTEXT)); 
 
function pop3_dele($connection,$message) 
 
    return(imap_delete($connection,$message)); 
 

【讨论】:

【参考方案12】:

我们正在使用 Procmail 来过滤这些类型的邮件。在检查了这里已经提到的一些解决方案之后,我们最终得到了一个简单的 Procmail 配方来检测退回邮件。根据您需要的准确性,这可能适用于您的情况。

详情请查看blog entry。

【讨论】:

【参考方案13】:

我有同样的问题,确切的情况。默认情况下,我的邮件服务器会将我所有返回的邮件发送到最初发送邮件的同一帐户,并带有自动消息“邮件传递失败:将邮件返回给发件人”

我真的不想知道它为什么被退回,有这么多邮件交易,我只想删除坏的。没有时间检查特定的规则,例如是否存在,不可用等,,,只想标记删除并继续。

退回邮件非常简单,因为您需要处理许多不同的服务器和响应类型。每个反垃圾邮件软件或操作系统方案都可以在退回的电子邮件中发送不同的错误代码。

如果您想设置 IMAP 并发送您自己的自定义设置,我建议您在此处http://www.kidmoses.com/blog-article.php?bid=40 KIDMOSES 阅读并下载 处理退回的电子邮件 - 使用 PHPMAILER-BMH 和 AUTHSMTP 的固定调试版本标头,将它们发送到您的 bounce@domain.com,然后交叉手指查看脚本是否捕获了您在退回邮件中发送的标头。我试过了,有效。

但是,如果您想按照我的快速简便的解决方案解决我的问题,这里就是秘密。

1 - 从 KIDMOSES 网站或我的网站下载更好的版本,以防 KIDMOSES 想搬到其他地方http://chasqui.market/downloads/KIDMOSES-phpmailer-bmh.zip

2 - 包含返回邮件文本的变量是 $body ,它本身包含错误返回的电子邮件(所以它是一个多维数组)。 (还包含您的服务器邮件和其他 DNS 邮件内容,但我们正在寻找 BAD MAIL BOUNCED。

3 - 由于您的 OWN SERVICE 正在向您发送退回的电子邮件,因此它不太可能更改其格式和自己的标题,发送退回的电子邮件,因此您可以安全地选择退回的电子邮件数组返回的顺序。在我的情况下,总是相同的格式模板。 (除非您更改系统或提供商)

4 - 我们查看 $body 并搜索所有电子邮件字符串变量并将它们提取到一个名为 $matches二维数组中强>

5 - 我们通过使用 print_r(array_values( $matches )); 打印数组来选择数组位置;

6 - 这是您需要修改的代码。 class.phpmailer-bmh.php 文件中的第 500 行

  // process bounces by rules
  $result = bmhDSNRules($dsn_msg,$dsn_report,$this->debug_dsn_rule);
 elseif ($type == 'BODY') 
  $structure = imap_fetchstructure($this->_mailbox_link,$pos);
  switch ($structure->type) 
    case 0: // Content-type = text
      $body = imap_fetchbody($this->_mailbox_link,$pos,"1");
      $result = bmhBodyRules($body,$structure,$this->debug_body_rule);

      //MY RULE IT WORKS at least on my return mail system..
      $pattern = '/[a-z0-9_\-\+]+@[a-z0-9\-]+\.([a-z]2,3)(?:\.[a-z]2)?/i';
      preg_match_all($pattern, $body, $matches);
        //print_r( array_values( $matches ));     //To select array number of bad returned mail desired, usually is 1st array $matches[0][0]          
        echo "<font color = red>".$matches[0][0]."</font><br>";
      break;

因此,我们忘记了返回的标头并专注于不良电子邮件。你可以超越它们,你可以 mysql,或者处理任何你想做的事情。

重要 在示例目录中的 callback_echo.php 中注释回声,否则您会在打印之前得到所有垃圾。

function callbackAction ($msgnum, $bounce_type, $email, $subject,      $xheader, $cheader, $remove, $rule_no=false, $rule_cat=false, $rule_msg='', $totalFetched=0) 
  $displayData = prepData($email, $bounce_type, $remove);
  $bounce_type = $displayData['bounce_type'];
  $emailName   = $displayData['emailName'];
  $emailAddy   = $displayData['emailAddy'];
  $remove      = $displayData['remove'];
  //echo "<br>".$msgnum . ': '  . $rule_no . ' | '  . $rule_cat . ' | '  . $bounce_type . ' | '  . $remove . ' | ' . $email . ' | '  . $subject . ' | ';
  //echo 'Custom Header: '  . $cheader . " | ";
  //echo 'Bounce Message: '  . $rule_msg . " | ";
  return true;

我的输出

Connected to: mail.chasqui.market (bounce@chasqui.market)
Total: 271 messages 
Running in disable_delete mode, not deleting messages from mailbox

kty2001us@starmedia.com

...

entv@nuevoface.com

Closing mailbox, and purging messages
Read: 271 messages
0 action taken
271 no action taken
0 messages deleted
0 messages moved

【讨论】:

另一方面,如果您宁愿购买@Jason 提到的软件,它也很好用,只需检查并为您提供邮件被退回的各种确切原因。谢谢杰森:maxprog.com/site/software/internet-marketing/…【参考方案14】:

你应该看看 SwiftMailer。它完全用 PHP 编写,并且支持“退回”电子邮件。 http://swiftmailer.org/

【讨论】:

Swift Mailer 只能获取 SMTP 发送状态,无法获取收件人服务器的回复。 要使用 php 阅读退回邮件,请尝试 PHPMailer-BMH(退回邮件处理程序)-phpmailer.worxware.com/index.php?pg=bmh 它有点过时,但可以帮助您做一些基本的事情。对于高级退回处理,我还推荐 BounceStudio。 SwitfMailer 可以找到failures-by-reference,但它不支持退回。

以上是关于使用 PHP 处理退回电子邮件?的主要内容,如果未能解决你的问题,请参考以下文章

处理退回的电子邮件

如何在 PHP 中跟踪使用 GMAIL API 发送的电子邮件的已发送、已打开、已单击、已退回、已阻止等电子邮件传递状态

在 CakePHP 和 Postfix 中处理电子邮件退回

PHP 获得退回电子邮件

我如何跟踪退回的电子邮件?

如何使用带有 Postfix 的 AWS SES 接收退回的邮件