SwiftMailer 不在 MessageHandler 中发送邮件

SwiftMailer not sending mail in MessageHandler

我在我的 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 类型必须是文件而不是内存。这个GitHub issue references this. You can also see how to change the type here.

答案是"DO NOT spool emails unless you want to process them later"。 检查文档 Spool Emails

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

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

简单地处理你的假脱机 运行 :

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

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

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