From 0b1b7646d5677c7c085ba5d1784c9b6503374501 Mon Sep 17 00:00:00 2001 From: Prateek Banga Date: Fri, 13 Oct 2023 18:26:54 +0530 Subject: [PATCH] review changes --- app/controllers/api/messaging.php | 63 ++++++++++++------- src/Appwrite/Event/Messaging.php | 37 ++++++++++- .../Database/Validator/Queries/Messages.php | 25 ++++++++ .../Database/Validator/Queries/Providers.php | 4 +- 4 files changed, 101 insertions(+), 28 deletions(-) create mode 100644 src/Appwrite/Utopia/Database/Validator/Queries/Messages.php diff --git a/app/controllers/api/messaging.php b/app/controllers/api/messaging.php index 058f3ce1f6..40e6a159bc 100644 --- a/app/controllers/api/messaging.php +++ b/app/controllers/api/messaging.php @@ -5,6 +5,7 @@ use Appwrite\Extend\Exception; use Appwrite\Permission; use Appwrite\Role; use Appwrite\Utopia\Database\Validator\CustomId; +use Appwrite\Utopia\Database\Validator\Queries\Messages; use Appwrite\Utopia\Database\Validator\Queries\Providers; use Appwrite\Utopia\Database\Validator\Queries\Topics; use Appwrite\Utopia\Response; @@ -19,10 +20,8 @@ use Utopia\Database\Validator\Datetime as DatetimeValidator; use Utopia\Database\Validator\UID; use Utopia\Validator\ArrayList; use Utopia\Validator\Boolean; -use Utopia\Validator\JSON; use Utopia\Validator\Text; use Utopia\Validator\WhiteList; -use Utopia\Database\DateTime; App::post('/v1/messaging/providers/mailgun') ->desc('Create Mailgun Provider') @@ -1236,12 +1235,13 @@ App::post('/v1/messaging/topics') try { $topic = $dbForProject->createDocument('topics', $topic); - $response - ->setStatusCode(Response::STATUS_CODE_CREATED) - ->dynamic($topic, Response::MODEL_TOPIC); } catch (DuplicateException) { throw new Exception(Exception::TOPIC_ALREADY_EXISTS); } + + $response + ->setStatusCode(Response::STATUS_CODE_CREATED) + ->dynamic($topic, Response::MODEL_TOPIC); }); App::get('/v1/messaging/topics') @@ -1328,7 +1328,7 @@ App::patch('/v1/messaging/topics/:topicId') ->label('sdk.response.model', Response::MODEL_TOPIC) ->param('topicId', '', new UID(), 'Topic ID.') ->param('name', '', new Text(128), 'Topic Name.', true) - ->param('description', null, new Text(128), 'Topic Description.', true) + ->param('description', null, new Text(2048), 'Topic Description.', true) ->inject('dbForProject') ->inject('response') ->action(function (string $topicId, string $name, string $description, Database $dbForProject, Response $response) { @@ -1387,8 +1387,8 @@ App::post('/v1/messaging/topics/:topicId/subscribers') ->label('scope', 'subscribers.write') ->label('sdk.auth', [APP_AUTH_TYPE_JWT, APP_AUTH_TYPE_SESSION, APP_AUTH_TYPE_ADMIN, APP_AUTH_TYPE_KEY]) ->label('sdk.namespace', 'messaging') - ->label('sdk.method', 'addSubscriber') - ->label('sdk.description', '/docs/references/messaging/add-subscriber.md') + ->label('sdk.method', 'createSubscriber') + ->label('sdk.description', '/docs/references/messaging/create-subscriber.md') ->label('sdk.response.code', Response::STATUS_CODE_CREATED) ->label('sdk.response.type', Response::CONTENT_TYPE_JSON) ->label('sdk.response.model', Response::MODEL_SUBSCRIBER) @@ -1427,19 +1427,20 @@ App::post('/v1/messaging/topics/:topicId/subscribers') try { $subscriber = $dbForProject->createDocument('subscribers', $subscriber); $dbForProject->deleteCachedDocument('topics', $topicId); - $response - ->setStatusCode(Response::STATUS_CODE_CREATED) - ->dynamic($subscriber, Response::MODEL_SUBSCRIBER); } catch (DuplicateException) { throw new Exception(Exception::SUBSCRIBER_ALREADY_EXISTS); } + + $response + ->setStatusCode(Response::STATUS_CODE_CREATED) + ->dynamic($subscriber, Response::MODEL_SUBSCRIBER); }); App::get('/v1/messaging/topics/:topicId/subscribers') ->desc('List topic\'s subscribers.') ->groups(['api', 'messaging']) ->label('scope', 'subscribers.read') - ->label('sdk.auth', [APP_AUTH_TYPE_JWT, APP_AUTH_TYPE_SESSION, APP_AUTH_TYPE_ADMIN, APP_AUTH_TYPE_KEY]) + ->label('sdk.auth', [APP_AUTH_TYPE_ADMIN, APP_AUTH_TYPE_KEY]) ->label('sdk.namespace', 'messaging') ->label('sdk.method', 'listSubscribers') ->label('sdk.description', '/docs/references/messaging/list-subscribers.md') @@ -1471,7 +1472,7 @@ App::get('/v1/messaging/topics/:topicId/subscriber/:subscriberId') ->desc('Get a topic\'s subscriber.') ->groups(['api', 'messaging']) ->label('scope', 'subscribers.read') - ->label('sdk.auth', [APP_AUTH_TYPE_JWT, APP_AUTH_TYPE_SESSION, APP_AUTH_TYPE_ADMIN, APP_AUTH_TYPE_KEY]) + ->label('sdk.auth', [APP_AUTH_TYPE_ADMIN, APP_AUTH_TYPE_KEY]) ->label('sdk.namespace', 'messaging') ->label('sdk.method', 'getSubscriber') ->label('sdk.description', '/docs/references/messaging/get-subscriber.md') @@ -1537,15 +1538,15 @@ App::delete('/v1/messaging/topics/:topicId/subscriber/:subscriberId') }); App::post('/v1/messaging/messages/email') - ->desc('Send an email.') + ->desc('Create an email.') ->groups(['api', 'messaging']) ->label('audits.event', 'messages.create') ->label('audits.resource', 'messages/{response.$id}') ->label('scope', 'messages.write') ->label('sdk.auth', [APP_AUTH_TYPE_ADMIN, APP_AUTH_TYPE_KEY]) ->label('sdk.namespace', 'messaging') - ->label('sdk.method', 'sendEmail') - ->label('sdk.description', '/docs/references/messaging/send-email.md') + ->label('sdk.method', 'createEmail') + ->label('sdk.description', '/docs/references/messaging/create-email.md') ->label('sdk.response.code', Response::STATUS_CODE_CREATED) ->label('sdk.response.type', Response::CONTENT_TYPE_JSON) ->label('sdk.response.model', Response::MODEL_MESSAGE) @@ -1557,11 +1558,12 @@ App::post('/v1/messaging/messages/email') ->param('content', '', new Text(64230), 'Email Content.') ->param('status', 'processing', new WhiteList(['draft', 'processing']), 'Message Status.', true) ->param('html', false, new Boolean(), 'Is content of type HTML', true) + ->param('deliveryTime', null, new DatetimeValidator(), 'Delivery time for message.', true) ->inject('dbForProject') ->inject('project') ->inject('messaging') ->inject('response') - ->action(function (string $messageId, string $providerId, array $to, string $subject, string $description, string $content, string $status, bool $html, Database $dbForProject, Document $project, Messaging $messaging, Response $response) { + ->action(function (string $messageId, string $providerId, array $to, string $subject, string $description, string $content, string $status, bool $html, ?string $deliveryTime, Database $dbForProject, Document $project, Messaging $messaging, Response $response) { $messageId = $messageId == 'unique()' ? ID::unique() : $messageId; $provider = $dbForProject->getDocument('providers', $providerId); @@ -1588,8 +1590,15 @@ App::post('/v1/messaging/messages/email') if ($status === 'processing') { $messaging ->setMessageId($message->getId()) - ->setProject($project) - ->trigger(); + ->setProject($project); + + if (!empty($deliveryTime)) { + $messaging + ->setDeliveryTime($deliveryTime) + ->schedule(); + } else { + $messaging->trigger(); + } } $response @@ -1608,7 +1617,7 @@ App::get('/v1/messaging/messages') ->label('sdk.response.code', Response::STATUS_CODE_OK) ->label('sdk.response.type', Response::CONTENT_TYPE_JSON) ->label('sdk.response.model', Response::MODEL_MESSAGE_LIST) - ->param('queries', [], new Providers(), 'Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https://appwrite.io/docs/queries). Maximum of ' . APP_LIMIT_ARRAY_PARAMS_SIZE . ' queries are allowed, each ' . APP_LIMIT_ARRAY_ELEMENT_SIZE . ' characters long. You may filter on the following attributes: ' . implode(', ', Providers::ALLOWED_ATTRIBUTES), true) + ->param('queries', [], new Messages(), 'Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https://appwrite.io/docs/queries). Maximum of ' . APP_LIMIT_ARRAY_PARAMS_SIZE . ' queries are allowed, each ' . APP_LIMIT_ARRAY_ELEMENT_SIZE . ' characters long. You may filter on the following attributes: ' . implode(', ', Providers::ALLOWED_ATTRIBUTES), true) ->inject('dbForProject') ->inject('response') ->action(function (array $queries, Database $dbForProject, Response $response) { @@ -1682,12 +1691,12 @@ App::patch('/v1/messaging/messages/email/:messageId') ->param('content', '', new Text(64230), 'Email Content.', true) ->param('status', '', new WhiteList(['draft', 'processing']), 'Message Status.', true) ->param('html', false, new Boolean(), 'Is content of type HTML', true) - ->param('deliveryTime', DateTime::now(), new DatetimeValidator(), 'Delivery time for message.', true) + ->param('deliveryTime', null, new DatetimeValidator(), 'Delivery time for message in ISO 8601 format.', true) ->inject('dbForProject') ->inject('project') ->inject('messaging') ->inject('response') - ->action(function (string $messageId, array $to, string $subject, string $description, string $content, string $status, bool $html, string $deliveryTime, Database $dbForProject, Document $project, Messaging $messaging, Response $response) { + ->action(function (string $messageId, array $to, string $subject, string $description, string $content, string $status, bool $html, ?string $deliveryTime, Database $dbForProject, Document $project, Messaging $messaging, Response $response) { $message = $dbForProject->getDocument('messages', $messageId); if ($message->isEmpty()) { @@ -1728,9 +1737,15 @@ App::patch('/v1/messaging/messages/email/:messageId') if ($status === 'processing') { $messaging ->setMessageId($message->getId()) + ->setProject($project); + + if (!empty($deliveryTime)) { + $messaging ->setDeliveryTime($deliveryTime) - ->setProject($project) - ->trigger(); + ->schedule(); + } else { + $messaging->trigger(); + } } $response diff --git a/src/Appwrite/Event/Messaging.php b/src/Appwrite/Event/Messaging.php index 18887ffcd3..45ef843caa 100644 --- a/src/Appwrite/Event/Messaging.php +++ b/src/Appwrite/Event/Messaging.php @@ -2,8 +2,9 @@ namespace Appwrite\Event; +use Resque; use ResqueScheduler; -use Utopia\Database\DateTime; +use Utopia\Database\Document; class Messaging extends Event { @@ -61,16 +62,46 @@ class Messaging extends Event return $this->deliveryTime; } + /** + * Set project for this event. + * + * @param Document $project + * @return self + */ + public function setProject(Document $project): self + { + $this->project = $project; + + return $this; + } + /** * Executes the event and sends it to the messaging worker. + * @return string|bool + * @throws \InvalidArgumentException */ public function trigger(): string | bool { - ResqueScheduler::enqueueAt(!empty($this->deliveryTime) ? $this->deliveryTime : DateTime::now(), $this->queue, $this->class, [ + return Resque::enqueue($this->queue, $this->class, [ + 'project' => $this->project, + 'user' => $this->user, + 'messageId' => $this->messageId, + ]); + } + + /** + * Schedules the messaging event and schedules it in the messaging worker queue. + * + * @return void + * @throws \Resque_Exception + * @throws \ResqueScheduler_InvalidTimestampException + */ + public function schedule(): void + { + ResqueScheduler::enqueueAt(new \DateTime($this->deliveryTime, new \DateTimeZone('UTC')), $this->queue, $this->class, [ 'project' => $this->project, 'user' => $this->user, 'messageId' => $this->messageId, ]); - return true; } } diff --git a/src/Appwrite/Utopia/Database/Validator/Queries/Messages.php b/src/Appwrite/Utopia/Database/Validator/Queries/Messages.php new file mode 100644 index 0000000000..5fa391e7f6 --- /dev/null +++ b/src/Appwrite/Utopia/Database/Validator/Queries/Messages.php @@ -0,0 +1,25 @@ +