【问题标题】:Not all mails being received by recipients when sent via PHP using Amazon SES使用 Amazon SES 通过 PHP 发送时,并非所有邮件都被收件人接收
【发布时间】:2014-06-29 02:36:33
【问题描述】:

我编写了简单的 PHP (codeigniter) 脚本来使用 Amazon SES 发送时事通讯。我在 MySQL 表和脚本中有大约 8000 封电子邮件,它提取所有行(电子邮件地址),将其拆分为较小的包(由于 SES 限制)并通过 SMTP 发送电子邮件。我正在使用sleep()* 和一个每分钟运行的 cronjob。我知道这不是最好的解决方案,但作为一个概念它可以正常工作。

要允许使用bcc 发送邮件,我必须确保to 字段中至少有一个收件人,否则 Amazon SES 将不会发送它。所以,我的地址(news@baulink.rs)总是在to,其他地址在bcc。每次迭代都会在bcc 中放置 8 个不同的地址(顺便说一句,有没有更好的解决方案呢?)。我还有一个简单的日志文件,它记录了我的应用程序操作的每个地址。

如我所见,有些收件人没有收到时事通讯。 Amazon SES 返回退回的电子邮件并且工作正常,但有些地址根本没有收到它,并且没有来自 Amazon SES 的任何反馈。这些地址在我的日志中,这意味着它们是由 PHP 脚本处理的。然后我只是删除该地址并再次插入 MySQL 表 - 它有效!有些电子邮件是从 CSV 文件中解析出来的,有些是手动插入的。我真的不知道也无法与所有收件人核实他们是否收到了时事通讯。你知道什么会导致这种奇怪的行为吗?

我不知道是什么问题。

我正在使用 CodeIgniter 和 PHPMailer。

 public function cronSendMail(){
    $newsletter = $this->baumodel->getNewsletter();

    if(is_array($newsletter)){
        echo "No job for me!";    
        return;
    }elseif(is_object($newsletter)){ //means there is a newsletter ready for sending                        
        $limit = 104;
        $newsOfset = $newsletter->news_slanje_ofset;                        
        $noviOfset = $newsOfset+$limit;

        $adrese = $this->baumodel->getAdresar($limit, $newsOfset); 
        $brojAdresa = count($this->baumodel->getSveAdrese()); //number of recipients in whole MySQL table

        if($brojAdresa < $newsOfset){ 
            echo "Adrese: ".$brojAdresa;
            echo " Ofset: " .$newsOfset;
            die('Job is finished! ');
        }

        $this->baumodel->setNewsletterOfset($newsletter->news_id, $noviOfset);                      
        $emailArray = array();

        foreach($adrese as $adr){
            array_push($emailArray, trim($adr['adr_email']));
        }

        $newsletterContent = $newsletter->news_sadrzaj;                                                                                     
        $this->load->library('email');
        $this->email->clear();                

        $maliNiz = array();
        for($i=0; $i<13; $i++){
            //13 times with 2 seconds sleep is ~30-35 seconds of execution time.
            //CronJob runs every minute
            $j=0;
            $maliNiz[$j] = array_pop($emailArray);
            $j++;
            $maliNiz[$j] = array_pop($emailArray);
            $j++;
            $maliNiz[$j] = array_pop($emailArray);
            $j++;
            $maliNiz[$j] = array_pop($emailArray);
            $j++;                           
            $maliNiz[$j] = array_pop($emailArray);
            $j++;
            $maliNiz[$j] = array_pop($emailArray);
            $j++;
            $maliNiz[$j] = array_pop($emailArray);
            $j++;
            $maliNiz[$j] = array_pop($emailArray);
            $j++;                           

            $this->email->to('news@baulink.rs');
            $this->email->bcc($maliNiz); //This is my BCC array of 8 addresses
            $this->email->from('office@baulink.rs', 'Baulink Portal');
            $this->email->subject('Gradjevinski portal Baulink - Novo na portalu');
            $this->email->message($newsletterContent);
            $this->email->send();
            //echo $this->email->print_debugger();

            sleep(2);               

            //log file start
            $filepath = APPPATH . 'logs/mail-log-' . date('Y-m-d') . '.php';
            $handle = fopen($filepath, "a+");                                                       
            $currentDateTime = date('d.M.Y H:i:s');
            foreach($maliNiz as $emailAdresa){
                    $infoLog = $emailAdresa . " // ".$currentDateTime . " \n";
                    fwrite($handle, $infoLog);
            }
            fclose($handle);
            //log file end
        }
    }
}

【问题讨论】:

  • 可能是邮件被标记为垃圾邮件。所以问题可能是发送的域被列入黑名单或其他原因导致垃圾邮件列表中的分数。
  • 不,它甚至不在垃圾邮件中。例如,有些 Gmail 帐户运行良好,邮件在收件箱中传递,但在其他一些情况下,它根本不起作用。 @hotmail 和基于域的(业务)电子邮件地址也是如此。真的很奇怪……
  • 好的,很公平。但不清楚是亚马逊 SES 还是你这边的邮寄流程。很别致。如果你仔细想想,你的日志可能只是误报。
  • 我将尝试从 SMTP 记录答案,这将为我提供更多数据进行分析。这可能是我这边的事情。
  • 没错。您仍然需要建立 SMTP 连接才能将材料发送到 Amazon SES,因此这是另一个值得关注的方面。

标签: php mysql codeigniter newsletter amazon-ses


【解决方案1】:

根据亚马逊文档,这可能是问题所在。

重要当您将电子邮件发送给多个收件人(收件人 是“To”、“CC”和“BCC”地址)并且对 Amazon SES 的调用失败, 整个电子邮件都被拒绝,并且没有一个收件人会收到 预期的电子邮件。因此,我们建议您发送电子邮件至 一次一个收件人。

http://docs.aws.amazon.com/ses/latest/DeveloperGuide/sending-email.html

【讨论】:

  • 谢谢,我看到了,但忘记了。我将不得不重写我的脚本。 RTFM :)
  • 如果您使用 Amazon PHP SDK,您可以直接连接到 API 而不是通过 smtp,这样您就可以批量发送电子邮件。唯一的缺点是,如果您想切换邮件提供商,您需要重新编写。
  • 如果我使用 Amazon PHP SDK 会更快吗?现在每个请求大约需要 3 秒,如果我每个请求只发送给一个收件人,那会很慢。
  • 而且我认为,如果对服务器的调用失败,SES 也会拒绝整个电子邮件,如果它是通过 SMTP 或常规 API 调用的,则不会。
  • 在进一步阅读时,它看起来确实会出现与 api 相同的问题。我在第一次出现时查看了 SES 文档,但从那以后就没有再查看了。我最终使用了山魈。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-08-03
  • 1970-01-01
  • 1970-01-01
  • 2020-11-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多