Skip to content

Commit de06865

Browse files
authored
Merge pull request #113 from utopia-php/feat-resend-attachments
feat: add attachment support to Resend adapter
2 parents b2358fd + 9fb9241 commit de06865

File tree

2 files changed

+91
-15
lines changed

2 files changed

+91
-15
lines changed

src/Utopia/Messaging/Adapter/Email/Resend.php

Lines changed: 39 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,9 +35,42 @@ public function getMaxMessagesPerRequest(): int
3535
*/
3636
protected function process(EmailMessage $message): array
3737
{
38-
// Resend doesn't support attachments yet
38+
$attachments = [];
3939
if (! \is_null($message->getAttachments()) && ! empty($message->getAttachments())) {
40-
throw new \Exception('Resend does not support attachments at this time');
40+
$size = 0;
41+
foreach ($message->getAttachments() as $attachment) {
42+
if ($attachment->getContent() !== null) {
43+
$size += \strlen($attachment->getContent());
44+
} else {
45+
$fileSize = \filesize($attachment->getPath());
46+
if ($fileSize === false) {
47+
throw new \Exception('Failed to read attachment file: '.$attachment->getPath());
48+
}
49+
$size += $fileSize;
50+
}
51+
}
52+
53+
if ($size > self::MAX_ATTACHMENT_BYTES) {
54+
throw new \Exception('Total attachment size exceeds '.self::MAX_ATTACHMENT_BYTES.' bytes');
55+
}
56+
57+
foreach ($message->getAttachments() as $attachment) {
58+
if ($attachment->getContent() !== null) {
59+
$content = \base64_encode($attachment->getContent());
60+
} else {
61+
$data = \file_get_contents($attachment->getPath());
62+
if ($data === false) {
63+
throw new \Exception('Failed to read attachment file: '.$attachment->getPath());
64+
}
65+
$content = \base64_encode($data);
66+
}
67+
68+
$attachments[] = [
69+
'filename' => $attachment->getName(),
70+
'content' => $content,
71+
'content_type' => $attachment->getType(),
72+
];
73+
}
4174
}
4275

4376
$response = new Response($this->getType());
@@ -78,6 +111,10 @@ protected function process(EmailMessage $message): array
78111
}
79112
}
80113

114+
if (! empty($attachments)) {
115+
$email['attachments'] = $attachments;
116+
}
117+
81118
if (! \is_null($message->getBCC()) && ! empty($message->getBCC())) {
82119
$bccList = [];
83120
foreach ($message->getBCC() as $bcc) {

tests/Messaging/Adapter/Email/ResendTest.php

Lines changed: 52 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -115,29 +115,68 @@ public function testSendMultipleEmails(): void
115115
$this->assertEquals('success', $response['results'][1]['status'], \var_export($response, true));
116116
}
117117

118-
public function testSendEmailWithAttachmentsThrowsException(): void
118+
public function testSendEmailWithFileAttachment(): void
119119
{
120-
$this->expectException(\Exception::class);
121-
$this->expectExceptionMessage('Resend does not support attachments at this time');
122-
123-
$to = $this->testEmail;
124-
$subject = 'Test Subject';
125-
$content = 'Test Content';
126-
$fromEmail = $this->testEmail;
127-
128120
$message = new Email(
129-
to: [$to],
130-
subject: $subject,
131-
content: $content,
121+
to: [$this->testEmail],
122+
subject: 'Test File Attachment',
123+
content: 'Test Content with file attachment',
132124
fromName: 'Test Sender',
133-
fromEmail: $fromEmail,
125+
fromEmail: $this->testEmail,
134126
attachments: [new Attachment(
135127
name: 'image.png',
136128
path: __DIR__.'/../../../assets/image.png',
137129
type: 'image/png'
138130
)],
139131
);
140132

133+
$response = $this->sender->send($message);
134+
135+
$this->assertResponse($response);
136+
}
137+
138+
public function testSendEmailWithStringAttachment(): void
139+
{
140+
$message = new Email(
141+
to: [$this->testEmail],
142+
subject: 'Test String Attachment',
143+
content: 'Test Content with string attachment',
144+
fromName: 'Test Sender',
145+
fromEmail: $this->testEmail,
146+
attachments: [new Attachment(
147+
name: 'test.txt',
148+
path: '',
149+
type: 'text/plain',
150+
content: 'Hello, this is a test attachment.',
151+
)],
152+
);
153+
154+
$response = $this->sender->send($message);
155+
156+
$this->assertResponse($response);
157+
}
158+
159+
public function testSendEmailWithAttachmentExceedingMaxSize(): void
160+
{
161+
$this->expectException(\Exception::class);
162+
$this->expectExceptionMessage('Total attachment size exceeds');
163+
164+
$largeContent = \str_repeat('x', 25 * 1024 * 1024 + 1);
165+
166+
$message = new Email(
167+
to: [$this->testEmail],
168+
subject: 'Test Oversized Attachment',
169+
content: 'Test Content',
170+
fromName: 'Test Sender',
171+
fromEmail: $this->testEmail,
172+
attachments: [new Attachment(
173+
name: 'large.bin',
174+
path: '',
175+
type: 'application/octet-stream',
176+
content: $largeContent,
177+
)],
178+
);
179+
141180
$this->sender->send($message);
142181
}
143182
}

0 commit comments

Comments
 (0)