Skip to content

Commit 41822b8

Browse files
committed
feature symfony#58761 [Mailer] [Amazon] Add support for custom headers in ses+api (StudioMaX)
This PR was merged into the 7.3 branch. Discussion ---------- [Mailer] [Amazon] Add support for custom headers in ses+api | Q | A | ------------- | --- | Branch? | 7.2 | Bug fix? | no | New feature? | yes <!-- please update src/**/CHANGELOG.md files --> | Deprecations? | no <!-- please update UPGRADE-*.md and src/**/CHANGELOG.md files --> | Issues | Fix symfony#45168 <!-- prefix each issue number with "Fix #", no need to create an issue if none exists, explain below instead --> | License | MIT Until recently it was not possible to add custom headers when using AWS SES API with `Simple` mode, see symfony#45168. This problem is also mentioned in Mailer's docs: > If you send custom headers when using the [Amazon SES](https://github.com/symfony/symfony/blob/7.1/src/Symfony/Component/Mailer/Bridge/Amazon/README.md) transport (to receive them later via a webhook), make sure to use the ses+https provider because it's the only one that supports them. However, changes have been made to the SendEmail API and now this will be possible from approximately 2024/03/05. References: https://docs.aws.amazon.com/ses/latest/APIReference-V2/API_SendEmail.html https://awsapichanges.com/archive/changes/539fb6-email.html In this change I add all custom headers to the request, excluding the standard ones, similar to other transports. Example: ```php $mail->getHeaders()->addTextHeader('X-Custom-Header', 'foobar'); ``` Commits ------- 6038343 [Mailer] [Amazon] Add support for custom headers in ses+api
2 parents 41bee39 + 6038343 commit 41822b8

File tree

4 files changed

+35
-1
lines changed

4 files changed

+35
-1
lines changed

src/Symfony/Component/Mailer/Bridge/Amazon/CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
CHANGELOG
22
=========
33

4+
7.2
5+
---
6+
7+
* Add support for custom headers in ses+api
8+
49
7.1
510
---
611

src/Symfony/Component/Mailer/Bridge/Amazon/Tests/Transport/SesApiAsyncAwsTransportTest.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,7 @@ public function testSend()
9292
$this->assertSame('bounces@example.com', $content['FeedbackForwardingEmailAddress']);
9393
$this->assertSame([['Name' => 'tagName1', 'Value' => 'tag Value1'], ['Name' => 'tagName2', 'Value' => 'tag Value2']], $content['EmailTags']);
9494
$this->assertSame(['ContactListName' => 'TestContactList', 'TopicName' => 'TestNewsletter'], $content['ListManagementOptions']);
95+
$this->assertSame([['Name' => 'X-Custom-Header', 'Value' => 'foobar']], $content['Content']['Simple']['Headers']);
9596

9697
$json = '{"MessageId": "foobar"}';
9798

@@ -115,6 +116,7 @@ public function testSend()
115116
$mail->getHeaders()->addTextHeader('X-SES-CONFIGURATION-SET', 'aws-configuration-set-name');
116117
$mail->getHeaders()->addTextHeader('X-SES-SOURCE-ARN', 'aws-source-arn');
117118
$mail->getHeaders()->addTextHeader('X-SES-LIST-MANAGEMENT-OPTIONS', 'contactListName=TestContactList;topicName=TestNewsletter');
119+
$mail->getHeaders()->addTextHeader('X-Custom-Header', 'foobar');
118120
$mail->getHeaders()->add(new MetadataHeader('tagName1', 'tag Value1'));
119121
$mail->getHeaders()->add(new MetadataHeader('tagName2', 'tag Value2'));
120122

src/Symfony/Component/Mailer/Bridge/Amazon/Transport/SesApiAsyncAwsTransport.php

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,10 @@ protected function getRequest(SentMessage $message): SendEmailRequest
107107
$request['FeedbackForwardingEmailAddress'] = $email->getReturnPath()->toString();
108108
}
109109

110+
if ($customHeaders = $this->getCustomHeaders($email->getHeaders())) {
111+
$request['Content']['Simple']['Headers'] = $customHeaders;
112+
}
113+
110114
foreach ($email->getHeaders()->all() as $header) {
111115
if ($header instanceof MetadataHeader) {
112116
$request['EmailTags'][] = ['Name' => $header->getKey(), 'Value' => $header->getValue()];
@@ -123,6 +127,29 @@ private function getRecipients(Email $email, Envelope $envelope): array
123127
return array_filter($envelope->getRecipients(), fn (Address $address) => !\in_array($address, $emailRecipients, true));
124128
}
125129

130+
private function getCustomHeaders(Headers $headers): array
131+
{
132+
$headersPrepared = [];
133+
134+
$headersToBypass = ['from', 'to', 'cc', 'bcc', 'return-path', 'subject', 'reply-to', 'sender', 'content-type', 'x-ses-configuration-set', 'x-ses-source-arn', 'x-ses-list-management-options'];
135+
foreach ($headers->all() as $name => $header) {
136+
if (\in_array($name, $headersToBypass, true)) {
137+
continue;
138+
}
139+
140+
if ($header instanceof MetadataHeader) {
141+
continue;
142+
}
143+
144+
$headersPrepared[] = [
145+
'Name' => $header->getName(),
146+
'Value' => $header->getBodyAsString(),
147+
];
148+
}
149+
150+
return $headersPrepared;
151+
}
152+
126153
protected function stringifyAddresses(array $addresses): array
127154
{
128155
return array_map(fn (Address $a) => $this->stringifyAddress($a), $addresses);

src/Symfony/Component/Mailer/Bridge/Amazon/composer.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
],
1818
"require": {
1919
"php": ">=8.2",
20-
"async-aws/ses": "^1.3",
20+
"async-aws/ses": "^1.8",
2121
"symfony/mailer": "^7.2"
2222
},
2323
"require-dev": {

0 commit comments

Comments
 (0)