Messaging

This commit is contained in:
shimon
2023-05-29 19:32:33 +03:00
parent 5a22d17459
commit 06ca9ce815
4 changed files with 170 additions and 80 deletions
+66 -72
View File
@@ -1,33 +1,45 @@
<?php
namespace Appwrite\Platform\Workers;
use Exception;
use Appwrite\Template\Template;
use PHPMailer\PHPMailer\PHPMailer;
use Utopia\App;
use Utopia\CLI\Console;
use Utopia\Database\Document;
use Utopia\Database\Validator\Authorization;
use Utopia\Locale\Locale;
use Utopia\Platform\Action;
use Utopia\Queue\Message;
use Utopia\Queue\Server;
use Utopia\Registry\Registry;
class Mails extends Action
{
public static function getName(): string
{
return 'audits';
}
require_once __DIR__ . '/../worker.php';
public function __construct()
{
$this
->desc('Audits worker')
->inject('message')
->inject('dbForProject')
->inject('register')
->callback(fn($message, $dbForProject, $register) => $this->action($message, $dbForProject, $register));
}
Authorization::disable();
Authorization::setDefaultStatus(false);
public function action(Message $message, $dbForProject, $register): void
{
/**
* Returns true if all the required terms in a locale exist. False otherwise
*
* @param $locale
* @param $prefix
*
* @return bool
*/
Server::setResource('doesLocaleExist', function () {
return function (Locale $locale, string $prefix) {
if (!$locale->getText('emails.sender') || !$locale->getText("$prefix.hello") || !$locale->getText("$prefix.subject") || !$locale->getText("$prefix.body") || !$locale->getText("$prefix.footer") || !$locale->getText("$prefix.thanks") || !$locale->getText("$prefix.signature")) {
return false;
}
return true;
};
});
$server->job()
->inject('message')
->inject('doesLocaleExist')
->inject('register')
->action(function (Message $message, callable $doesLocaleExist, Registry $register) {
$payload = $message->getPayload() ?? [];
if (empty($payload)) {
@@ -60,37 +72,37 @@ class Mails extends Action
$locale = new Locale($payload['locale']);
$projectName = $project->isEmpty() ? 'Console' : $project->getAttribute('name', '[APP-NAME]');
if (!$doesLocaleExist($locale, $prefix)) {
$locale->setDefault('en');
}
if (!$doesLocaleExist($locale, $prefix)) {
$locale->setDefault('en');
}
$from = $project->isEmpty() || $project->getId() === 'console' ? '' : \sprintf($locale->getText('emails.sender'), $projectName);
$body = Template::fromFile(__DIR__ . '/../config/locale/templates/email-base.tpl');
$subject = '';
switch ($type) {
case MAIL_TYPE_CERTIFICATE:
$domain = $payload['domain'];
$error = $payload['error'];
$attempt = $payload['attempt'];
switch ($type) {
case MAIL_TYPE_CERTIFICATE:
$domain = $payload['domain'];
$error = $payload['error'];
$attempt = $payload['attempt'];
$subject = \sprintf($locale->getText("$prefix.subject"), $domain);
$body->setParam('{{domain}}', $domain);
$body->setParam('{{error}}', $error);
$body->setParam('{{attempt}}', $attempt);
break;
case MAIL_TYPE_INVITATION:
$subject = \sprintf($locale->getText("$prefix.subject"), $team->getAttribute('name'), $projectName);
$body->setParam('{{owner}}', $user->getAttribute('name'));
$body->setParam('{{team}}', $team->getAttribute('name'));
break;
case MAIL_TYPE_RECOVERY:
case MAIL_TYPE_VERIFICATION:
case MAIL_TYPE_MAGIC_SESSION:
$subject = $locale->getText("$prefix.subject");
break;
default:
throw new Exception('Undefined Mail Type : ' . $type, 500);
}
$subject = \sprintf($locale->getText("$prefix.subject"), $domain);
$body->setParam('{{domain}}', $domain);
$body->setParam('{{error}}', $error);
$body->setParam('{{attempt}}', $attempt);
break;
case MAIL_TYPE_INVITATION:
$subject = \sprintf($locale->getText("$prefix.subject"), $team->getAttribute('name'), $projectName);
$body->setParam('{{owner}}', $user->getAttribute('name'));
$body->setParam('{{team}}', $team->getAttribute('name'));
break;
case MAIL_TYPE_RECOVERY:
case MAIL_TYPE_VERIFICATION:
case MAIL_TYPE_MAGIC_SESSION:
$subject = $locale->getText("$prefix.subject");
break;
default:
throw new Exception('Undefined Mail Type : ' . $type, 500);
}
$body
->setParam('{{subject}}', $subject)
@@ -135,30 +147,12 @@ class Mails extends Action
$mail->Body = $body;
$mail->AltBody = \strip_tags($body);
try {
$mail->send();
} catch (\Exception $error) {
throw new Exception('Error sending mail: ' . $error->getMessage(), 500);
}
try {
$mail->send();
} catch (\Exception $error) {
throw new Exception('Error sending mail: ' . $error->getMessage(), 500);
}
});
/**
* Returns true if all the required terms in a locale exist. False otherwise
*
* @param Locale $locale
* @param string $prefix
* @return bool
*/
private function doesLocaleExist(Locale $locale, string $prefix)
{
if (!$locale->getText('emails.sender') || !$locale->getText("$prefix.hello") || !$locale->getText("$prefix.subject") || !$locale->getText("$prefix.body") || !$locale->getText("$prefix.footer") || !$locale->getText("$prefix.thanks") || !$locale->getText("$prefix.signature")) {
return false;
}
return true;
}
}
$server->workerStart();
$server->start();
+1 -8
View File
@@ -1,10 +1,3 @@
#!/bin/sh
if [ -z "$_APP_REDIS_USER" ] && [ -z "$_APP_REDIS_PASS" ]
then
REDIS_BACKEND="${_APP_REDIS_HOST}:${_APP_REDIS_PORT}"
else
REDIS_BACKEND="redis://${_APP_REDIS_USER}:${_APP_REDIS_PASS}@${_APP_REDIS_HOST}:${_APP_REDIS_PORT}"
fi
INTERVAL=1 QUEUE='v1-messaging' APP_INCLUDE='/usr/src/code/app/workers/messaging.php' php /usr/src/code/vendor/bin/resque -dopcache.preload=opcache.preload=/usr/src/code/app/preload.php
QUEUE=v1-messaging php /usr/src/code/app/worker.php messaging $@
@@ -6,6 +6,7 @@ use Utopia\Platform\Service;
use Appwrite\Platform\Workers\Audits;
use Appwrite\Platform\Workers\Webhooks;
use Appwrite\Platform\Workers\Mails;
use Appwrite\Platform\Workers\Messaging;
class Workers extends Service
{
@@ -16,6 +17,7 @@ class Workers extends Service
->addAction(Audits::getName(), new Audits())
->addAction(Webhooks::getName(), new Webhooks())
->addAction(Mails::getName(), new Mails())
->addAction(Messaging::getName(), new Messaging())
;
}
}
+101
View File
@@ -0,0 +1,101 @@
<?php
namespace Appwrite\Platform\Workers;
use Exception;
use Utopia\App;
use Utopia\CLI\Console;
use Utopia\DSN\DSN;
use Utopia\Messaging\Messages\Sms;
use Utopia\Messaging\Adapters\SMS\Mock;
use Utopia\Messaging\Adapters\SMS\Msg91;
use Utopia\Messaging\Adapters\SMS\Telesign;
use Utopia\Messaging\Adapters\SMS\TextMagic;
use Utopia\Messaging\Adapters\SMS\Twilio;
use Utopia\Messaging\Adapters\SMS\Vonage;
use Utopia\Platform\Action;
use Utopia\Queue\Message;
class Messaging extends Action
{
private ?DSN $dsn;
private string $user;
private string $secret;
private string $provider;
public static function getName(): string
{
return 'messaging';
}
public function __construct()
{
$this->provider = App::getEnv('_APP_SMS_PROVIDER', '');
$this->dsn = !empty($this->provider) ? new DSN($this->provider) : null;
$this->user = !empty($this->provider) ? $this->dsn->getUser() : '';
$this->secret = !empty($this->provider) ? $this->dsn->getPassword() : '';
$this
->desc('Messaging worker')
->inject('message')
->callback(fn($message) => $this->action($message));
}
public function action(Message $message): void
{
$payload = $message->getPayload() ?? [];
if (empty($payload)) {
throw new Exception('Missing payload');
}
if (empty($payload['recipient'])) {
throw new Exception('Missing recipient');
}
if (empty($payload['message'])) {
throw new Exception('Missing message');
}
$this->execute($payload['recipient'], $payload['message']);
}
private function execute(string $recipient, string $message)
{
$sms = match ($this->dsn->getHost()) {
'mock' => new Mock($this->user, $this->secret), // used for tests
'twilio' => new Twilio($this->user, $this->secret),
'text-magic' => new TextMagic($this->user, $this->secret),
'telesign' => new Telesign($this->user, $this->secret),
'msg91' => new Msg91($this->user, $this->secret),
'vonage' => new Vonage($this->user, $this->secret),
default => null
};
$from = App::getEnv('_APP_SMS_FROM');
if (empty(App::getEnv('_APP_SMS_PROVIDER'))) {
Console::info('Skipped sms processing. No Phone provider has been set.');
return;
}
if (empty($from)) {
Console::info('Skipped sms processing. No phone number has been set.');
return;
}
$message = new SMS(
to: [$recipient],
content: $message,
from: $from,
);
try {
$sms->send($message);
} catch (\Exception $error) {
throw new Exception('Error sending message: ' . $error->getMessage(), 500);
}
}
}