From 2273b2260cc9de68c67674651dfb5de52e242f3b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20Andr=C3=A9?= Date: Tue, 8 Aug 2023 03:02:13 +0200 Subject: [PATCH] [RemoteEvent][Webhook] Add Sendgrid support --- .../Mailer/Bridge/Sendgrid/CHANGELOG.md | 5 ++ .../RemoteEvent/SendgridPayloadConverter.php | 61 ++++++++++++++++++ .../Tests/Webhook/Fixtures/bounce.json | 15 +++++ .../Tests/Webhook/Fixtures/bounce.php | 11 ++++ .../Tests/Webhook/Fixtures/click.json | 14 +++++ .../Sendgrid/Tests/Webhook/Fixtures/click.php | 10 +++ .../Tests/Webhook/Fixtures/deferred.json | 14 +++++ .../Tests/Webhook/Fixtures/deferred.php | 10 +++ .../Tests/Webhook/Fixtures/delivered.json | 13 ++++ .../Tests/Webhook/Fixtures/delivered.php | 10 +++ .../Tests/Webhook/Fixtures/dropped.json | 13 ++++ .../Tests/Webhook/Fixtures/dropped.php | 11 ++++ .../Webhook/Fixtures/group_unsubscribe.json | 15 +++++ .../Webhook/Fixtures/group_unsubscribe.php | 10 +++ .../Sendgrid/Tests/Webhook/Fixtures/open.json | 14 +++++ .../Sendgrid/Tests/Webhook/Fixtures/open.php | 10 +++ .../Tests/Webhook/Fixtures/processed.json | 11 ++++ .../Tests/Webhook/Fixtures/processed.php | 10 +++ .../Tests/Webhook/Fixtures/spamreport.json | 10 +++ .../Tests/Webhook/Fixtures/spamreport.php | 9 +++ .../Tests/Webhook/Fixtures/unsubscribe.json | 11 ++++ .../Tests/Webhook/Fixtures/unsubscribe.php | 10 +++ .../Webhook/SendgridRequestParserTest.php | 25 ++++++++ .../Webhook/SendgridRequestParser.php | 63 +++++++++++++++++++ .../Mailer/Bridge/Sendgrid/composer.json | 3 +- 25 files changed, 387 insertions(+), 1 deletion(-) create mode 100644 src/Symfony/Component/Mailer/Bridge/Sendgrid/RemoteEvent/SendgridPayloadConverter.php create mode 100644 src/Symfony/Component/Mailer/Bridge/Sendgrid/Tests/Webhook/Fixtures/bounce.json create mode 100644 src/Symfony/Component/Mailer/Bridge/Sendgrid/Tests/Webhook/Fixtures/bounce.php create mode 100644 src/Symfony/Component/Mailer/Bridge/Sendgrid/Tests/Webhook/Fixtures/click.json create mode 100644 src/Symfony/Component/Mailer/Bridge/Sendgrid/Tests/Webhook/Fixtures/click.php create mode 100644 src/Symfony/Component/Mailer/Bridge/Sendgrid/Tests/Webhook/Fixtures/deferred.json create mode 100644 src/Symfony/Component/Mailer/Bridge/Sendgrid/Tests/Webhook/Fixtures/deferred.php create mode 100644 src/Symfony/Component/Mailer/Bridge/Sendgrid/Tests/Webhook/Fixtures/delivered.json create mode 100644 src/Symfony/Component/Mailer/Bridge/Sendgrid/Tests/Webhook/Fixtures/delivered.php create mode 100644 src/Symfony/Component/Mailer/Bridge/Sendgrid/Tests/Webhook/Fixtures/dropped.json create mode 100644 src/Symfony/Component/Mailer/Bridge/Sendgrid/Tests/Webhook/Fixtures/dropped.php create mode 100644 src/Symfony/Component/Mailer/Bridge/Sendgrid/Tests/Webhook/Fixtures/group_unsubscribe.json create mode 100644 src/Symfony/Component/Mailer/Bridge/Sendgrid/Tests/Webhook/Fixtures/group_unsubscribe.php create mode 100644 src/Symfony/Component/Mailer/Bridge/Sendgrid/Tests/Webhook/Fixtures/open.json create mode 100644 src/Symfony/Component/Mailer/Bridge/Sendgrid/Tests/Webhook/Fixtures/open.php create mode 100644 src/Symfony/Component/Mailer/Bridge/Sendgrid/Tests/Webhook/Fixtures/processed.json create mode 100644 src/Symfony/Component/Mailer/Bridge/Sendgrid/Tests/Webhook/Fixtures/processed.php create mode 100644 src/Symfony/Component/Mailer/Bridge/Sendgrid/Tests/Webhook/Fixtures/spamreport.json create mode 100644 src/Symfony/Component/Mailer/Bridge/Sendgrid/Tests/Webhook/Fixtures/spamreport.php create mode 100644 src/Symfony/Component/Mailer/Bridge/Sendgrid/Tests/Webhook/Fixtures/unsubscribe.json create mode 100644 src/Symfony/Component/Mailer/Bridge/Sendgrid/Tests/Webhook/Fixtures/unsubscribe.php create mode 100644 src/Symfony/Component/Mailer/Bridge/Sendgrid/Tests/Webhook/SendgridRequestParserTest.php create mode 100644 src/Symfony/Component/Mailer/Bridge/Sendgrid/Webhook/SendgridRequestParser.php diff --git a/src/Symfony/Component/Mailer/Bridge/Sendgrid/CHANGELOG.md b/src/Symfony/Component/Mailer/Bridge/Sendgrid/CHANGELOG.md index 40a44c58c4614..31ca187542b40 100644 --- a/src/Symfony/Component/Mailer/Bridge/Sendgrid/CHANGELOG.md +++ b/src/Symfony/Component/Mailer/Bridge/Sendgrid/CHANGELOG.md @@ -1,6 +1,11 @@ CHANGELOG ========= +6.4 +--- + +* Add support for `RemoteEvent` and `Webhook` + 5.4 --- diff --git a/src/Symfony/Component/Mailer/Bridge/Sendgrid/RemoteEvent/SendgridPayloadConverter.php b/src/Symfony/Component/Mailer/Bridge/Sendgrid/RemoteEvent/SendgridPayloadConverter.php new file mode 100644 index 0000000000000..2e0d53a230787 --- /dev/null +++ b/src/Symfony/Component/Mailer/Bridge/Sendgrid/RemoteEvent/SendgridPayloadConverter.php @@ -0,0 +1,61 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mailer\Bridge\Sendgrid\RemoteEvent; + +use Symfony\Component\RemoteEvent\Event\Mailer\AbstractMailerEvent; +use Symfony\Component\RemoteEvent\Event\Mailer\MailerDeliveryEvent; +use Symfony\Component\RemoteEvent\Event\Mailer\MailerEngagementEvent; +use Symfony\Component\RemoteEvent\Exception\ParseException; +use Symfony\Component\RemoteEvent\PayloadConverterInterface; + +final class SendgridPayloadConverter implements PayloadConverterInterface +{ + public function convert(array $payload): AbstractMailerEvent + { + if (\in_array($payload['event'], ['bounce', 'deferred', 'delivered', 'dropped', 'processed'], true)) { + $name = match ($payload['event']) { + 'bounce' => MailerDeliveryEvent::BOUNCE, + 'deferred' => MailerDeliveryEvent::DEFERRED, + 'delivered' => MailerDeliveryEvent::DELIVERED, + 'dropped' => MailerDeliveryEvent::DROPPED, + 'processed' => MailerDeliveryEvent::RECEIVED, + }; + $event = new MailerDeliveryEvent($name, $payload['sg_event_id'], $payload); + if (isset($payload['reason'])) { + $event->setReason($payload['reason']); + } + } else { + $name = match ($payload['event']) { + 'click' => MailerEngagementEvent::CLICK, + 'group_unsubscribe' => MailerEngagementEvent::UNSUBSCRIBE, + 'open' => MailerEngagementEvent::OPEN, + 'spamreport' => MailerEngagementEvent::SPAM, + 'unsubscribe' => MailerEngagementEvent::UNSUBSCRIBE, + default => throw new ParseException(sprintf('Unsupported event "%s".', $payload['event'])), + }; + $event = new MailerEngagementEvent($name, $payload['sg_event_id'], $payload); + } + + if (!$date = \DateTimeImmutable::createFromFormat('U', $payload['timestamp'])) { + throw new ParseException(sprintf('Invalid date "%s".', $payload['timestamp'])); + } + $event->setDate($date); + + $event->setRecipientEmail($payload['email']); + + if (isset($payload['category'])) { + $event->setTags((array) $payload['category']); + } + + return $event; + } +} diff --git a/src/Symfony/Component/Mailer/Bridge/Sendgrid/Tests/Webhook/Fixtures/bounce.json b/src/Symfony/Component/Mailer/Bridge/Sendgrid/Tests/Webhook/Fixtures/bounce.json new file mode 100644 index 0000000000000..00cef3b94ac20 --- /dev/null +++ b/src/Symfony/Component/Mailer/Bridge/Sendgrid/Tests/Webhook/Fixtures/bounce.json @@ -0,0 +1,15 @@ +[ + { + "email": "example@test.com", + "timestamp": 1513299569, + "smtp-id": "<14c5d75ce93.dfd.64b469@ismtpd-555>", + "bounce_classification": "invalid", + "event": "bounce", + "ip": "168.1.1.1", + "category": "cat facts", + "sg_event_id": "sg_event_id", + "sg_message_id": "sg_message_id", + "reason": "500 unknown recipient", + "status": "5.0.0" + } +] diff --git a/src/Symfony/Component/Mailer/Bridge/Sendgrid/Tests/Webhook/Fixtures/bounce.php b/src/Symfony/Component/Mailer/Bridge/Sendgrid/Tests/Webhook/Fixtures/bounce.php new file mode 100644 index 0000000000000..d7ab66f7d622a --- /dev/null +++ b/src/Symfony/Component/Mailer/Bridge/Sendgrid/Tests/Webhook/Fixtures/bounce.php @@ -0,0 +1,11 @@ +setRecipientEmail('example@test.com'); +$wh->setDate(\DateTimeImmutable::createFromFormat('U', 1513299569)); +$wh->setReason('500 unknown recipient'); +$wh->setTags(['cat facts']); + +return $wh; diff --git a/src/Symfony/Component/Mailer/Bridge/Sendgrid/Tests/Webhook/Fixtures/click.json b/src/Symfony/Component/Mailer/Bridge/Sendgrid/Tests/Webhook/Fixtures/click.json new file mode 100644 index 0000000000000..2a01aff745c58 --- /dev/null +++ b/src/Symfony/Component/Mailer/Bridge/Sendgrid/Tests/Webhook/Fixtures/click.json @@ -0,0 +1,14 @@ +[ + { + "email": "example@test.com", + "timestamp": 1513299569, + "smtp-id": "<14c5d75ce93.dfd.64b469@ismtpd-555>", + "event": "click", + "category": "cat facts", + "sg_event_id": "sg_event_id", + "sg_message_id": "sg_message_id", + "useragent": "Mozilla/4.0 (compatible; MSIE 6.1; Windows XP; .NET CLR 1.1.4322; .NET CLR 2.0.50727)", + "ip": "255.255.255.255", + "url": "http://www.sendgrid.com/" + } +] diff --git a/src/Symfony/Component/Mailer/Bridge/Sendgrid/Tests/Webhook/Fixtures/click.php b/src/Symfony/Component/Mailer/Bridge/Sendgrid/Tests/Webhook/Fixtures/click.php new file mode 100644 index 0000000000000..8162502aa6293 --- /dev/null +++ b/src/Symfony/Component/Mailer/Bridge/Sendgrid/Tests/Webhook/Fixtures/click.php @@ -0,0 +1,10 @@ +setRecipientEmail('example@test.com'); +$wh->setDate(\DateTimeImmutable::createFromFormat('U', 1513299569)); +$wh->setTags(['cat facts']); + +return $wh; diff --git a/src/Symfony/Component/Mailer/Bridge/Sendgrid/Tests/Webhook/Fixtures/deferred.json b/src/Symfony/Component/Mailer/Bridge/Sendgrid/Tests/Webhook/Fixtures/deferred.json new file mode 100644 index 0000000000000..2a8060f904cb1 --- /dev/null +++ b/src/Symfony/Component/Mailer/Bridge/Sendgrid/Tests/Webhook/Fixtures/deferred.json @@ -0,0 +1,14 @@ +[ + { + "email": "example@test.com", + "timestamp": 1513299569, + "smtp-id": "<14c5d75ce93.dfd.64b469@ismtpd-555>", + "event": "deferred", + "ip": "168.1.1.1", + "category": "cat facts", + "sg_event_id": "sg_event_id", + "sg_message_id": "sg_message_id", + "response": "400 try again later", + "attempt": "5" + } +] diff --git a/src/Symfony/Component/Mailer/Bridge/Sendgrid/Tests/Webhook/Fixtures/deferred.php b/src/Symfony/Component/Mailer/Bridge/Sendgrid/Tests/Webhook/Fixtures/deferred.php new file mode 100644 index 0000000000000..4447e3f533cb7 --- /dev/null +++ b/src/Symfony/Component/Mailer/Bridge/Sendgrid/Tests/Webhook/Fixtures/deferred.php @@ -0,0 +1,10 @@ +setRecipientEmail('example@test.com'); +$wh->setDate(\DateTimeImmutable::createFromFormat('U', 1513299569)); +$wh->setTags(['cat facts']); + +return $wh; diff --git a/src/Symfony/Component/Mailer/Bridge/Sendgrid/Tests/Webhook/Fixtures/delivered.json b/src/Symfony/Component/Mailer/Bridge/Sendgrid/Tests/Webhook/Fixtures/delivered.json new file mode 100644 index 0000000000000..451520bd1b234 --- /dev/null +++ b/src/Symfony/Component/Mailer/Bridge/Sendgrid/Tests/Webhook/Fixtures/delivered.json @@ -0,0 +1,13 @@ +[ + { + "email": "example@test.com", + "timestamp": 1513299569, + "smtp-id": "<14c5d75ce93.dfd.64b469@ismtpd-555>", + "event": "delivered", + "ip": "168.1.1.1", + "category": "cat facts", + "sg_event_id": "sg_event_id", + "sg_message_id": "sg_message_id", + "response": "250 OK" + } +] diff --git a/src/Symfony/Component/Mailer/Bridge/Sendgrid/Tests/Webhook/Fixtures/delivered.php b/src/Symfony/Component/Mailer/Bridge/Sendgrid/Tests/Webhook/Fixtures/delivered.php new file mode 100644 index 0000000000000..de6ac2332910a --- /dev/null +++ b/src/Symfony/Component/Mailer/Bridge/Sendgrid/Tests/Webhook/Fixtures/delivered.php @@ -0,0 +1,10 @@ +setRecipientEmail('example@test.com'); +$wh->setDate(\DateTimeImmutable::createFromFormat('U', 1513299569)); +$wh->setTags(['cat facts']); + +return $wh; diff --git a/src/Symfony/Component/Mailer/Bridge/Sendgrid/Tests/Webhook/Fixtures/dropped.json b/src/Symfony/Component/Mailer/Bridge/Sendgrid/Tests/Webhook/Fixtures/dropped.json new file mode 100644 index 0000000000000..f2ab568b31f1f --- /dev/null +++ b/src/Symfony/Component/Mailer/Bridge/Sendgrid/Tests/Webhook/Fixtures/dropped.json @@ -0,0 +1,13 @@ +[ + { + "email": "example@test.com", + "timestamp": 1513299569, + "smtp-id": "<14c5d75ce93.dfd.64b469@ismtpd-555>", + "event": "dropped", + "category": "cat facts", + "sg_event_id": "sg_event_id", + "sg_message_id": "sg_message_id", + "reason": "Bounced Address", + "status": "5.0.0" + } +] diff --git a/src/Symfony/Component/Mailer/Bridge/Sendgrid/Tests/Webhook/Fixtures/dropped.php b/src/Symfony/Component/Mailer/Bridge/Sendgrid/Tests/Webhook/Fixtures/dropped.php new file mode 100644 index 0000000000000..58c1f88bac04a --- /dev/null +++ b/src/Symfony/Component/Mailer/Bridge/Sendgrid/Tests/Webhook/Fixtures/dropped.php @@ -0,0 +1,11 @@ +setDate(\DateTimeImmutable::createFromFormat('U', 1513299569)); +$wh->setReason('Bounced Address'); +$wh->setRecipientEmail('example@test.com'); +$wh->setTags(['cat facts']); + +return $wh; diff --git a/src/Symfony/Component/Mailer/Bridge/Sendgrid/Tests/Webhook/Fixtures/group_unsubscribe.json b/src/Symfony/Component/Mailer/Bridge/Sendgrid/Tests/Webhook/Fixtures/group_unsubscribe.json new file mode 100644 index 0000000000000..50fef1d1e0021 --- /dev/null +++ b/src/Symfony/Component/Mailer/Bridge/Sendgrid/Tests/Webhook/Fixtures/group_unsubscribe.json @@ -0,0 +1,15 @@ +[ + { + "email": "example@test.com", + "timestamp": 1513299569, + "smtp-id": "<14c5d75ce93.dfd.64b469@ismtpd-555>", + "event": "group_unsubscribe", + "category": "cat facts", + "sg_event_id": "sg_event_id", + "sg_message_id": "sg_message_id", + "useragent": "Mozilla/4.0 (compatible; MSIE 6.1; Windows XP; .NET CLR 1.1.4322; .NET CLR 2.0.50727)", + "ip": "255.255.255.255", + "url": "http://www.sendgrid.com/", + "asm_group_id": 10 + } +] diff --git a/src/Symfony/Component/Mailer/Bridge/Sendgrid/Tests/Webhook/Fixtures/group_unsubscribe.php b/src/Symfony/Component/Mailer/Bridge/Sendgrid/Tests/Webhook/Fixtures/group_unsubscribe.php new file mode 100644 index 0000000000000..27945f0f3b369 --- /dev/null +++ b/src/Symfony/Component/Mailer/Bridge/Sendgrid/Tests/Webhook/Fixtures/group_unsubscribe.php @@ -0,0 +1,10 @@ +setRecipientEmail('example@test.com'); +$wh->setDate(\DateTimeImmutable::createFromFormat('U', 1513299569)); +$wh->setTags(['cat facts']); + +return $wh; diff --git a/src/Symfony/Component/Mailer/Bridge/Sendgrid/Tests/Webhook/Fixtures/open.json b/src/Symfony/Component/Mailer/Bridge/Sendgrid/Tests/Webhook/Fixtures/open.json new file mode 100644 index 0000000000000..7eac61cafc93a --- /dev/null +++ b/src/Symfony/Component/Mailer/Bridge/Sendgrid/Tests/Webhook/Fixtures/open.json @@ -0,0 +1,14 @@ +[ + { + "email": "example@test.com", + "timestamp": 1513299569, + "smtp-id": "<14c5d75ce93.dfd.64b469@ismtpd-555>", + "event": "open", + "sg_machine_open": false, + "category": "cat facts", + "sg_event_id": "sg_event_id", + "sg_message_id": "sg_message_id", + "useragent": "Mozilla/4.0 (compatible; MSIE 6.1; Windows XP; .NET CLR 1.1.4322; .NET CLR 2.0.50727)", + "ip": "255.255.255.255" + } +] diff --git a/src/Symfony/Component/Mailer/Bridge/Sendgrid/Tests/Webhook/Fixtures/open.php b/src/Symfony/Component/Mailer/Bridge/Sendgrid/Tests/Webhook/Fixtures/open.php new file mode 100644 index 0000000000000..116ab2275959f --- /dev/null +++ b/src/Symfony/Component/Mailer/Bridge/Sendgrid/Tests/Webhook/Fixtures/open.php @@ -0,0 +1,10 @@ +setRecipientEmail('example@test.com'); +$wh->setDate(\DateTimeImmutable::createFromFormat('U', 1513299569)); +$wh->setTags(['cat facts']); + +return $wh; diff --git a/src/Symfony/Component/Mailer/Bridge/Sendgrid/Tests/Webhook/Fixtures/processed.json b/src/Symfony/Component/Mailer/Bridge/Sendgrid/Tests/Webhook/Fixtures/processed.json new file mode 100644 index 0000000000000..9c5b3cdd0c121 --- /dev/null +++ b/src/Symfony/Component/Mailer/Bridge/Sendgrid/Tests/Webhook/Fixtures/processed.json @@ -0,0 +1,11 @@ +[ + { + "email": "example@test.com", + "timestamp": 1513299569, + "smtp-id": "<14c5d75ce93.dfd.64b469@ismtpd-555>", + "event": "processed", + "category": "cat facts", + "sg_event_id": "sg_event_id", + "sg_message_id": "sg_message_id" + } +] diff --git a/src/Symfony/Component/Mailer/Bridge/Sendgrid/Tests/Webhook/Fixtures/processed.php b/src/Symfony/Component/Mailer/Bridge/Sendgrid/Tests/Webhook/Fixtures/processed.php new file mode 100644 index 0000000000000..15c821edc18cd --- /dev/null +++ b/src/Symfony/Component/Mailer/Bridge/Sendgrid/Tests/Webhook/Fixtures/processed.php @@ -0,0 +1,10 @@ +setDate(\DateTimeImmutable::createFromFormat('U', 1513299569)); +$wh->setRecipientEmail('example@test.com'); +$wh->setTags(['cat facts']); + +return $wh; diff --git a/src/Symfony/Component/Mailer/Bridge/Sendgrid/Tests/Webhook/Fixtures/spamreport.json b/src/Symfony/Component/Mailer/Bridge/Sendgrid/Tests/Webhook/Fixtures/spamreport.json new file mode 100644 index 0000000000000..3a4f171bc58bb --- /dev/null +++ b/src/Symfony/Component/Mailer/Bridge/Sendgrid/Tests/Webhook/Fixtures/spamreport.json @@ -0,0 +1,10 @@ +[ + { + "email": "example@test.com", + "timestamp": 1513299569, + "smtp-id": "<14c5d75ce93.dfd.64b469@ismtpd-555>", + "event": "spamreport", + "sg_event_id": "sg_event_id", + "sg_message_id": "sg_message_id" + } +] diff --git a/src/Symfony/Component/Mailer/Bridge/Sendgrid/Tests/Webhook/Fixtures/spamreport.php b/src/Symfony/Component/Mailer/Bridge/Sendgrid/Tests/Webhook/Fixtures/spamreport.php new file mode 100644 index 0000000000000..b94fd4090a609 --- /dev/null +++ b/src/Symfony/Component/Mailer/Bridge/Sendgrid/Tests/Webhook/Fixtures/spamreport.php @@ -0,0 +1,9 @@ +setRecipientEmail('example@test.com'); +$wh->setDate(\DateTimeImmutable::createFromFormat('U', 1513299569)); + +return $wh; diff --git a/src/Symfony/Component/Mailer/Bridge/Sendgrid/Tests/Webhook/Fixtures/unsubscribe.json b/src/Symfony/Component/Mailer/Bridge/Sendgrid/Tests/Webhook/Fixtures/unsubscribe.json new file mode 100644 index 0000000000000..e0d612ab79e92 --- /dev/null +++ b/src/Symfony/Component/Mailer/Bridge/Sendgrid/Tests/Webhook/Fixtures/unsubscribe.json @@ -0,0 +1,11 @@ +[ + { + "email": "example@test.com", + "timestamp": 1513299569, + "smtp-id": "<14c5d75ce93.dfd.64b469@ismtpd-555>", + "event": "unsubscribe", + "category": "cat facts", + "sg_event_id": "sg_event_id", + "sg_message_id": "sg_message_id" + } +] diff --git a/src/Symfony/Component/Mailer/Bridge/Sendgrid/Tests/Webhook/Fixtures/unsubscribe.php b/src/Symfony/Component/Mailer/Bridge/Sendgrid/Tests/Webhook/Fixtures/unsubscribe.php new file mode 100644 index 0000000000000..350e713026fd5 --- /dev/null +++ b/src/Symfony/Component/Mailer/Bridge/Sendgrid/Tests/Webhook/Fixtures/unsubscribe.php @@ -0,0 +1,10 @@ +setDate(\DateTimeImmutable::createFromFormat('U', 1513299569)); +$wh->setRecipientEmail('example@test.com'); +$wh->setTags(['cat facts']); + +return $wh; diff --git a/src/Symfony/Component/Mailer/Bridge/Sendgrid/Tests/Webhook/SendgridRequestParserTest.php b/src/Symfony/Component/Mailer/Bridge/Sendgrid/Tests/Webhook/SendgridRequestParserTest.php new file mode 100644 index 0000000000000..2ed3fb3b956ed --- /dev/null +++ b/src/Symfony/Component/Mailer/Bridge/Sendgrid/Tests/Webhook/SendgridRequestParserTest.php @@ -0,0 +1,25 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mailer\Bridge\Sendgrid\Tests\Webhook; + +use Symfony\Component\Mailer\Bridge\Sendgrid\RemoteEvent\SendgridPayloadConverter; +use Symfony\Component\Mailer\Bridge\Sendgrid\Webhook\SendgridRequestParser; +use Symfony\Component\Webhook\Client\RequestParserInterface; +use Symfony\Component\Webhook\Test\AbstractRequestParserTestCase; + +class SendgridRequestParserTest extends AbstractRequestParserTestCase +{ + protected function createRequestParser(): RequestParserInterface + { + return new SendgridRequestParser(new SendgridPayloadConverter()); + } +} diff --git a/src/Symfony/Component/Mailer/Bridge/Sendgrid/Webhook/SendgridRequestParser.php b/src/Symfony/Component/Mailer/Bridge/Sendgrid/Webhook/SendgridRequestParser.php new file mode 100644 index 0000000000000..c2e8fc9d75e0a --- /dev/null +++ b/src/Symfony/Component/Mailer/Bridge/Sendgrid/Webhook/SendgridRequestParser.php @@ -0,0 +1,63 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mailer\Bridge\Sendgrid\Webhook; + +use Symfony\Component\HttpFoundation\ChainRequestMatcher; +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpFoundation\RequestMatcher\IsJsonRequestMatcher; +use Symfony\Component\HttpFoundation\RequestMatcher\MethodRequestMatcher; +use Symfony\Component\HttpFoundation\RequestMatcherInterface; +use Symfony\Component\Mailer\Bridge\Sendgrid\RemoteEvent\SendgridPayloadConverter; +use Symfony\Component\RemoteEvent\Event\Mailer\AbstractMailerEvent; +use Symfony\Component\RemoteEvent\Exception\ParseException; +use Symfony\Component\Webhook\Client\AbstractRequestParser; +use Symfony\Component\Webhook\Exception\RejectWebhookException; + +final class SendgridRequestParser extends AbstractRequestParser +{ + public function __construct( + private readonly SendgridPayloadConverter $converter, + ) { + } + + protected function getRequestMatcher(): RequestMatcherInterface + { + return new ChainRequestMatcher([ + new MethodRequestMatcher('POST'), + new IsJsonRequestMatcher(), + ]); + } + + protected function doParse(Request $request, string $secret): ?AbstractMailerEvent + { + $payload = $request->toArray(); + if ( + !\is_array($content = $payload[0] ?? null) + || !isset($content['event']) + || !isset($content['email']) + || !isset($content['sg_event_id']) + || !isset($content['timestamp']) + ) { + throw new RejectWebhookException(406, 'Payload is malformed.'); + } + + if ('group_resubscribe' === $content['event']) { + return null; + } + + try { + return $this->converter->convert($content); + } catch (ParseException $e) { + throw new RejectWebhookException(406, $e->getMessage(), $e); + } + } +} diff --git a/src/Symfony/Component/Mailer/Bridge/Sendgrid/composer.json b/src/Symfony/Component/Mailer/Bridge/Sendgrid/composer.json index 460b176b58374..7e953d54c1405 100644 --- a/src/Symfony/Component/Mailer/Bridge/Sendgrid/composer.json +++ b/src/Symfony/Component/Mailer/Bridge/Sendgrid/composer.json @@ -20,7 +20,8 @@ "symfony/mailer": "^5.4.21|^6.2.7|^7.0" }, "require-dev": { - "symfony/http-client": "^5.4|^6.0|^7.0" + "symfony/http-client": "^5.4|^6.0|^7.0", + "symfony/webhook": "^6.4|^7.0" }, "conflict": { "symfony/mime": "<6.2" pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy