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

时间:2009-06-18 09:26:19

标签: php email bounce

以下是我的情景:

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

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

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

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

我应该使用哪种编程语言来处理“处理脚本”?

“处理脚本”会是什么样子?你能举样吗?

换句话说,

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

14 个答案:

答案 0 :(得分:29)

最好的方案是能够对弹跳类型进行分类:软,硬......

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

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

X-user-id: XXXXX
X-campaign-id: YYYYYY 
X-recipient-id: SSSSSSSSS
通过这种方式,我们可以知道我们发送电子邮件的真实收件人。

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

答案 1 :(得分:7)

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

编辑评论后:请检查我的链接whcih有一个PHP脚本,它将教你如何打开和使用PHP邮箱和阅读电子邮件。您可以使用此脚本来检查错误消息。

答案 2 :(得分:5)

让电子邮件反弹到一个真正的电子邮件地址(有登录详情等)。

创建一个运行x分钟的php脚本(例如使用cron作业)。这个PHP脚本必须执行以下操作。 - 从框中检索所有电子邮件(例如使用Zend Mail) - 检查邮件中的错误(例如,使用正则表达式搜索) - 尽一切必要。

如果您想知道谁已经退回,您可以使用特定于用户的退回地址。 (参见例如this site

答案 3 :(得分:4)

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

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

干杯。

答案 4 :(得分:2)

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

答案 5 :(得分:0)

您可以随时使用类似http://cloudmailin.com的内容通过http将退回的电子邮件转发到您的php服务器上,但是您可能会更好地使用专门用于发送电子邮件和使用其API来检索退回详细信息的服务。

答案 6 :(得分:0)

我为此寻找一个PHP解决方案运气相当糟糕,但我遇到了这个产品,它正是我所需要的。

它作为原生app mac / win运行,但它可以完成任务。

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

答案 7 :(得分:0)

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

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

如果您使用的是cPanel或InterWorx / SiteWorx,您可以配置一些地址来处理收到的带有脚本的电子邮件,例如PHP脚本,这样您就可以借助于脚本来编写自己的处理。提到的课程。或者当然,您仍然可以创建普通的电子邮件帐户并通过POP3或IMAP检索邮件,然后解释它们。我认为第一个更好,因为它是直接的,你不必使用其他渠道,如IMAP。当然如果你不能配置你的邮件服务器,或者不知道怎么做,那么前者对你来说更好。

祝你好运! :)

答案 8 :(得分:0)

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

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

因此,您使用“-f mybouncebox@mydomain.com”作为参数

phpList newsletter manager使用它来管理跳出。

在邮箱中填满跳出后,您可以对其进行POP播放并对其进行处理。这是处理它们的最简单方法,而不是在它们到达时处理它们。

答案 9 :(得分:0)

以下是使用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)); 
} 

答案 10 :(得分:0)

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

有关详细信息,请查看此blog entry

答案 11 :(得分:0)

我有同样的问题,确切的情况。默认情况下,我的邮件服务器将所有返回的邮件发送到最初发送的同一帐户,并自动发送邮件&#34;邮件传递失败:向发件人返回邮件&#34;

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

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

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

但是如果你想按照解决我问题的快速简便的解决办法,这就是秘密。

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

2 - 包含您返回邮件文本的变量是$ body,它本身包含错误的返回邮件(SO ITS AN MULTIDIMENSIONAL ARRAY)。 (还包含您的服务器邮件和其他DNS邮件的内容,但我们正在寻找BAD MAIL BOUNCED。

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;

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

重要 在samples目录中的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

答案 12 :(得分:0)

您可以使用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变量中解析它。

答案 13 :(得分:-1)

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