Skip to content

Commit 161f1d5

Browse files
committed
bug #37527 [Mailer] Fix reply-to functionality in the SendgridApiTransport (jt2k)
This PR was squashed before being merged into the 4.4 branch. Discussion ---------- [Mailer] Fix reply-to functionality in the SendgridApiTransport | Q | A | ------------- | --- | Branch? | 4.4 | Bug fix? | yes | New feature? | no | Deprecations? | no | Tickets | | License | MIT | Doc PR | When sending a message using the `SendgridApiTransport`, the reply-to address was being ignored. In other transports, the reply to can be set using headers, but SendGrid requires that certain fields be added explicitly to the API payload. This is already handled for From, To, Cc, Bcc, and Subject, but was not handled for Reply-To. This change extracts the reply to address from the `Email` object and adds it to the payload. Note that the `Email` object allows for multiple Reply-To addresses, but SendGrid only supports a single one, so I am just using the first element of the array. I also fixed a link in a comment to SendGrid's documentation explaining the reserved headers that are not allowed. Commits ------- 2cf25d1055 [Mailer] Fix reply-to functionality in the SendgridApiTransport
2 parents ea99a09 + 3ca184d commit 161f1d5

File tree

4 files changed

+64
-2
lines changed

4 files changed

+64
-2
lines changed

Sendgrid/Tests/Transport/SendgridApiTransportTest.php

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,4 +166,30 @@ public function testCustomHeader()
166166
$this->assertArrayHasKey('foo', $payload['headers']);
167167
$this->assertEquals('bar', $payload['headers']['foo']);
168168
}
169+
170+
public function testReplyTo()
171+
{
172+
$from = '[email protected]';
173+
174+
$replyTo = '[email protected]';
175+
$email = new Email();
176+
$email->from($from)
177+
->to($to)
178+
->replyTo($replyTo)
179+
->text('content');
180+
$envelope = new Envelope(new Address($from), [new Address($to)]);
181+
182+
$transport = new SendgridApiTransport('ACCESS_KEY');
183+
$method = new \ReflectionMethod(SendgridApiTransport::class, 'getPayload');
184+
$method->setAccessible(true);
185+
$payload = $method->invoke($transport, $email, $envelope);
186+
187+
$this->assertArrayHasKey('from', $payload);
188+
$this->assertArrayHasKey('email', $payload['from']);
189+
$this->assertSame($from, $payload['from']['email']);
190+
191+
$this->assertArrayHasKey('reply_to', $payload);
192+
$this->assertArrayHasKey('email', $payload['reply_to']);
193+
$this->assertSame($replyTo, $payload['reply_to']['email']);
194+
}
169195
}

Sendgrid/Transport/SendgridApiTransport.php

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,11 +93,16 @@ private function getPayload(Email $email, Envelope $envelope): array
9393
if ($emails = array_map($addressStringifier, $email->getBcc())) {
9494
$personalization['bcc'] = $emails;
9595
}
96+
if ($emails = array_map($addressStringifier, $email->getReplyTo())) {
97+
// Email class supports an array of reply-to addresses,
98+
// but SendGrid only supports a single address
99+
$payload['reply_to'] = $emails[0];
100+
}
96101

97102
$payload['personalizations'][] = $personalization;
98103

99104
// these headers can't be overwritten according to Sendgrid docs
100-
// see https://developers.pepipost.com/migration-api/new-subpage/email-send
105+
// see https://sendgrid.api-docs.io/v3.0/mail-send/mail-send-errors#-Headers-Errors
101106
$headersToBypass = ['x-sg-id', 'x-sg-eid', 'received', 'dkim-signature', 'content-transfer-encoding', 'from', 'to', 'cc', 'bcc', 'subject', 'content-type', 'reply-to'];
102107
foreach ($email->getHeaders()->all() as $name => $header) {
103108
if (\in_array($name, $headersToBypass, true)) {

SendgridApiTransport.php

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,11 +93,16 @@ private function getPayload(Email $email, Envelope $envelope): array
9393
if ($emails = array_map($addressStringifier, $email->getBcc())) {
9494
$personalization['bcc'] = $emails;
9595
}
96+
if ($emails = array_map($addressStringifier, $email->getReplyTo())) {
97+
// Email class supports an array of reply-to addresses,
98+
// but SendGrid only supports a single address
99+
$payload['reply_to'] = $emails[0];
100+
}
96101

97102
$payload['personalizations'][] = $personalization;
98103

99104
// these headers can't be overwritten according to Sendgrid docs
100-
// see https://developers.pepipost.com/migration-api/new-subpage/email-send
105+
// see https://sendgrid.api-docs.io/v3.0/mail-send/mail-send-errors#-Headers-Errors
101106
$headersToBypass = ['x-sg-id', 'x-sg-eid', 'received', 'dkim-signature', 'content-transfer-encoding', 'from', 'to', 'cc', 'bcc', 'subject', 'content-type', 'reply-to'];
102107
foreach ($email->getHeaders()->all() as $name => $header) {
103108
if (\in_array($name, $headersToBypass, true)) {

SendgridApiTransportTest.php

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,4 +166,30 @@ public function testCustomHeader()
166166
$this->assertArrayHasKey('foo', $payload['headers']);
167167
$this->assertEquals('bar', $payload['headers']['foo']);
168168
}
169+
170+
public function testReplyTo()
171+
{
172+
$from = '[email protected]';
173+
174+
$replyTo = '[email protected]';
175+
$email = new Email();
176+
$email->from($from)
177+
->to($to)
178+
->replyTo($replyTo)
179+
->text('content');
180+
$envelope = new Envelope(new Address($from), [new Address($to)]);
181+
182+
$transport = new SendgridApiTransport('ACCESS_KEY');
183+
$method = new \ReflectionMethod(SendgridApiTransport::class, 'getPayload');
184+
$method->setAccessible(true);
185+
$payload = $method->invoke($transport, $email, $envelope);
186+
187+
$this->assertArrayHasKey('from', $payload);
188+
$this->assertArrayHasKey('email', $payload['from']);
189+
$this->assertSame($from, $payload['from']['email']);
190+
191+
$this->assertArrayHasKey('reply_to', $payload);
192+
$this->assertArrayHasKey('email', $payload['reply_to']);
193+
$this->assertSame($replyTo, $payload['reply_to']['email']);
194+
}
169195
}

0 commit comments

Comments
 (0)