如何通过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
相关产品推荐
相关产品推荐

