Skip to content

Commit 6b652f2

Browse files
committed
[Webhook] Added component documentation for use in combination with Mailer
1 parent 8ca8c9b commit 6b652f2

File tree

4 files changed

+149
-0
lines changed

4 files changed

+149
-0
lines changed

index.rst

+1
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ Topics
5858
translation
5959
validation
6060
web_link
61+
webhook
6162
workflow
6263

6364
Components

reference/attributes.rst

+5
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,11 @@ Each validation constraint comes with a PHP attribute. See
112112

113113
* :doc:`HasNamedArguments </validation/custom_constraint>`
114114

115+
Webhook
116+
~~~~~~~
117+
118+
* :ref:`AsRemoteEventConsumer <webhook>`
119+
115120
.. _`AsEntityAutocompleteField`: https://symfony.com/bundles/ux-autocomplete/current/index.html#usage-in-a-form-with-ajax
116121
.. _`AsLiveComponent`: https://symfony.com/bundles/ux-live-component/current/index.html
117122
.. _`AsTwigComponent`: https://symfony.com/bundles/ux-twig-component/current/index.html

reference/configuration/framework.rst

+10
Original file line numberDiff line numberDiff line change
@@ -3625,6 +3625,16 @@ enabled
36253625

36263626
Adds a `Link HTTP header`_ to the response.
36273627

3628+
webhook
3629+
~~~~~~~
3630+
3631+
.. versionadded:: 6.3
3632+
3633+
The Webhook configuration was introduced in Symfony 6.3.
3634+
3635+
The ``webhook`` option (and its children) are used to configure the webhooks
3636+
defined in your application. Read more about the options in the :ref:`Webhooks documentation <webhook>`.
3637+
36283638
workflows
36293639
~~~~~~~~~
36303640

webhook.rst

+133
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
Webhook
2+
=======
3+
4+
.. versionadded:: 6.3
5+
6+
The Webhook component was introduced in Symfony 6.3
7+
8+
The webhook component is used to respond to remote webhooks to trigger actions
9+
in your application. This document focusses on using webhooks to listen to remote
10+
events in other Symfony components.
11+
12+
Installation
13+
------------
14+
15+
.. code-block:: terminal
16+
17+
$ composer require symfony/webhook
18+
19+
Usage in combination with the Mailer component
20+
----------------------------------------------
21+
22+
When using a third-party mailer, you can use the webhook component to receive
23+
webhook calls from the third-party mailer.
24+
25+
In this example Mailgun is used with ``'mailer_mailgun'`` as webhook type.
26+
Any type name can be used as long as it's unique. Make sure to use it in the
27+
routing configuration, the webhook URL and the Remote Event Consumer.
28+
29+
Install the third party mailer as described in the documentation of the mailer
30+
component.
31+
32+
The webhook component routing needs to be defined:
33+
34+
.. configuration-block::
35+
36+
.. code-block:: yaml
37+
38+
# config/packages/framework.yaml
39+
framework:
40+
webhook:
41+
routing:
42+
mailer_mailgun:
43+
service: 'mailer.webhook.request_parser.mailgun'
44+
secret: '%env(MAILER_MAILGUN_SECRET)%'
45+
46+
.. code-block:: xml
47+
48+
<!-- config/packages/framework.xml -->
49+
<?xml version="1.0" encoding="UTF-8" ?>
50+
<container xmlns="http://symfony.com/schema/dic/services"
51+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
52+
xmlns:framework="http://symfony.com/schema/dic/symfony"
53+
xsi:schemaLocation="http://symfony.com/schema/dic/services
54+
https://symfony.com/schema/dic/services/services-1.0.xsd
55+
http://symfony.com/schema/dic/symfony https://symfony.com/schema/dic/symfony/symfony-1.0.xsd">
56+
<framework:config>
57+
<framework:webhook enabled="true">
58+
<framework:routing type="mailer_mailgun">
59+
<framework:service>mailer.webhook.request_parser.mailgun</framework:service>
60+
<framework:secret>%env(MAILER_MAILGUN_SECRET)%</framework:secret>
61+
</framework:routing>
62+
</framework:webhook>
63+
</framework:config>
64+
</container>
65+
66+
.. code-block:: php
67+
68+
// config/packages/framework.php
69+
use App\Webhook\MailerWebhookParser;
70+
use Symfony\Config\FrameworkConfig;
71+
return static function (FrameworkConfig $frameworkConfig): void {
72+
$webhookConfig = $frameworkConfig->webhook();
73+
$webhookConfig
74+
->routing('mailer_mailgun')
75+
->service('mailer.webhook.request_parser.mailgun')
76+
->secret('%env(MAILER_MAILGUN_SECRET)%')
77+
;
78+
};
79+
80+
Currently, the following third-party mailer services support webhooks:
81+
82+
=============== ==========================================
83+
Mailer service Parser service name
84+
=============== ==========================================
85+
Mailgun ``mailer.webhook.request_parser.mailgun``
86+
Postmark ``mailer.webhook.request_parser.postmark``
87+
Sendgrid ``mailer.webhook.request_parser.sendgrid``
88+
=============== ==========================================
89+
90+
Set up the webhook in the third-party mailer. For Mailgun, you can do this
91+
in the control panel. As URL, make sure to use the ``/webhook/mailer_mailgun``
92+
path behind the domain you're using.
93+
94+
Mailgun will provide a secret for the webhook. Add this secret to your ``.env``
95+
file:
96+
97+
.. code-block:: env
98+
99+
MAILER_MAILGUN_SECRET=your_secret
100+
101+
With this done, you can now add Remote Event Consumers to react to the webhooks::
102+
103+
use Symfony\Component\RemoteEvent\Attribute\AsRemoteEventConsumer;
104+
use Symfony\Component\RemoteEvent\Consumer\ConsumerInterface;
105+
use Symfony\Component\RemoteEvent\Event\Mailer\MailerDeliveryEvent;
106+
use Symfony\Component\RemoteEvent\Event\Mailer\MailerEngagementEvent;
107+
use Symfony\Component\RemoteEvent\RemoteEvent;
108+
109+
#[AsRemoteEventConsumer('mailer_mailgun')]
110+
final readonly class WebhookListener implements ConsumerInterface
111+
{
112+
public function consume(RemoteEvent $event): void
113+
{
114+
if ($event instanceof MailerDeliveryEvent) {
115+
$this->handleMailDelivery($event);
116+
} elseif ($event instanceof MailerEngagementEvent) {
117+
$this->handleMailEngagement($event);
118+
} else {
119+
// This is not an email event
120+
return;
121+
}
122+
}
123+
124+
private function handleMailDelivery(MailerDeliveryEvent $event): void
125+
{
126+
// Handle the mail delivery event
127+
}
128+
129+
private function handleMailEngagement(MailerEngagementEvent $event): void
130+
{
131+
// Handle the mail engagement event
132+
}
133+
}

0 commit comments

Comments
 (0)