【问题标题】:How to get Email Queue ID with swiftmailer?如何使用 swiftmailer 获取电子邮件队列 ID?
【发布时间】:2014-12-26 12:08:37
【问题描述】:

当我使用 telnet 发送电子邮件时,smtp 服务器在发送电子邮件时回复我250 2.0.0 Ok: queued as 7A821440123E。所以我需要获取 ID 7A821440123E 来跟踪邮件日志中的电子邮件。 用 Swiftmailer 可以得到这个吗?

【问题讨论】:

    标签: php swiftmailer


    【解决方案1】:

    SwiftMailer 是基于事件的,因此其他开发人员可以轻松扩展它。每次调用Swift_Transport 上的send 方法时,都会调度正确的事件。您可以使用已经开发的侦听器(插件),也可以编写自己的更加定制化的侦听器。

    现有插件

    SwiftMailer 已经发布了一些plugins,您可以使用它们来解决您的问题。

    只需使用logger plugin。它将记录Swift_Transport 实现中的所有命令调用。

    示例

    $transport = Swift_SmtpTransport::newInstance('example.com', 25);
    
    $mailer = Swift_Mailer::newInstance($transport);
    $mailer->registerPlugin(
        new Swift_Plugins_LoggerPlugin(
            new Swift_Plugins_Loggers_EchoLogger(false)
        )
    );
    
    $message = Swift_Message::newInstance('Wonderful Subject');
    
    $mailer->send($message);
    

    输出

    ++ Starting Swift_SmtpTransport
    << 220 example.com ESMTP ready
    
    >> EHLO [127.0.0.1]
    
    << 250-example.com
    250-SIZE 5242880
    250-PIPELINING
    250-ENHANCEDSTATUSCODES
    250-8BITMIME
    250-DSN
    250-AUTH PLAIN LOGIN CRAM-MD5
    250 STARTTLS
    
    >> AUTH CRAM-MD5
    
    << 235 2.0.0 OK
    
    ++ Swift_SmtpTransport started
    >> MAIL FROM: <john@example.com>
    
    << 250 2.1.0 Ok
    
    >> RCPT TO: <receiver@example.com>
    
    << 250 2.1.0 Ok
    
    >> DATA
    
    << 354 Go ahead
    
    >>
    .
    
    << 250 2.0.0 Ok: queued as 7A821440123E
    
    1++ Stopping Swift_SmtpTransport
    >> QUIT
    
    << 221 2.0.0 Bye
    
    ++ Swift_SmtpTransport stopped
    

    正如你在最后看到的,有想要的 id。

    自定义插件

    Swift_Transport 提供注册插件的接口。 它只不过是将事件侦听器附加到事件调度程序。 你可以自己写一个简单的插件。您需要做的就是实现Swift_Events_ResponseListener

    class FindEmailIdResponse implements Swift_Events_ResponseListener
    {
        /**
         * {@inheritdoc}
         */
        public function responseReceived(Swift_Events_ResponseEvent $evt)
        {
            if (strpos($evt->getResponse(), 'queued') !== false) {
                 // do whatever you want with the response or event
            }
        }
    }
    

    然后只需在邮件程序实例中注册您的插件

    $mailer->registerPlugin(new FindEmailIdResponse());
    

    【讨论】:

    • 换句话说,Swift Mailer 似乎没有开箱即用地提供这条信息,您需要自己从服务器响应中解析它。虽然库必须做一些基本的解析,但它只对 250 状态码感兴趣。太糟糕了,您无法直接访问确切的日志行。
    【解决方案2】:

    根据documentation,不需要第 3 方插件即可获取 Message-ID。 Message-ID 由 SwiftMailer 设置,否则 SMTP 服务器会自己创建一个。 所以,你只需要:

    $message = \Swift_Message::newInstance($subject, $body);
    ...
    $messageID = $message->getId();
    

    【讨论】:

    • 但不是同一个ID吧?
    • 如果您检查源代码,您会看到 Swift 生成的 ID 以“@something”结尾(例如“@swift.generated”或“@example.com”),但每次我检查SMTP 日志我发现了简单的十六进制字符串,如问题中所示。 (还有 2 个已删除的答案与您的做法相同,当您有足够的代表时,您可以看到它们。)
    • 我使用 mailcatcher 作为虚拟 SMTP 服务器来测试我的邮件服务,我可以确认 SwiftMailer 生成的 ID 是 mailcatcher SMTP 报告的 ID。我会尝试用现实世界的 SMTP 重现你所说的。
    • 我最近与两三个提供商合作过,没有一个会使用 Swift 生成的 ID。另外,几年前我曾经维护过一个 Postfix 服务器,它大量使用了十六进制队列 ID:您可以使用该 ID 来跟踪、重新发送、删除……使用 postqueue 命令,并在在该上下文中,ID 必须是唯一的。 10年后我无法确定,但我怀疑ID是报告的那个。不管怎样,为了得到一个明确的答案,我们需要深入研究 SMTP RFC,看看他们对队列 ID 说了什么(或不说)。
    • 您说的是与 OP 不同的 ID! OP 要求的称为 Queue ID,通常看起来像 @ 987654323@。您所说的是 Message-ID (即电子邮件中的标头),通常看起来像电子邮件地址,例如&lt;0d0d90b541b06acce4559ef40bd238b4@example.com&gt;
    猜你喜欢
    • 1970-01-01
    • 2018-11-03
    • 2019-03-25
    • 1970-01-01
    • 2021-03-04
    • 2021-04-08
    • 2019-05-18
    • 1970-01-01
    • 2015-03-28
    相关资源
    最近更新 更多