PHP如何处理退信邮件?

29

这是我的场景:

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

我想使用admin@domain.com将电子邮件发送给所有用户,但然后“回复到”bounce@domain.com(到此为止,我的PHP脚本可以处理它)。

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

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

用于“处理脚本”的编程语言应该是什么?

"处理脚本"会是什么样子? 你能给个示例吗?

换句话说:

我应该遵循哪些程序来处理反弹电子邮件?

14个回答

29
最好的情况是能够分类反弹类型:软、硬...。
我们使用的是BounceStudio。您需要编译它并添加php库...一点也不难。该产品有免费和付费版本。
一旦我们检测到反弹类型,我们就使用PEAR::MAIL::MIME搜索先前添加到电子邮件中的自定义标头,比如说:
X-user-id: XXXXX
X-campaign-id: YYYYYY 
X-recipient-id: SSSSSSSSS

这样我们就可以知道我们发送电子邮件的真正收件人。

希望这对你有所帮助!这样你就可以帮助我获得500分:P


1
很高兴看到你达到了500个 :) - Álvaro González
似乎他们不再有免费版本了。 - Bot

7

为什么不创建一个bounce@domain.com,使用php 读取这些邮件 并随心所欲地进行操作呢?

在您的评论之后编辑:请检查我的链接,其中有一个php脚本,将教您如何使用php打开并读取电子邮件。您可以使用此脚本检查错误消息。


你的意思是,我创建一个目录,存储所有反弹邮件(bounce@domain.com)。然后,编写一个 PHP 脚本,定期检查该文件夹并检查错误代码? - mcfadder_09
请创建一个新的ID为bounce@domain.com的电子邮件账户。将电子邮件详细信息提供给PHP脚本,并使用cron定期运行。可以使用PHP打开POP3帐户(请参考上面的代码)。无需存储电子邮件。您的脚本应自动打开邮箱并处理新邮件。 - Shoban
这就是为什么我需要一个流程,因为我完全不知道如何处理这个退信邮件的事情。我甚至不知道从哪里开始,如何“向PHP脚本提供电子邮件详细信息”?我需要帮助……帮助我…… - mcfadder_09
你说你不是 PHP 新手了.. 你有没有查看我发布的链接?检查链接中的 PHP 代码,并针对其中任何具体疑问进行提问。你只需要提供电子邮件 ID、端口详细信息等即可。 - Shoban

5
让电子邮件反弹到一个真正的电子邮件地址(带有登录详细信息等)。 编写一个 PHP 脚本,每 x 分钟运行一次(例如使用 cron 作业)。此 PHP 脚本必须执行以下操作。 - 检索来自邮箱的所有电子邮件(例如使用 Zend Mail) - 检查消息中的错误(例如通过使用正则表达式进行搜索) - 进行必要的操作。 如果您想知道特定谁已经反弹回来,您可以使用用户特定的反弹地址。 (请参见this site

Zend Mail的链接已经失效了,这里提供一个新的链接http://framework.zend.com/manual/current/en/modules/zend.mail.introduction.html - Jaider

4
也许回答有点晚了,但您总是可以尝试一些新的东西。我上周有一个类似的任务,使用了Chris Fortune的BOUNCE HANDLER Class,它将退信切成关联数组 - http://www.phpclasses.org/browse/file/11665.html。在使用某个邮件程序连接到POP3以获取退信后,使用此功能将其解析成片段,并且如果具有您搜索的状态,则执行必要的操作。祝好运。

2
如果您已经设置了一个用于 bounce@domain.com 的 POP3 邮箱,您可以使用用 PHP 编写的 POP3 客户端脚本来检索消息并检查不可投递的消息。

1
你可以使用imap_open从PHP中访问你的邮件。

这个函数也适用于POP3,但是并非所有功能都能在此处工作。然而,我猜想在2018年,大多数电子邮件客户端应该支持IMAP。

此函数还可用于打开到POP3和NNTP服务器的流,但某些功能和特性仅适用于IMAP服务器。

以下是一个小例子,演示如何遍历你的电子邮件:

  /* connect to server */
  $hostname = "{$your-server:$your-port}INBOX";
  $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才能使我的连接正常工作。 - SuprMan

0
这是一个使用IMAP处理退信的预设解决方案。
我将我的邮件实例的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)); 
} 

0

我曾经遇到过同样的问题,情况完全一样。默认情况下,我的邮件服务器会将所有退回的邮件发送到与原始发件人相同的帐户,并自动发送消息"Mail delivery failed: returning message to sender"

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

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

如果您想设置IMAP并发送自己的自定义标题,请将其发送到您的bounce@domain.com,然后祈祷脚本是否捕获您在退回的邮件中写入的标题,我建议您阅读并下载KIDMOSES的这个已修复调试版本的Handling Bounced Email - USING PHPMAILER-BMH AND AUTHSMTP,链接在这里http://www.kidmoses.com/blog-article.php?bid=40。我尝试过,它有效。

但是,如果您想要遵循我的快速简易修复方法来解决问题,这里有一个秘诀。

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

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

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

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;

所以我们忘记返回的头部,专注于错误的电子邮件。您可以使用Excel处理它们,也可以使用MySQL处理,或者根据您想要做的任何操作进行处理。

重要提示 在示例目录中的callback_echo.php文件中注释掉echo语句,否则会打印出所有的垃圾信息。

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提到的软件,它也非常好用,我刚刚检查过,可以给你所有邮件退回的确切原因。谢谢Jason:http://www.maxprog.com/site/software/internet-marketing/email-bounce-handler_sheet_us.php - Luis H Cabrejo

0

0
你可以随时使用类似 http://cloudmailin.com 的工具通过http将退回的电子邮件转发到你的php服务器,但是你最好使用专门发送电子邮件并使用其API检索退回详细信息的服务。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接