8000 [Mailer] add Mailtrap webhook support · symfony/symfony@1517a70 · GitHub
[go: up one dir, main page]

Skip to content

Commit 1517a70

Browse files
committed
[Mailer] add Mailtrap webhook support
1 parent 81da0f2 commit 1517a70

26 files changed

+476
-1
lines changed

src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2681,6 +2681,7 @@ private function registerMailerConfiguration(array $config, ContainerBuilder $co
26812681
MailerBridge\Mailjet\Webhook\MailjetRequestParser::class => 'mailer.webhook.request_parser.mailjet',
26822682
MailerBridge\Mailomat\Webhook\MailomatRequestParser::class => 'mailer.webhook.request_parser.mailomat',
26832683
MailerBridge\Postmark\Webhook\PostmarkRequestParser::class => 'mailer.webhook.request_parser.postmark',
2684+
MailerBridge\Mailtrap\Webhook\MailtrapRequestParser::class => 'mailer.webhook.request_parser.mailtrap',
26842685
MailerBridge\Resend\Webhook\ResendRequestParser::class => 'mailer.webhook.request_parser.resend',
26852686
MailerBridge\Sendgrid\Webhook\SendgridRequestParser::class => 'mailer.webhook.request_parser.sendgrid',
26862687
MailerBridge\Sweego\Webhook\SweegoRequestParser::class => 'mailer.webhook.request_parser.sweego',

src/Symfony/Bundle/FrameworkBundle/Resources/config/mailer_webhook.php

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@
2121
use Symfony\Component\Mailer\Bridge\Mailjet\Webhook\MailjetRequestParser;
2222
use Symfony\Component\Mailer\Bridge\Mailomat\RemoteEvent\MailomatPayloadConverter;
2323
use Symfony\Component\Mailer\Bridge\Mailomat\Webhook\MailomatRequestParser;
24+
use Symfony\Component\Mailer\Bridge\Mailtrap\RemoteEvent\MailtrapPayloadConverter;
25+
use Symfony\Component\Mailer\Bridge\Mailtrap\Webhook\MailtrapRequestParser;
2426
use Symfony\Component\Mailer\Bridge\Postmark\RemoteEvent\PostmarkPayloadConverter;
2527
use Symfony\Component\Mailer\Bridge\Postmark\Webhook\PostmarkRequestParser;
2628
use Symfony\Component\Mailer\Bridge\Resend\RemoteEvent\ResendPayloadConverter;
@@ -62,6 +64,11 @@
6264
->args([service('mailer.payload_converter.postmark')])
6365
->alias(PostmarkRequestParser::class, 'mailer.webhook.request_parser.postmark')
6466

67+
->set('mailer.payload_converter.mailtrap', MailtrapPayloadConverter::class)
68+
->set('mailer.webhook.request_parser.mailtrap', MailtrapRequestParser::class)
69+
->args([service('mailer.payload_converter.mailtrap')])
70+
->alias(MailtrapRequestParser::class, 'mailer.webhook.request_parser.mailtrap')
71+
6572
->set('mailer.payload_converter.resend', ResendPayloadConverter::class)
6673
->set('mailer.webhook.request_parser.resend', ResendRequestParser::class)
6774
->args([service('mailer.payload_converter.resend')])
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\Mailer\Bridge\Mailtrap\RemoteEvent;
13+
14+
use Symfony\Component\RemoteEvent\Event\Mailer\AbstractMailerEvent;
15+
use Symfony\Component\RemoteEvent\Event\Mailer\MailerDeliveryEvent;
16+
use Symfony\Component\RemoteEvent\Event\Mailer\MailerEngagementEvent;
17+
use Symfony\Component\RemoteEvent\Exception\ParseException;
18+
use Symfony\Component\RemoteEvent\PayloadConverterInterface;
19+
use Symfony\Component\RemoteEvent\RemoteEvent;
20+
21+
/**
22+
* @author Kevin Bond <kevinbond@gmail.com>
23+
*/
24+
final class MailtrapPayloadConverter implements PayloadConverterInterface
25+
{
26+
public function convert(array $payload): RemoteEvent
27+
{
28+
$type = match ($payload['event']) {
29+
'delivery' => MailerDeliveryEvent::DELIVERED,
30+
'open' => MailerEngagementEvent::OPEN,
31+
'click' => MailerEngagementEvent::CLICK,
32+
'unsubscribe' => MailerEngagementEvent::UNSUBSCRIBE,
33+
'spam' => MailerEngagementEvent::SPAM,
34+
'soft bounce', 'bounce' => MailerDeliveryEvent::BOUNCE,
35+
'suspension', 'reject' => MailerDeliveryEvent::DROPPED,
36+
default => throw new ParseException(\sprintf('Unsupported event "%s".', $payload['event'])),
37+
};
38+
39+
if (\in_array($type, [MailerDeliveryEvent::DELIVERED, MailerDeliveryEvent::BOUNCE, MailerDeliveryEvent::DROPPED], true)) {
40+
$event = new MailerDeliveryEvent($type, $payload['message_id'], $payload);
41+
$event->setReason($payload['reason'] ?? $payload['response'] ?? '');
42+
} else {
43+
$event = new MailerEngagementEvent($type, $payload['message_id'], $payload);
44+
}
45+
46+
if (!$date = \DateTimeImmutable::createFromFormat('U', $payload['timestamp'])) {
47+
throw new ParseException(\sprintf('Invalid date "%s".', $payload['timestamp']));
48+
}
49+
50+
$event->setDate($date);
51+
$event->setRecipientEmail($payload['email']);
52+
53+
if (isset($payload['category'])) {
54+
$event->setTags([$payload['category']]);
55+
}
56+
57+
if (isset($payload['custom_variables'])) {
58+
$event->setMetadata($payload['custom_variables']);
59+
}
60+
61+
return $event;
62+
}
63+
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
{
2+
"events": [
3+
{
4+
"event": "bounce",
5+
"category": "Password reset",
6+
"custom_variables": {
7+
"variable_a": "value",
8+
"variable_b": "value2"
9+
},
10+
"message_id": "00000000-0000-0000-0000-000000000001",
11+
"email": "receiver@example.com",
12+
"timestamp": 1726358034,
13+
"event_id": "bede7236-2284-43d6-a953-1fdcafd0fdbc",
14+
"response": "[CS01] Message rejected due to local policy",
15+
"response_code": 555,
16+
"bounce_category": "spam"
17+
},
18+
{
19+
"event": "click",
20+
"category": "Password reset",
21+
"custom_variables": {
22+
"variable_a": "value",
23+
"variable_b": "value2"
24+
},
25+
"message_id": "00000000-0000-0000-0000-000000000002",
26+
"email": "receiver@example.com",
27+
"timestamp": 1726358034,
28+
"event_id": "bede7236-2284-43d6-a953-1fdcafd0fdbc",
29+
"ip": "142.86.27.2",
30+
"user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Safari/537.36",
31+
"url": "https://mailtrap.io/email-api"
32+
}
33+
]
34+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<?php
2+
3+
use Symfony\Component\RemoteEvent\Event\Mailer\MailerDeliveryEvent;
4+
use Symfony\Component\RemoteEvent\Event\Mailer\MailerEngagementEvent;
5+
6+
$wh1 = new MailerDeliveryEvent(MailerDeliveryEvent::BOUNCE, '00000000-0000-0000-0000-000000000001', json_decode(file_get_contents(str_replace('.php', '.json', __FILE__)), true)['events'][0]);
7+
$wh1->setRecipientEmail('receiver@example.com');
8+
$wh1->setTags(['Password reset']);
9+
$wh1->setMetadata(['variable_a' => 'value', 'variable_b' => 'value2']);
10+
$wh1->setReason('[CS01] Message rejected due to local policy');
11+
$wh1->setDate(\DateTimeImmutable::createFromFormat('U', 1726358034));
12+
13+
$wh2 = new MailerEngagementEvent(MailerEngagementEvent::CLICK, '00000000-0000-0000-0000-000000000002', json_decode(file_get_contents(str_replace('.php', '.json', __FILE__)), true)['events'][1]);
14+
$wh2->setRecipientEmail('receiver@example.com');
15+
$wh2->setTags(['Password reset']);
16+
$wh2->setMetadata(['variable_a' => 'value', 'variable_b' => 'value2']);
17+
$wh2->setDate(\DateTimeImmutable::createFromFormat('U', 1726358034));
18+
19+
return [$wh1, $wh2];
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
{
2+
"events": [
3+
{
4+
"event": "bounce",
5+
"category": "Password reset",
6+
"custom_variables": {
7+
"variable_a": "value",
8+
"variable_b": "value2"
9+
},
10+
"message_id": "00000000-0000-0000-0000-000000000000",
11+
"email": "receiver@example.com",
12+
"timestamp": 1726358034,
13+
"event_id": "bede7236-2284-43d6-a953-1fdcafd0fdbc",
14+
"response": "[CS01] Message rejected due to local policy",
15+
"response_code": 555,
16+
"bounce_category": "spam"
17+
}
18+
]
19+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<?php
2+
3+
use Symfony\Component\RemoteEvent\Event\Mailer\MailerDeliveryEvent;
4+
5+
$wh = new MailerDeliveryEvent(MailerDeliveryEvent::BOUNCE, '00000000-0000-0000-0000-000000000000', json_decode(file_get_contents(str_replace('.php', '.json', __FILE__)), true)['events'][0]);
6+
$wh->setRecipientEmail('receiver@example.com');
7+
$wh->setTags(['Password reset']);
8+
$wh->setMetadata(['variable_a' => 'value', 'variable_b' => 'value2']);
9+
$wh->setReason('[CS01] Message rejected due to local policy');
10+
$wh->setDate(\DateTimeImmutable::createFromFormat('U', 1726358034));
11+
12+
return [$wh];
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
{
2+
"events": [
3+
{
4+
"event": "click",
5+
"category": "Password reset",
6+
"custom_variables": {
7+
"variable_a": "value",
8+
"variable_b": "value2"
9+
},
10+
"message_id": "00000000-0000-0000-0000-000000000000",
11+
"email": "receiver@example.com",
12+
"timestamp": 1726358034,
13+
"event_id": "bede7236-2284-43d6-a953-1fdcafd0fdbc",
14+
"ip": "142.86.27.2",
15+
"user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Safari/537.36",
16+
"url": "https://mailtrap.io/email-api"
17+
}
18+
]
19+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<?php
2+
3+
use Symfony\Component\RemoteEvent\Event\Mailer\MailerEngagementEvent;
4+
5+
$wh = new MailerEngagementEvent(MailerEngagementEvent::CLICK, '00000000-0000-0000-0000-000000000000', json_decode(file_get_contents(str_replace('.php', '.json', __FILE__)), true)['events'][0]);
6+
$wh->setRecipientEmail('receiver@example.com');
7+
$wh->setTags(['Password reset']);
8+
$wh->setMetadata(['variable_a' => 'value', 'variable_b' => 'value2']);
9+
$wh->setDate(\DateTimeImmutable::createFromFormat('U', 1726358034));
10+
11+
return [$wh];
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
{
2+
"events": [
3+
{
4+
"event": "delivery",
5+
"category": "Password reset",
6+
"custom_variables": {
7+
"variable_a": "value",
8+
"variable_b": "value2"
9+
},
10+
"message_id": "00000000-0000-0000-0000-000000000000",
11+
"email": "receiver@example.com",
12+
"timestamp": 1726358034,
13+
"event_id": "bede7236-2284-43d6-a953-1fdcafd0fdbc"
14+
}
15+
]
16+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<?php
2+
3+
use Symfony\Component\RemoteEvent\Event\Mailer\MailerDeliveryEvent;
4+
5+
$wh = new MailerDeliveryEvent(MailerDeliveryEvent::DELIVERED, '00000000-0000-0000-0000-000000000000', json_decode(file_get_contents(str_replace('.php', '.json', __FILE__)), true)['events'][0]);
6+
$wh->setRecipientEmail('receiver@example.com');
7+
$wh->setTags(['Password reset']);
8+
$wh->setMetadata(['variable_a' => 'value', 'variable_b' => 'value2']);
9+
$wh->setReason('');
10+
$wh->setDate(\DateTimeImmutable::createFromFormat('U', 1726358034));
11+
12+
return [$wh];
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
{
2+
"events": [
3+
{
4+
"event": "open",
5+
"category": "Password reset",
6+
"custom_variables": {
7+
"variable_a": "value",
8+
"variable_b": "value2"
9+
},
10+
"message_id": "00000000-0000-0000-0000-000000000000",
11+
"email": "receiver@example.com",
12+
"timestamp": 1726358034,
13+
"event_id": "bede7236-2284-43d6-a953-1fdcafd0fdbc",
14+
"ip": "127.138.158.185",
15+
"user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Safari/537.36"
16+
}
17+
]
18+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<?php
2+
3+
use Symfony\Component\RemoteEvent\Event\Mailer\MailerEngagementEvent;
4+
5+
$wh = new MailerEngagementEvent(MailerEngagementEvent::OPEN, '00000000-0000-0000-0000-000000000000', json_decode(file_get_contents(str_replace('.php', '.json', __FILE__)), true)['events'][0]);
6+
$wh->setRecipientEmail('receiver@example.com');
7+
$wh->setTags(['Password reset']);
8+
$wh->setMetadata(['variable_a' => 'value', 'variable_b' => 'value2']);
9+
$wh->setDate(\DateTimeImmutable::createFromFormat('U', 1726358034));
10+
11+
return [$wh];
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
{
2+
"events": [
3+
{
4+
"event": "reject",
5+
"category": "Password reset",
6+
"custom_variables": {
7+
"variable_a": "value",
8+
"variable_b": "value2"
9+
},
10+
"message_id": "00000000-0000-0000-0000-000000000000",
11+
"email": "receiver@example.com",
12+
"timestamp": 1726358034,
13+
"event_id": "bede7236-2284-43d6-a953-1fdcafd0fdbc",
14+
"reason": "Recipient in suppression list. Reason: unsubscription"
15+
}
16+
]
17+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<?php
2+
3+
use Symfony\Component\RemoteEvent\Event\Mailer\MailerDeliveryEvent;
4+
5+
$wh = new MailerDeliveryEvent(MailerDeliveryEvent::DROPPED, '00000000-0000-0000-0000-000000000000', json_decode(file_get_contents(str_replace('.php', '.json', __FILE__)), true)['events'][0]);
6+
$wh->setRecipientEmail('receiver@example.com');
7+
$wh->setTags(['Password reset']);
8+
$wh->setMetadata(['variable_a' => 'value', 'variable_b' => 'value2']);
9+
$wh->setReason('Recipient in suppression list. Reason: unsubscription');
10+
$wh->setDate(\DateTimeImmutable::createFromFormat('U', 1726358034));
11+
12+
return [$wh];
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
{
2+
"events": [
3+
{
4+
"event": "soft bounce",
5+
"category": "Password reset",
6+
"custom_variables": {
7+
"variable_a": "value",
8+
"variable_b": "value2"
9+
},
10+
"message_id": "00000000-0000-0000-0000-000000000000",
11+
"email": "receiver@example.com",
12+
"timestamp": 1726358034,
13+
"event_id": "bede7236-2284-43d6-a953-1fdcafd0fdbc",
14+
"response": "4.7.1 Temporary error, please retry",
15+
"response_code": 451,
16+
"bounce_category": "greylisting"
17+
}
18+
]
19+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<?php
2+
3+
use Symfony\Component\RemoteEvent\Event\Mailer\MailerDeliveryEvent;
4+
5+
$wh = new MailerDeliveryEvent(MailerDeliveryEvent::BOUNCE, '00000000-0000-0000-0000-000000000000', json_decode(file_get_contents(str_replace('.php', '.json', __FILE__)), true)['events'][0]);
6+
$wh->setRecipientEmail('receiver@example.com');
7+
$wh->setTags(['Password reset']);
8+
$wh->setMetadata(['variable_a' => 'value', 'variable_b' => 'value2']);
9+
$wh->setReason('4.7.1 Temporary error, please retry');
10+
$wh->setDate(\DateTimeImmutable::createFromFormat('U', 1726358034));
11+
12+
return [$wh];
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
{
2+
"events": [
3+
{
4+
"event": "spam",
5+
"category": "Password reset",
6+
"custom_variables": {
7+
"variable_a": "value",
8+
"variable_b": "value2"
9+
},
10+
"message_id": "00000000-0000-0000-0000-000000000000",
11+
"email": "receiver@example.com",
12+
"timestamp": 1726358034,
13+
"event_id": "bede7236-2284-43d6-a953-1fdcafd0fdbc"
14+
}
15+
]
16+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<?php
2+
3+
use Symfony\Component\RemoteEvent\Event\Mailer\MailerEngagementEvent;
4+
5+
$wh = new MailerEngagementEvent(MailerEngagementEvent::SPAM, '00000000-0000-0000-0000-000000000000', json_decode(file_get_contents(str_replace('.php', '.json', __FILE__)), true)['events'][0]);
6+
$wh->setRecipientEmail('receiver@example.com');
7+
$wh->setTags(['Password reset']);
8+
$wh->setMetadata(['variable_a' => 'value', 'variable_b' => 'value2']);
9+
$wh->setDate(\DateTimeImmutable::createFromFormat('U', 1726358034));
10+
11+
return [$wh];
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
{
2+
"events": [
3+
{
4+
"event": "suspension",
5+
"category": "Password reset",
6+
"custom_variables": {
7+
"variable_a": "value",
8+
"variable_b": "value2"
9+
},
10+
"message_id": "00000000-0000-0000-0000-000000000000",
11+
"email": "receiver@example.com",
12+
"timestamp": 1726358034,
13+
"event_id": "bede7236-2284-43d6-a953-1fdcafd0fdbc",
14+
"reason": "Your account has reached its daily sending limit."
15+
}
16+
]
17+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<?php
2+
3+
use Symfony\Component\RemoteEvent\Event\Mailer\MailerDeliveryEvent;
4+
5+
$wh = new MailerDeliveryEvent(MailerDeliveryEvent::DROPPED, '00000000-0000-0000-0000-000000000000', json_decode(file_get_contents(str_replace('.php', '.json', __FILE__)), true)['events'][0]);
6+
$wh->setRecipientEmail('receiver@example.com');
7+
$wh->setTags(['Password reset']);
8+
$wh->setMetadata(['variable_a' => 'value', 'variable_b' => 'value2']);
9+
$wh->setReason('Your account has reached its daily sending limit.');
10+
$wh->setDate(\DateTimeImmutable::createFromFormat('U', 1726358034));
11+
12+
return [$wh];

0 commit comments

Comments
 (0)
0