1
0
Fork 0
mirror of synced 2024-06-30 12:10:51 +12:00

Use targets for cc/bcc

This commit is contained in:
Jake Barnby 2023-12-15 03:19:24 +13:00
parent 2eace5a627
commit 7b99fab512
No known key found for this signature in database
GPG key ID: C437A8CC85B96E9C
4 changed files with 87 additions and 86 deletions

View file

@ -2278,8 +2278,8 @@ App::post('/v1/messaging/messages/email')
->param('topics', [], new ArrayList(new Text(Database::LENGTH_KEY)), 'List of Topic IDs.', true) ->param('topics', [], new ArrayList(new Text(Database::LENGTH_KEY)), 'List of Topic IDs.', true)
->param('users', [], new ArrayList(new Text(Database::LENGTH_KEY)), 'List of User IDs.', true) ->param('users', [], new ArrayList(new Text(Database::LENGTH_KEY)), 'List of User IDs.', true)
->param('targets', [], new ArrayList(new Text(Database::LENGTH_KEY)), 'List of Targets IDs.', true) ->param('targets', [], new ArrayList(new Text(Database::LENGTH_KEY)), 'List of Targets IDs.', true)
->param('cc', [], new ArrayList(new Email()), 'Array of email addresses to be added as CC.', true) ->param('cc', [], new ArrayList(new UID()), 'Array of target IDs to be added as CC.', true)
->param('bcc', [], new ArrayList(new Email()), 'Array of email addresses to be added as BCC.', true) ->param('bcc', [], new ArrayList(new UID()), 'Array of target IDs to be added as BCC.', true)
->param('description', '', new Text(256), 'Description for message.', true) ->param('description', '', new Text(256), 'Description for message.', true)
->param('status', 'processing', new WhiteList(['draft', 'canceled', 'processing']), 'Message Status. Value must be either draft or cancelled or processing.', true) ->param('status', 'processing', new WhiteList(['draft', 'canceled', 'processing']), 'Message Status. Value must be either draft or cancelled or processing.', true)
->param('html', false, new Boolean(), 'Is content of type HTML', true) ->param('html', false, new Boolean(), 'Is content of type HTML', true)
@ -2290,22 +2290,30 @@ App::post('/v1/messaging/messages/email')
->inject('queueForMessaging') ->inject('queueForMessaging')
->inject('response') ->inject('response')
->action(function (string $messageId, string $subject, string $content, array $topics, array $users, array $targets, string $description, array $cc, array $bcc, string $status, bool $html, ?string $scheduledAt, Event $queueForEvents, Database $dbForProject, Document $project, Messaging $queueForMessaging, Response $response) { ->action(function (string $messageId, string $subject, string $content, array $topics, array $users, array $targets, string $description, array $cc, array $bcc, string $status, bool $html, ?string $scheduledAt, Event $queueForEvents, Database $dbForProject, Document $project, Messaging $queueForMessaging, Response $response) {
$messageId = $messageId == 'unique()' ? ID::unique() : $messageId; $messageId = $messageId == 'unique()'
? ID::unique()
: $messageId;
if (\count($topics) === 0 && \count($users) === 0 && \count($targets) === 0) { if (\count($topics) === 0 && \count($users) === 0 && \count($targets) === 0) {
throw new Exception(Exception::MESSAGE_MISSING_TARGET); throw new Exception(Exception::MESSAGE_MISSING_TARGET);
} }
foreach ($targets as $target) { $mergedTargets = \array_merge($targets, $cc, $bcc);
$targetDocument = $dbForProject->getDocument('targets', $target);
if ($targetDocument->isEmpty()) { $foundTargets = $dbForProject->find('targets', [
Query::equal('$id', $mergedTargets),
Query::equal('providerType', [MESSAGE_TYPE_EMAIL]),
Query::limit(\count($mergedTargets)),
]);
if (\count($foundTargets) !== \count($mergedTargets)) {
throw new Exception(Exception::MESSAGE_TARGET_NOT_EMAIL);
}
foreach ($foundTargets as $target) {
if ($target->isEmpty()) {
throw new Exception(Exception::USER_TARGET_NOT_FOUND); throw new Exception(Exception::USER_TARGET_NOT_FOUND);
} }
if ($targetDocument->getAttribute('providerType') !== MESSAGE_TYPE_EMAIL) {
throw new Exception(Exception::MESSAGE_TARGET_NOT_EMAIL . ' ' . $targetDocument->getId());
}
} }
$message = $dbForProject->createDocument('messages', new Document([ $message = $dbForProject->createDocument('messages', new Document([
@ -2368,22 +2376,28 @@ App::post('/v1/messaging/messages/sms')
->inject('queueForMessaging') ->inject('queueForMessaging')
->inject('response') ->inject('response')
->action(function (string $messageId, string $content, array $topics, array $users, array $targets, string $description, string $status, ?string $scheduledAt, Event $queueForEvents, Database $dbForProject, Document $project, Messaging $queueForMessaging, Response $response) { ->action(function (string $messageId, string $content, array $topics, array $users, array $targets, string $description, string $status, ?string $scheduledAt, Event $queueForEvents, Database $dbForProject, Document $project, Messaging $queueForMessaging, Response $response) {
$messageId = $messageId == 'unique()' ? ID::unique() : $messageId; $messageId = $messageId == 'unique()'
? ID::unique()
: $messageId;
if (\count($topics) === 0 && \count($users) === 0 && \count($targets) === 0) { if (\count($topics) === 0 && \count($users) === 0 && \count($targets) === 0) {
throw new Exception(Exception::MESSAGE_MISSING_TARGET); throw new Exception(Exception::MESSAGE_MISSING_TARGET);
} }
foreach ($targets as $target) { $foundTargets = $dbForProject->find('targets', [
$targetDocument = $dbForProject->getDocument('targets', $target); Query::equal('$id', $targets),
Query::equal('providerType', [MESSAGE_TYPE_SMS]),
Query::limit(\count($targets)),
]);
if ($targetDocument->isEmpty()) { if (\count($foundTargets) !== \count($targets)) {
throw new Exception(Exception::MESSAGE_TARGET_NOT_SMS);
}
foreach ($foundTargets as $target) {
if ($target->isEmpty()) {
throw new Exception(Exception::USER_TARGET_NOT_FOUND); throw new Exception(Exception::USER_TARGET_NOT_FOUND);
} }
if ($targetDocument->getAttribute('providerType') !== MESSAGE_TYPE_SMS) {
throw new Exception(Exception::MESSAGE_TARGET_NOT_SMS . ' ' . $targetDocument->getId());
}
} }
$message = $dbForProject->createDocument('messages', new Document([ $message = $dbForProject->createDocument('messages', new Document([
@ -2450,22 +2464,28 @@ App::post('/v1/messaging/messages/push')
->inject('queueForMessaging') ->inject('queueForMessaging')
->inject('response') ->inject('response')
->action(function (string $messageId, string $title, string $body, array $topics, array $users, array $targets, string $description, ?array $data, string $action, string $icon, string $sound, string $color, string $tag, string $badge, string $status, ?string $scheduledAt, Event $queueForEvents, Database $dbForProject, Document $project, Messaging $queueForMessaging, Response $response) { ->action(function (string $messageId, string $title, string $body, array $topics, array $users, array $targets, string $description, ?array $data, string $action, string $icon, string $sound, string $color, string $tag, string $badge, string $status, ?string $scheduledAt, Event $queueForEvents, Database $dbForProject, Document $project, Messaging $queueForMessaging, Response $response) {
$messageId = $messageId == 'unique()' ? ID::unique() : $messageId; $messageId = $messageId == 'unique()'
? ID::unique()
: $messageId;
if (\count($topics) === 0 && \count($users) === 0 && \count($targets) === 0) { if (\count($topics) === 0 && \count($users) === 0 && \count($targets) === 0) {
throw new Exception(Exception::MESSAGE_MISSING_TARGET); throw new Exception(Exception::MESSAGE_MISSING_TARGET);
} }
foreach ($targets as $target) { $foundTargets = $dbForProject->find('targets', [
$targetDocument = $dbForProject->getDocument('targets', $target); Query::equal('$id', $targets),
Query::equal('providerType', [MESSAGE_TYPE_PUSH]),
Query::limit(\count($targets)),
]);
if ($targetDocument->isEmpty()) { if (\count($foundTargets) !== \count($targets)) {
throw new Exception(Exception::MESSAGE_TARGET_NOT_PUSH);
}
foreach ($foundTargets as $target) {
if ($target->isEmpty()) {
throw new Exception(Exception::USER_TARGET_NOT_FOUND); throw new Exception(Exception::USER_TARGET_NOT_FOUND);
} }
if ($targetDocument->getAttribute('providerType') !== MESSAGE_TYPE_PUSH) {
throw new Exception(Exception::MESSAGE_TARGET_NOT_PUSH . ' ' . $targetDocument->getId());
}
} }
$pushData = []; $pushData = [];

View file

@ -56,7 +56,7 @@
"utopia-php/image": "0.5.*", "utopia-php/image": "0.5.*",
"utopia-php/locale": "0.4.*", "utopia-php/locale": "0.4.*",
"utopia-php/logger": "0.3.*", "utopia-php/logger": "0.3.*",
"utopia-php/messaging": "0.6.*", "utopia-php/messaging": "0.7.*",
"utopia-php/migration": "0.3.*", "utopia-php/migration": "0.3.*",
"utopia-php/orchestration": "0.9.*", "utopia-php/orchestration": "0.9.*",
"utopia-php/platform": "0.5.*", "utopia-php/platform": "0.5.*",

14
composer.lock generated
View file

@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically" "This file is @generated automatically"
], ],
"content-hash": "7041499af2e7b23795d8ef82c9d7a072", "content-hash": "ec8d49765c3f6ccc5759c5eab267f326",
"packages": [ "packages": [
{ {
"name": "adhocore/jwt", "name": "adhocore/jwt",
@ -2270,16 +2270,16 @@
}, },
{ {
"name": "utopia-php/messaging", "name": "utopia-php/messaging",
"version": "0.6.0", "version": "0.7.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/utopia-php/messaging.git", "url": "https://github.com/utopia-php/messaging.git",
"reference": "a3ebf9d0714e760cfa36f9c5de75c7c0f31c4024" "reference": "b2d4b0334412390e839d250b848ff0f3466f7a55"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/utopia-php/messaging/zipball/a3ebf9d0714e760cfa36f9c5de75c7c0f31c4024", "url": "https://api.github.com/repos/utopia-php/messaging/zipball/b2d4b0334412390e839d250b848ff0f3466f7a55",
"reference": "a3ebf9d0714e760cfa36f9c5de75c7c0f31c4024", "reference": "b2d4b0334412390e839d250b848ff0f3466f7a55",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -2314,9 +2314,9 @@
], ],
"support": { "support": {
"issues": "https://github.com/utopia-php/messaging/issues", "issues": "https://github.com/utopia-php/messaging/issues",
"source": "https://github.com/utopia-php/messaging/tree/0.6.0" "source": "https://github.com/utopia-php/messaging/tree/0.7.0"
}, },
"time": "2023-12-05T11:08:43+00:00" "time": "2023-12-05T13:47:36+00:00"
}, },
{ {
"name": "utopia-php/migration", "name": "utopia-php/migration",

View file

@ -63,7 +63,7 @@ class Messaging extends Action
$payload = $message->getPayload() ?? []; $payload = $message->getPayload() ?? [];
if (empty($payload)) { if (empty($payload)) {
Console::error('Payload arg not found'); Console::error('Payload not found.');
return; return;
} }
@ -85,14 +85,14 @@ class Messaging extends Action
$usersId = $message->getAttribute('users', []); $usersId = $message->getAttribute('users', []);
/** /**
* @var Document[] $recipients * @var Document[] $recipients
*/ */
$recipients = []; $recipients = [];
if (\count($topicsId) > 0) { if (\count($topicsId) > 0) {
$topics = $dbForProject->find('topics', [Query::equal('$id', $topicsId)]); $topics = $dbForProject->find('topics', [Query::equal('$id', $topicsId)]);
foreach ($topics as $topic) { foreach ($topics as $topic) {
$targets = \array_filter($topic->getAttribute('targets'), fn (Document $target) => $target->getAttribute('providerType') === $message->getAttribute('providerType')); $targets = \array_filter($topic->getAttribute('targets'), fn(Document $target) => $target->getAttribute('providerType') === $message->getAttribute('providerType'));
$recipients = \array_merge($recipients, $targets); $recipients = \array_merge($recipients, $targets);
} }
} }
@ -100,7 +100,7 @@ class Messaging extends Action
if (\count($usersId) > 0) { if (\count($usersId) > 0) {
$users = $dbForProject->find('users', [Query::equal('$id', $usersId)]); $users = $dbForProject->find('users', [Query::equal('$id', $usersId)]);
foreach ($users as $user) { foreach ($users as $user) {
$targets = \array_filter($user->getAttribute('targets'), fn (Document $target) => $target->getAttribute('providerType') === $message->getAttribute('providerType')); $targets = \array_filter($user->getAttribute('targets'), fn(Document $target) => $target->getAttribute('providerType') === $message->getAttribute('providerType'));
$recipients = \array_merge($recipients, $targets); $recipients = \array_merge($recipients, $targets);
} }
} }
@ -116,13 +116,13 @@ class Messaging extends Action
]); ]);
/** /**
* @var array<string, array<string>> $identifiersByProviderId * @var array<string, array<string>> $identifiersByProviderId
*/ */
$identifiersByProviderId = []; $identifiersByProviderId = [];
/** /**
* @var Document[] $providers * @var Document[] $providers
*/ */
$providers = []; $providers = [];
foreach ($recipients as $recipient) { foreach ($recipients as $recipient) {
$providerId = $recipient->getAttribute('providerId'); $providerId = $recipient->getAttribute('providerId');
@ -140,12 +140,10 @@ class Messaging extends Action
} }
/** /**
* @var array[] $results * @var array[] $results
*/ */
$results = batch(\array_map(function ($providerId) use ($identifiersByProviderId, $providers, $primaryProvider, $message, $dbForProject) { $results = batch(\array_map(function ($providerId) use ($identifiersByProviderId, $providers, $primaryProvider, $message, $dbForProject) {
return function () use ($providerId, $identifiersByProviderId, $providers, $primaryProvider, $message, $dbForProject) { return function () use ($providerId, $identifiersByProviderId, $providers, $primaryProvider, $message, $dbForProject) {
$provider = new Document();
if ($primaryProvider->getId() === $providerId) { if ($primaryProvider->getId() === $providerId) {
$provider = $primaryProvider; $provider = $primaryProvider;
} else { } else {
@ -156,13 +154,12 @@ class Messaging extends Action
} }
} }
$providers[] = $provider;
$identifiers = $identifiersByProviderId[$providerId]; $identifiers = $identifiersByProviderId[$providerId];
$adapter = match ($provider->getAttribute('type')) { $adapter = match ($provider->getAttribute('type')) {
MESSAGE_TYPE_SMS => $this->sms($provider), MESSAGE_TYPE_SMS => $this->sms($provider),
MESSAGE_TYPE_PUSH => $this->push($provider), MESSAGE_TYPE_PUSH => $this->push($provider),
MESSAGE_TYPE_EMAIL => $this->email($provider), MESSAGE_TYPE_EMAIL => $this->email($provider),
default => throw new Exception(Exception::PROVIDER_INCORRECT_TYPE) default => throw new Exception(Exception::PROVIDER_INCORRECT_TYPE)
}; };
@ -170,7 +167,7 @@ class Messaging extends Action
$batches = \array_chunk($identifiers, $maxBatchSize); $batches = \array_chunk($identifiers, $maxBatchSize);
$batchIndex = 0; $batchIndex = 0;
$results = batch(\array_map(function ($batch) use ($message, $provider, $adapter, $batchIndex, $dbForProject) { return batch(\array_map(function ($batch) use ($message, $provider, $adapter, $batchIndex, $dbForProject) {
return function () use ($batch, $message, $provider, $adapter, $batchIndex, $dbForProject) { return function () use ($batch, $message, $provider, $adapter, $batchIndex, $dbForProject) {
$deliveredTotal = 0; $deliveredTotal = 0;
$deliveryErrors = []; $deliveryErrors = [];
@ -180,7 +177,7 @@ class Messaging extends Action
$data = match ($provider->getAttribute('type')) { $data = match ($provider->getAttribute('type')) {
MESSAGE_TYPE_SMS => $this->buildSMSMessage($messageData, $provider), MESSAGE_TYPE_SMS => $this->buildSMSMessage($messageData, $provider),
MESSAGE_TYPE_PUSH => $this->buildPushMessage($messageData), MESSAGE_TYPE_PUSH => $this->buildPushMessage($messageData),
MESSAGE_TYPE_EMAIL => $this->buildEmailMessage($messageData, $provider), MESSAGE_TYPE_EMAIL => $this->buildEmailMessage($dbForProject, $messageData, $provider),
default => throw new Exception(Exception::PROVIDER_INCORRECT_TYPE) default => throw new Exception(Exception::PROVIDER_INCORRECT_TYPE)
}; };
@ -214,8 +211,6 @@ class Messaging extends Action
} }
}; };
}, $batches)); }, $batches));
return $results;
}; };
}, \array_keys($identifiersByProviderId))); }, \array_keys($identifiersByProviderId)));
@ -364,58 +359,44 @@ class Messaging extends Action
}; };
} }
private function buildEmailMessage(Document $message, Document $provider): Email private function buildEmailMessage(Database $dbForProject, Document $message, Document $provider): Email
{ {
$fromName = $provider['options']['fromName']; $fromName = $provider['options']['fromName'];
$fromEmail = $provider['options']['fromEmail']; $fromEmail = $provider['options']['fromEmail'];
$replyToEmail = null; $replyToEmail = null;
$replyToName = null; $replyToName = null;
$cc = null;
$bcc = null;
if (isset($provider['options']['replyToName']) && isset($provider['options']['replyToEmail'])) { if (isset($provider['options']['replyToName']) && isset($provider['options']['replyToEmail'])) {
$replyToName = $provider['options']['replyToName']; $replyToName = $provider['options']['replyToName'];
$replyToEmail = $provider['options']['replyToEmail']; $replyToEmail = $provider['options']['replyToEmail'];
} }
if (\count($message['data']['cc']) > 0) { $data = $message['data'] ?? [];
foreach ($message['data']['cc'] as $ccEmail) { $ccTargets = $data['cc'] ?? [];
if (is_array($cc)) { $bccTargets = $data['bcc'] ?? [];
$cc[] = [ $cc = [];
'email' => $ccEmail, $bcc = [];
];
} else { if (\count($ccTargets) > 0) {
$cc = [ $ccTargets = $dbForProject->find('targets', [Query::equal('identifier', $ccTargets)]);
[ foreach ($ccTargets as $ccTarget) {
'email' => $ccEmail, $cc[] = ['email' => $ccTarget['identifier']];
]
];
}
} }
} }
if (\count($message['data']['bcc'])) { if (\count($bccTargets) > 0) {
foreach ($message['data']['bcc'] as $bccEmail) { $bccTargets = $dbForProject->find('targets', [Query::equal('identifier', $bccTargets)]);
if (is_array($bcc)) { foreach ($bccTargets as $bccTarget) {
$bcc[] = [ $bcc[] = ['email' => $bccTarget['identifier']];
'email' => $bccEmail,
];
} else {
$bcc = [
[
'email' => $bccEmail,
]
];
}
} }
} }
$to = $message['to']; $to = $message['to'];
$subject = $message['data']['subject']; $subject = $data['subject'];
$content = $message['data']['content']; $content = $data['content'];
$html = $message['data']['html']; $html = $data['html'];
return new Email($to, $subject, $content, $fromName, $fromEmail, $replyToName, $replyToEmail, $cc, $bcc, html: $html); return new Email($to, $subject, $content, $fromName, $fromEmail, $replyToName, $replyToEmail, $cc, $bcc, null, $html);
} }
private function buildSMSMessage(Document $message, Document $provider): SMS private function buildSMSMessage(Document $message, Document $provider): SMS