Edit: This question arose in the attempt to have both synchronous and synchronous emails in the same application. That was not made clear. As of this writing it is not possible, at least not as simply as tried here. See comments by @msg below.
An email service configured to send email asynchronously instead sends emails immediately. This happens with either doctrine
or amqp
selected as MESSENGER_TRANSPORT_DSN
. doctrine
transport successfully creates messenger_messages
table, but with no contents. This tells me the MESSENGER_TRANSPORT_DSN
is observed. Simple test of amqp
using RabbitMQ 'Hello World' tutorial shows it is properly configured.
What have I missed in the code below?
Summary of sequence shown below: Opportunity added -> OppEmailService
creates email contents -> gets TemplatedEmail()
object from EmailerService
(not shown) -> submits TemplatedEmail()
object to LaterEmailService
, which is configured to be async.
messenger.yaml:
framework:
messenger:
transports:
async: '%env(MESSENGER_TRANSPORT_DSN)%'
sync: 'sync://'
routing:
'App\Services\NowEmailService': sync
'App\Services\LaterEmailService': async
OpportunityController
:
class OpportunityController extends AbstractController
{
private $newOpp;
private $templateSvc;
public function __construct(OppEmailService $newOpp, TemplateService $templateSvc)
{
$this->newOpp = $newOpp;
$this->templateSvc = $templateSvc;
}
...
public function addOpp(Request $request): Response
{
...
if ($form->isSubmitted() && $form->isValid()) {
...
$volunteers = $em->getRepository(Person::class)->opportunityEmails($opportunity);
$this->newOpp->oppEmail($volunteers, $opportunity);
...
}
OppEmailService
:
class OppEmailService
{
private $em;
private $makeMail;
private $laterMail;
public function __construct(
EmailerService $makeMail,
EntityManagerInterface $em,
LaterEmailService $laterMail
)
{
$this->makeMail = $makeMail;
$this->em = $em;
$this->laterMail = $laterMail;
}
...
public function oppEmail($volunteers, $opp): array
{
...
$mailParams = [
'template' => 'Email/volunteer_opportunities.html.twig',
'context' => ['fname' => $person->getFname(), 'opportunity' => $opp,],
'recipient' => $person->getEmail(),
'subject' => 'New volunteer opportunity',
];
$toBeSent = $this->makeMail->assembleEmail($mailParams);
$this->laterMail->send($toBeSent);
...
}
}
LaterEmailService
:
namespace App\Services;
use Symfony\Component\Mailer\MailerInterface;
class LaterEmailService
{
private $mailer;
public function __construct(MailerInterface $mailer)
{
$this->mailer = $mailer;
}
public function send($email)
{
$this->mailer->send($email);
}
}