Swift Mailer投递状态

30

请问SwiftMailer的send函数是否返回邮件传递状态?我想知道邮件是否被送达或未被送达。这是否可能?

谢谢


http://swiftmailer.org/docs/failures-byreference - anon
以上链接已经失效,这是新的更新链接:http://swiftmailer.org/docs/sending.html#getting-failures-by-reference - shasi kanth
3个回答

40

SwiftMailer支持至少三层检查,可报告多种投递失败类型。

1)始终检查SwiftMailer的send()或batchSend()命令的返回代码是否为非零结果。来自文档

//Send the message
$numSent = $mailer->send($message);

printf("Sent %d messages\n", $numSent);

/* Note that often that only the boolean equivalent of the
   return value is of concern (zero indicates FALSE)

if ($mailer->send($message))
{
  echo "Sent\n";
}
else
{
  echo "Failed\n";
}

2) 使用failures-by-reference特性来了解特定地址是否被拒绝或未能完成:

//Pass a variable name to the send() method
if (!$mailer->send($message, $failures))
{
  echo "Failures:";
  print_r($failures);
}

/*
Failures:
Array (
  0 => receiver@bad-domain.org,
  1 => other-receiver@bad-domain.org
)
*/

3) 在一些情况下,您可能也希望启用回执,以确认邮件读者已显示该消息。它们通常会被用户或其电子邮件应用程序禁用或忽略,但如果您收到回执,则高度确认。还要注意,这可能会在发送后多天发生,因此不像上述两种测试是实时同步的。

$message->setReadReceiptTo('your@address.tld');

然而,由于涉及到许多变量和系统层级,SMTP传送不能确保消息是否被成功投递。您能做的最好的事情是确保使用前面提到的前两个检查。如果您使用自己的服务器进行SMTP服务,则还需要监视日志和队列,如Marc B所提到的。

另一个例子强调了熟悉所使用的基础电子邮件系统的必要性。我刚开始使用John Hobbs为Amazon Web Services SES编写的Swift_AWSTransport工具。SES具有返回XML响应的功能,用于每个经过它发送的消息进行诊断。虽然SwiftMailer本身不知道如何使用XML响应,但我发现它在故障排除投递问题时非常有用。我提到它是因为我发现,在某些情况下,检查#1和#2上将会对SwiftMailer显示成功,但SES不喜欢我的消息格式。因此,我正在考虑解析该XML作为额外的检查。


这个答案真的帮助了我快速解决与我的服务器设置值不符的发件人地址相关的问题。谢谢你用一种逻辑的方式提供了详细的答案。 - Art Geigel

9

虽然这是一篇比较旧的文章,但从Swiftmailer 4+开始,除了从send方法调用中获取result状态之外,如果您想要调试您的邮件发送程序并查看传输过程中发生了什��,您可以使用Logger插件,甚至创建自己的插件。 https://swiftmailer.symfony.com/docs/plugins.html

$mailer = \Swift_Mailer::newInstance(
    \Swift_SmtpTransport::newInstance('tls://smtp.gmail.com', 465)
);
$logger = new \Swift_Plugins_Loggers_ArrayLogger;
//$logger = new \Swift_Plugins_Loggers_EchoLogger; //echo messages in real-time
$mailer->registerPlugin(new \Swift_Plugins_LoggerPlugin($logger));

foreach ($recipients as $recipient) {
    //...

    $mailer->send(/*...*/);
}

echo $logger->dump(); //not needed if using EchoLogger plugin

以下代码将为每个 send 调用输出传输消息,看起来像这样:

++ Starting Swift_SmtpTransport 
<< 220 smtp.gmail.com ESMTP x12sm4143221vkc.19 - gsmtp 
>> EHLO server.example.com 
<< 250-smtp.gmail.com at your service, [192.168.1.1] 250-SIZE 35882577 250-8BITMIME 250-AUTH LOGIN PLAIN XOAUTH2 PLAIN-CLIENTTOKEN OAUTHBEARER XOAUTH 250-ENHANCEDSTATUSCODES 250-PIPELINING 250-CHUNKING 250 SMTPUTF8 
>> AUTH LOGIN 
<< 334 AbcDefGhIjKlMnop 
>> AbcDefGhIjKlMnop== 
<< 334 AbcDefGhIjKlMnop 
>> AbcDefGhIjKlMnop== 
<< 235 2.7.0 Accepted 
++ Swift_SmtpTransport started 
>> MAIL FROM: 
<< 250 2.1.0 OK x12sm4143221vkc.19 - gsmtp 
>> RCPT TO:<recipient@example.com> 
<< 250 2.1.5 OK x12sm4143221vkc.19 - gsmtp 
>> DATA 
<< 354 Go ahead x12sm4143221vkc.19 - gsmtp 
>> . 
<< 250 2.0.0 OK 1468948643 x12sm4143221vkc.19 - gsmtp

6

Swiftmailer与邮件的实际传递无关。它只是将邮件交给您指定的SMTP服务器,而正是该服务器负责传递邮件。您需要检查SMTP服务器的日志以查看邮件的情况。由于服务器过载,邮件可能会被卡在发件队列中。由于接收端不可达或使用灰名单等原因,邮件可能会被卡在队列中...一旦Swiftmailer从SMTP服务器获得邮件已排队的确认,它的工作就结束了。


1
Swiftmailer会通知我发送的消息是否未排队或SMTP服务器无法访问吗?它会返回错误字符串吗? - DavidW
2
它仍然没有说明失败的原因。它无法到达服务器吗?是认证被拒绝了吗?是否需要使用SSL/TLS,但未被使用?等等... - Josh M.

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