You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过Symfony Messenger追踪邮件发送状态并反馈给用户

Symfony Messenger邮件发送状态追踪实现方案

完全可以实现追踪邮件发送状态并获取SMTP响应信息,核心思路是利用Symfony Mailer的返回值和异常处理,结合Doctrine记录状态,具体步骤如下:

1. 调整消息类(SendEmailMessage)

给消息类添加关联实体的标识(比如Dossier的ID),用于后续更新状态:

<?php
namespace App\Message;

class SendEmailMessage
{
    private int $dossierId;

    public function __construct(int $dossierId)
    {
        $this->dossierId = $dossierId;
    }

    public function getDossierId(): int
    {
        return $this->dossierId;
    }
}

2. 修改消息处理器,捕获SMTP响应与异常

在处理器中接收Mailer返回的SentMessage对象,提取SMTP响应;同时捕获发送失败的异常,记录失败状态:

<?php

namespace App\MessageHandler;

use App\Entity\Dossier;
use App\Message\SendEmailMessage;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\Mailer\Exception\TransportExceptionInterface;
use Symfony\Component\Mailer\MailerInterface;
use Symfony\Component\Mailer\SentMessage;
use Symfony\Component\Mime\Email;
use Symfony\Component\Messenger\Handler\MessageHandlerInterface;

class SendEmailMessageHandler implements MessageHandlerInterface
{
    private EntityManagerInterface $entityManager;
    private MailerInterface $mailer;

    public function __construct(EntityManagerInterface $entityManager, MailerInterface $mailer)
    {
        $this->entityManager = $entityManager;
        $this->mailer = $mailer;
    }

    public function __invoke(SendEmailMessage $message)
    {
        /** @var Dossier $dossier */
        $dossier = $this->entityManager->getRepository(Dossier::class)->find($message->getDossierId());
        if (!$dossier) {
            return;
        }

        $email = (new Email())
            ->from('test@gmail.com')
            ->to('test@gmail.com')
            ->subject('test')
            ->html('test');

        try {
            /** @var SentMessage $sentMessage */
            $sentMessage = $this->mailer->send($email);
            // 获取SMTP服务器响应
            $smtpResponse = $sentMessage->getOriginalMessage()->getDebug();
            
            // 更新实体状态为成功
            $dossier->setEmailStatus('sent');
            $dossier->setSmtpResponse($smtpResponse);
        } catch (TransportExceptionInterface $e) {
            // 捕获发送失败异常,记录错误信息
            $dossier->setEmailStatus('failed');
            $dossier->setSmtpResponse($e->getMessage());
        }

        $this->entityManager->persist($dossier);
        $this->entityManager->flush();
    }
}

3. 实体类添加状态字段

在Dossier实体中添加用于存储邮件状态和SMTP响应的字段:

// App/Entity/Dossier.php
private string $emailStatus = 'pending'; // pending/sent/failed
private ?string $smtpResponse = null;

// 对应的getter和setter方法
public function getEmailStatus(): string
{
    return $this->emailStatus;
}

public function setEmailStatus(string $emailStatus): self
{
    $this->emailStatus = $emailStatus;
    return $this;
}

public function getSmtpResponse(): ?string
{
    return $this->smtpResponse;
}

public function setSmtpResponse(?string $smtpResponse): self
{
    $this->smtpResponse = $smtpResponse;
    return $this;
}

4. 前端展示状态

在业务页面中,从数据库读取Dossier实体的emailStatus和smtpResponse字段,即可向用户展示邮件发送结果及SMTP响应信息。

内容的提问来源于stack exchange,提问作者Venerivagus

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 09:45:55