WEBVTT

NOTE Created by CaptionSync from Automatic Sync Technologies www.automaticsync.com

00:00:02.156 --> 00:00:06.806 align:middle
In Mailtrap, when we send emails in production,
remember that we can check each email:

00:00:06.856 --> 00:00:10.966 align:middle
was it sent, delivered, opened,
bounced (which is important!)

00:00:10.966 --> 00:00:16.756 align:middle
and more. Mailtrap lets us set a webhook URL
so it can send info about these events to us.

00:00:17.316 --> 00:00:20.516 align:middle
As a bonus, we get to discover
two new Symfony components!

00:00:20.516 --> 00:00:22.436 align:middle
Find your terminal and install them:

00:00:22.726 --> 00:00:28.816 align:middle
composer require webhook remote-event The
webhook component gives us a single endpoint

00:00:28.816 --> 00:00:30.346 align:middle
to send all webhooks to.

00:00:30.796 --> 00:00:33.626 align:middle
It parses the data sent to
us - called the payload,

00:00:33.966 --> 00:00:37.946 align:middle
converts it to a remote event
object, and sends it to a consumer.

00:00:38.466 --> 00:00:41.536 align:middle
You can think of remote events
as similar to Symfony events.

00:00:41.756 --> 00:00:43.946 align:middle
Instead of your app dispatching an event,

00:00:44.046 --> 00:00:47.156 align:middle
a third-party service does
it - hence remote event.

00:00:47.556 --> 00:00:51.826 align:middle
And instead of event listeners, we
say that remote events have consumers.

00:00:53.066 --> 00:00:58.576 align:middle
Run git status to see what the recipe
added: config/routes/webhook.yaml.

00:00:58.896 --> 00:01:01.196 align:middle
Cool! That adds the webhook controller.

00:01:01.516 --> 00:01:08.496 align:middle
Check out the route with: symfony console
debug:route webhook Check the first one.

00:01:08.686 --> 00:01:10.856 align:middle
The path is /webhook/{type}.

00:01:10.856 --> 00:01:14.226 align:middle
So now we need to configure some sort of a type.

00:01:14.416 --> 00:01:20.526 align:middle
3rd party webhooks - like from Mailtrap or a
payment processor or a supernova alert system -

00:01:20.786 --> 00:01:22.856 align:middle
can send us wildly different payloads,

00:01:23.196 --> 00:01:26.106 align:middle
we typically need to create our
own parsers and remote events.

00:01:26.266 --> 00:01:31.126 align:middle
Since email events are pretty standard, Symfony
provides some out-of-the-box remote events

00:01:31.126 --> 00:01:35.086 align:middle
for these: MailerDeliveryEvent
and MailerEngagementEvent.

00:01:35.196 --> 00:01:38.606 align:middle
Some mailer bridges, including
the Mailtrap bridge we're using,

00:01:38.836 --> 00:01:43.086 align:middle
provide parsers for each service's
webhook payload to create these objects.

00:01:43.486 --> 00:01:44.636 align:middle
We just need to set it up.

00:01:45.056 --> 00:01:48.636 align:middle
In config/packages/, create a webhook.yaml file.

00:01:48.636 --> 00:01:57.356 align:middle
Add: framework, webhook, routing, mailtrap (this
is the type used in the URL), and then service.

00:01:57.356 --> 00:02:03.546 align:middle
To figure out the Mailtrap parser service id,
pop over to the Symfony Webhook documentation.

00:02:04.986 --> 00:02:09.906 align:middle
Find the service id for the
Mailtrap parser, copy it...

00:02:09.906 --> 00:02:12.526 align:middle
and paste it here: Now we need a consumer.

00:02:13.926 --> 00:02:19.016 align:middle
Create a new class called
EmailEventConsumer in the App\Webhook namespace.

00:02:21.916 --> 00:02:28.886 align:middle
This needs to implement ConsumerInterface from
RemoteEvent Add the necessary consume() method.

00:02:30.556 --> 00:02:33.526 align:middle
To tell Symfony which webhook
type we want this to consume,

00:02:33.776 --> 00:02:40.956 align:middle
add the #[AsRemoteEventConsumer]
attribute with mailtrap: Above consume(),

00:02:40.956 --> 00:02:42.826 align:middle
add a docblock to help our IDE:

00:02:43.706 --> 00:02:49.116 align:middle
@param MailerDeliveryEvent|MailerEngagementEvent
$event:

00:02:49.936 --> 00:02:53.076 align:middle
These are the generic mailer
remote events Symfony provides.

00:02:54.056 --> 00:02:57.526 align:middle
Inside, write $event-&gt; to
see the methods available.

00:02:58.346 --> 00:03:01.786 align:middle
In a real app, this would be where you'd do
something with these events like save them

00:03:01.786 --> 00:03:05.186 align:middle
to the database or notify an
admin if an email bounced.

00:03:05.566 --> 00:03:09.446 align:middle
Actually if an email bounces a few
times, you may want to update something

00:03:09.446 --> 00:03:12.976 align:middle
to prevent trying again as this
can hurt your email reliability.

00:03:13.586 --> 00:03:17.536 align:middle
But for our purposes, just
dump($event): One last thing:

00:03:17.886 --> 00:03:22.276 align:middle
the webhook controller sends the remote
event to the consumer via Symfony Messenger,

00:03:22.556 --> 00:03:26.776 align:middle
inside of a message class called
ConsumeRemoteEventMessage.

00:03:27.426 --> 00:03:31.186 align:middle
To handle this asynchronously &amp;
keep your webhook responses fast,

00:03:31.606 --> 00:03:36.156 align:middle
in config/packages/messenger.yaml,
under routing,

00:03:36.926 --> 00:03:42.706 align:middle
add Symfony\Component\RemoteEvent\Messenger
ConsumeRemoteEventMessage

00:03:43.036 --> 00:03:46.096 align:middle
and send it to our async transport: Ok!

00:03:46.096 --> 00:03:47.736 align:middle
We're ready to demo this webhook.

00:03:47.966 --> 00:03:48.656 align:middle
That's next!

