【问题标题】:SwiftMailer not sending mail in MessageHandlerSwiftMailer 不在 MessageHandler 中发送邮件
【发布时间】:2020-08-04 07:01:19
【问题描述】:

我在我的 Symfony 5 项目中使用 SwiftMailer 来发送电子邮件。

我在控制器中使用它来发送重置密码电子邮件,一切正常。 我现在正在尝试在 MessageHandler 中使用它,这是我现在使用的代码:

final class SendEmailMessageHandler implements MessageHandlerInterface
{
private $mailer;

public function __construct(\Swift_Mailer $mailer)
{
    $this->mailer = $mailer;
}

public function __invoke(SendEmailMessage $message)
{
    $mail = (new \Swift_Message())
        ->setFrom($message->getFrom())
        ->setTo($message->getTo())
        ->setBody($message->getBody(), $message->getContentType())
        ->setSubject($message->getSubject());
    $response = $this->mailer->send($mail);
}
}

回复正常,但邮件始终没有到达我的邮箱。

这是我发送 SendEmailMessage 的方式:

class AskResetPassword extends AbstractController
{
use ResetPasswordControllerTrait;

private $resetPasswordHelper;
private $validator;
private $bus;

public function __construct(ResetPasswordHelperInterface $resetPasswordHelper, ValidatorInterface $validator, MessageBusInterface $bus)
{
    $this->resetPasswordHelper = $resetPasswordHelper;
    $this->validator = $validator;
    $this->bus = $bus;
}

public function __invoke($data)
{
    $emailConstraints = new Assert\Email();

    $email = $data->getEmail();
    if ($email) {
        $errors = $this->validator->validate($email, $emailConstraints);
        if (count($errors) === 0) {
            return $this->processPasswordReset($email);
        } else {
            return new JsonResponse(['success' => false, 'error' => 'Invalid E-Mail format'], 404);
        }
    }
}

private function processPasswordReset($email)
{
    $user = $this->getDoctrine()->getRepository(User::class)->findOneBy([
        'email' => $email,
    ]);

    $this->setCanCheckEmailInSession();

    if (!$user) {
        // Do not reveal whether a user account was found or not.
        return new JsonResponse(['success' => true], 200);
    }

    try {
        $resetToken = $this->resetPasswordHelper->generateResetToken($user);
    } catch (ResetPasswordExceptionInterface $e) {
        return new JsonResponse(['success' => false, 'error' => 'There was a problem handling your password reset request - ' . $e->getReason()]);
    }
    $message = new SendEmailMessage($email);
    $message->setFrom('from.from@from.from');
    $message->setBody(
        $this->renderView('reset_password/email.html.twig', [
            'resetToken' => $resetToken,
            'tokenLifetime' => $this->resetPasswordHelper->getTokenLifetime()
        ])
    );
    $message->setSubject('Votre demande de changement de mot de passe');
    $this->bus->dispatch($message);

    return new JsonResponse(['success' => true], 200);
}
}

这是我的 swiftmailer.yaml:

swiftmailer:
    url: '%env(MAILER_URL)%'
    spool: { type: 'memory' }

你能帮帮我吗?

【问题讨论】:

  • Swiftmailer 的配置是什么?
  • 我添加了我的 Swiftmailer 配置
  • 我猜 MAILER_URL 定义正确
  • 是的,我在控制器中使用了这段代码,一切正常
  • 你是如何发送 SendEmailMessage 的?

标签: php symfony email message-queue swiftmailer


【解决方案1】:

答案是“不要假脱机电子邮件,除非您想稍后处理它们”。 查看文档Spool Emails

假脱机程序是一种队列机制,它将逐个处理您的消息队列。这是在 swift-mailer 被重写并添加回 symfony 时引入的。与提供抽象接口 MessageBusInterface 的 Messenger 组件结合使用,它将委托给正确的后端服务,该服务可以是 smtp 中继、推送通知或任何其他类型的 RPC,它们可能会在单独的 Web 服务上触发操作。

随着 symfony 向消息总线添加新功能,添加此功能是为了将其用于消息队列和其他服务,其中事务性电子邮件和通知是分开处理的。

要处理您的线轴,只需运行:

APP_ENV=prod php bin/console swiftmailer:spool:send

在典型的安装中,spooling 是禁用的,当你在内存中启用 spooling 时,它会等到请求完成并且内核即将退出。如果您正在使用其他任何东西进行调试而导致内核中途终止,或者应用程序的其他组件和部分将内核保留在内存中,则不会触发事件并且不会发送邮件。

您可以在此处查看整个文档:Sending Emails

【讨论】:

    【解决方案2】:

    我不记得确切的原因,并且在发布此内容时我正在努力寻找答案,但 swiftmailer 类型必须是文件而不是内存。这个GitHub issue 引用了这个。也可以看看如何更改here的类型。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-05-23
      • 1970-01-01
      • 2014-11-19
      • 1970-01-01
      • 2019-10-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多