diff --git a/src/Utopia/Messaging/Adapter/Email/SMTP.php b/src/Utopia/Messaging/Adapter/Email/SMTP.php index fc569a4..b400024 100644 --- a/src/Utopia/Messaging/Adapter/Email/SMTP.php +++ b/src/Utopia/Messaging/Adapter/Email/SMTP.php @@ -27,7 +27,7 @@ public function __construct( private string $password = '', private string $smtpSecure = '', private bool $smtpAutoTLS = false, - private string $xMailer = '' + private string $xMailer = '', ) { if (!\in_array($this->smtpSecure, ['', 'ssl', 'tls'])) { throw new \InvalidArgumentException('Invalid SMTP secure prefix. Must be "", "ssl" or "tls"'); @@ -72,6 +72,14 @@ protected function process(EmailMessage $message): array $mail->AltBody = \strip_tags($mail->AltBody); $mail->AltBody = \trim($mail->AltBody); + if (empty($message->getTo())) { + if (empty($message->getBCC()) && empty($message->getDefaultRecipient())) { + throw new \Exception('Email requires either "to" recipients or both BCC and a default recipient configurations'); + } + + $mail->addAddress($message->getDefaultRecipient()); + } + foreach ($message->getTo() as $to) { $mail->addAddress($to); } @@ -111,7 +119,8 @@ protected function process(EmailMessage $message): array $sent = $mail->send(); if ($sent) { - $response->setDeliveredTo(\count($message->getTo())); + $totalDelivered = \count($message->getTo()) + \count($message->getCC() ?: []) + \count($message->getBCC() ?: []); + $response->setDeliveredTo($totalDelivered); } foreach ($message->getTo() as $to) { @@ -122,6 +131,22 @@ protected function process(EmailMessage $message): array $response->addResult($to, $sent ? '' : $error); } + foreach ($message->getCC() as $cc) { + $error = empty($mail->ErrorInfo) + ? 'Unknown error' + : $mail->ErrorInfo; + + $response->addResult($cc['email'], $sent ? '' : $error); + } + + foreach ($message->getBCC() as $bcc) { + $error = empty($mail->ErrorInfo) + ? 'Unknown error' + : $mail->ErrorInfo; + + $response->addResult($bcc['email'], $sent ? '' : $error); + } + return $response->toArray(); } } diff --git a/src/Utopia/Messaging/Messages/Email.php b/src/Utopia/Messaging/Messages/Email.php index c53b540..9d359b9 100644 --- a/src/Utopia/Messaging/Messages/Email.php +++ b/src/Utopia/Messaging/Messages/Email.php @@ -19,6 +19,7 @@ class Email implements Message * @param string|null $replyToEmail The email address of the reply to. * @param array|null $attachments The attachments of the email. * @param bool $html Whether the message is HTML or not. + * @param string|null $defaultRecipient The default recipient of the email. * * @throws \InvalidArgumentException */ @@ -33,7 +34,8 @@ public function __construct( private ?array $cc = null, private ?array $bcc = null, private ?array $attachments = null, - private bool $html = false + private bool $html = false, + private ?string $defaultRecipient = null ) { if (\is_null($this->replyToName)) { $this->replyToName = $this->fromName; @@ -126,4 +128,9 @@ public function isHtml(): bool { return $this->html; } + + public function getDefaultRecipient(): ?string + { + return $this->defaultRecipient; + } } diff --git a/tests/Messaging/Adapter/Email/SMTPTest.php b/tests/Messaging/Adapter/Email/SMTPTest.php index f9aeeeb..ea0ec0e 100644 --- a/tests/Messaging/Adapter/Email/SMTPTest.php +++ b/tests/Messaging/Adapter/Email/SMTPTest.php @@ -54,7 +54,6 @@ public function testSendEmailWithAttachment(): void $fromName = 'Test Sender'; $fromEmail = 'sender@localhost.test'; - $message = new Email( to: [$to], subject: $subject, @@ -78,4 +77,43 @@ public function testSendEmailWithAttachment(): void $this->assertEquals($subject, $lastEmail['subject']); $this->assertEquals($content, \trim($lastEmail['text'])); } + + public function testSendEmailOnlyBCC(): void + { + $sender = new SMTP( + host: 'maildev', + port: 1025, + ); + + $defaultRecipient = 'tester@localhost.test'; + $subject = 'Test Subject'; + $content = 'Test Content'; + $fromName = 'Test Sender'; + $fromEmail = 'sender@localhost.test'; + $bcc = [ + [ + 'email' => 'tester2@localhost.test', + 'name' => 'Test Recipient 2', + ], + ]; + + $message = new Email( + to: [], + subject: $subject, + content: $content, + fromName: $fromName, + fromEmail: $fromEmail, + bcc: $bcc, + defaultRecipient: $defaultRecipient, + ); + + $response = $sender->send($message); + + $lastEmail = $this->getLastEmail(); + + $this->assertResponse($response); + $this->assertEquals($fromEmail, $lastEmail['from'][0]['address']); + $this->assertEquals($subject, $lastEmail['subject']); + $this->assertEquals($content, \trim($lastEmail['text'])); + } }