feat: use geosms

This commit is contained in:
loks0n
2024-01-31 11:49:38 +00:00
parent b07bdf610a
commit 90100e3867
5 changed files with 93 additions and 62 deletions
+1 -1
View File
@@ -441,7 +441,7 @@ return [
'variables' => [
[
'name' => '_APP_SMS_PROVIDER',
'description' => "Provider used for delivering SMS for Phone authentication. Use the following format: 'sms://[USER]:[SECRET]@[PROVIDER]'.\n\nEnsure `[USER]` and `[SECRET]` are URL encoded if they contain any non-alphanumeric characters.\n\nAvailable providers are twilio, text-magic, telesign, msg91, and vonage.",
'description' => "Provider used for delivering SMS for Phone authentication. Use the following format: 'sms://[USER]:[SECRET]@[PROVIDER]'.\n\nEnsure `[USER]` and `[SECRET]` are URL encoded if they contain any non-alphanumeric characters.\n\nAvailable providers are twilio, text-magic, telesign, msg91 and vonage.\n\nWhen using the using multiple providers, GEOSMS is enabled. With GEOSMS, the first adapter is used as the default adapter for calling codes, and subsequent adapters can add the `local` parameter to specify the calling code for which they are used: e.g. `sms://[user]:[pass]@twilio?local=default,sms://[user]:[pass]@msg91?local=91`",
'introduction' => '0.15.0',
'default' => '',
'required' => false,
-22
View File
@@ -47,13 +47,7 @@ use Utopia\Database\Validator\Datetime as DatetimeValidator;
use Utopia\Database\Validator\Structure;
use Utopia\Locale\Locale;
use Utopia\DSN\DSN;
use Utopia\Messaging\Adapters\SMS\Mock;
use Appwrite\GraphQL\Promises\Adapter\Swoole;
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\Registry\Registry;
use Utopia\Storage\Device;
use Utopia\Storage\Device\Backblaze;
@@ -1341,22 +1335,6 @@ App::setResource('passwordsDictionary', function ($register) {
return $register->get('passwordsDictionary');
}, ['register']);
App::setResource('sms', function () {
$dsn = new DSN(App::getEnv('_APP_SMS_PROVIDER'));
$user = $dsn->getUser();
$secret = $dsn->getPassword();
return match ($dsn->getHost()) {
'mock' => new Mock($user, $secret), // used for tests
'twilio' => new Twilio($user, $secret),
'text-magic' => new TextMagic($user, $secret),
'telesign' => new Telesign($user, $secret),
'msg91' => new Msg91($user, $secret),
'vonage' => new Vonage($user, $secret),
default => null
};
});
App::setResource('servers', function () {
$platforms = Config::getParam('platforms');
$server = $platforms[APP_PLATFORM_SERVER];
+1 -1
View File
@@ -56,7 +56,7 @@
"utopia-php/image": "0.5.*",
"utopia-php/locale": "0.4.*",
"utopia-php/logger": "0.3.*",
"utopia-php/messaging": "0.2.*",
"utopia-php/messaging": "0.3.*",
"utopia-php/migration": "0.3.*",
"utopia-php/orchestration": "0.9.*",
"utopia-php/platform": "0.5.*",
Generated
+19 -19
View File
@@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "35dcde03d0eb9a0d27de653b9fa038d4",
"content-hash": "615a0644ab34fb1809aba7d8e4217c85",
"packages": [
{
"name": "adhocore/jwt",
@@ -1353,16 +1353,16 @@
},
{
"name": "utopia-php/framework",
"version": "0.33.1",
"version": "0.33.2",
"source": {
"type": "git",
"url": "https://github.com/utopia-php/http.git",
"reference": "b745607aa1875554a0ad52e28f6db918da1ce11c"
"reference": "b1423ca3e3b61c6c4c2e619d2cb80672809a19f3"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/utopia-php/http/zipball/b745607aa1875554a0ad52e28f6db918da1ce11c",
"reference": "b745607aa1875554a0ad52e28f6db918da1ce11c",
"url": "https://api.github.com/repos/utopia-php/http/zipball/b1423ca3e3b61c6c4c2e619d2cb80672809a19f3",
"reference": "b1423ca3e3b61c6c4c2e619d2cb80672809a19f3",
"shasum": ""
},
"require": {
@@ -1392,9 +1392,9 @@
],
"support": {
"issues": "https://github.com/utopia-php/http/issues",
"source": "https://github.com/utopia-php/http/tree/0.33.1"
"source": "https://github.com/utopia-php/http/tree/0.33.2"
},
"time": "2024-01-17T16:48:32+00:00"
"time": "2024-01-31T10:35:59+00:00"
},
{
"name": "utopia-php/image",
@@ -1554,16 +1554,16 @@
},
{
"name": "utopia-php/messaging",
"version": "0.2.0",
"version": "0.3.0",
"source": {
"type": "git",
"url": "https://github.com/utopia-php/messaging.git",
"reference": "2d0f474a106bb1da285f85e105c29b46085d3a43"
"reference": "d488223876f88f97bb76fd6681fed0df80558f62"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/utopia-php/messaging/zipball/2d0f474a106bb1da285f85e105c29b46085d3a43",
"reference": "2d0f474a106bb1da285f85e105c29b46085d3a43",
"url": "https://api.github.com/repos/utopia-php/messaging/zipball/d488223876f88f97bb76fd6681fed0df80558f62",
"reference": "d488223876f88f97bb76fd6681fed0df80558f62",
"shasum": ""
},
"require": {
@@ -1596,9 +1596,9 @@
],
"support": {
"issues": "https://github.com/utopia-php/messaging/issues",
"source": "https://github.com/utopia-php/messaging/tree/0.2.0"
"source": "https://github.com/utopia-php/messaging/tree/0.3.0"
},
"time": "2023-09-14T20:48:42+00:00"
"time": "2023-11-14T21:02:37+00:00"
},
{
"name": "utopia-php/migration",
@@ -2471,16 +2471,16 @@
},
{
"name": "doctrine/deprecations",
"version": "1.1.2",
"version": "1.1.3",
"source": {
"type": "git",
"url": "https://github.com/doctrine/deprecations.git",
"reference": "4f2d4f2836e7ec4e7a8625e75c6aa916004db931"
"reference": "dfbaa3c2d2e9a9df1118213f3b8b0c597bb99fab"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/doctrine/deprecations/zipball/4f2d4f2836e7ec4e7a8625e75c6aa916004db931",
"reference": "4f2d4f2836e7ec4e7a8625e75c6aa916004db931",
"url": "https://api.github.com/repos/doctrine/deprecations/zipball/dfbaa3c2d2e9a9df1118213f3b8b0c597bb99fab",
"reference": "dfbaa3c2d2e9a9df1118213f3b8b0c597bb99fab",
"shasum": ""
},
"require": {
@@ -2512,9 +2512,9 @@
"homepage": "https://www.doctrine-project.org/",
"support": {
"issues": "https://github.com/doctrine/deprecations/issues",
"source": "https://github.com/doctrine/deprecations/tree/1.1.2"
"source": "https://github.com/doctrine/deprecations/tree/1.1.3"
},
"time": "2023-09-27T20:04:15+00:00"
"time": "2024-01-30T19:34:25+00:00"
},
{
"name": "doctrine/instantiator",
+72 -19
View File
@@ -7,21 +7,20 @@ use Utopia\App;
use Utopia\CLI\Console;
use Utopia\DSN\DSN;
use Utopia\Messaging\Messages\SMS;
use Utopia\Messaging\Adapters\SMS as SMSAdapter;
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\Messaging\Adapters\SMS\GEOSMS;
use Utopia\Platform\Action;
use Utopia\Queue\Message;
class Messaging extends Action
{
private ?DSN $dsn = null;
private string $user = '';
private string $secret = '';
private string $provider = '';
private array $dsns = [];
public static function getName(): string
{
@@ -33,11 +32,14 @@ class Messaging extends Action
*/
public function __construct()
{
$this->provider = App::getEnv('_APP_SMS_PROVIDER', '');
if (!empty($this->provider)) {
$this->dsn = new DSN($this->provider);
$this->user = $this->dsn->getUser();
$this->secret = $this->dsn->getPassword();
$providers = App::getEnv('_APP_SMS_PROVIDER', '');
if (!empty($providers)) {
$providers = explode(',', $providers);
foreach ($providers as $provider) {
$this->dsns[] = new DSN($provider);
}
}
$this
@@ -82,21 +84,16 @@ class Messaging extends Action
return;
}
$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
};
if (empty(App::getEnv('_APP_SMS_PROVIDER'))) {
Console::error('Skipped sms processing. No Phone provider has been set.');
return;
}
$sms = count($this->dsns) > 1
? self::createGEOSMSAdapter($this->dsns)
: self::createAdapterFromDSN($this->dsns[0]);
$from = App::getEnv('_APP_SMS_FROM');
if (empty($from)) {
@@ -116,4 +113,60 @@ class Messaging extends Action
throw new Exception('Error sending message: ' . $error->getMessage(), 500);
}
}
}
protected static function createAdapterFromDSN(DSN $dsn): SMSAdapter
{
$from = empty($dsn->getParam('from', '')) ? null : $dsn->getParam('from', '');
switch ($dsn->getHost()) {
case 'mock':
return new Mock($dsn->getUser(), $dsn->getPassword());
case 'msg91':
$adapter = new Msg91($dsn->getUser(), $dsn->getPassword());
$template = $dsn->getParam('template', App::getEnv('_APP_SMS_FROM', ''));
if (!empty($template)) {
$adapter->setTemplate($template);
}
return $adapter;
case 'telesign':
return new Telesign($dsn->getUser(), $dsn->getPassword());
case 'textmagic':
case 'text-magic':
return new TextMagic($dsn->getUser(), $dsn->getPassword(), $from);
case 'twilio':
return new Twilio($dsn->getUser(), $dsn->getPassword(), $from);
case 'vonage':
return new Vonage($dsn->getUser(), $dsn->getPassword(), $from);
default:
throw new \Exception('Unknown SMS provider: ' . $dsn->getHost());
}
}
protected static function createGEOSMSAdapter(array $dsns): GEOSMS
{
$defaultAdapter = self::createAdapterFromDSN($dsns[0]);
$geosms = new GEOSMS($defaultAdapter);
$localDSNs = array_slice($dsns, 1);
/** @var DSN $localDSN */
foreach ($localDSNs as $localDSN) {
$localAdapter = null;
try {
$localAdapter = self::createAdapterFromDSN($localDSN);
} catch (\Exception) {
Console::warning('Unable to create adapter: ' . $localDSN->getHost());
continue;
}
$callingCode = $localDSN->getParam('local', '');
if (empty($callingCode)) {
Console::warning('Unable to register adapter: ' . $localDSN->getHost() . '. Missing `local` parameter.');
continue;
}
$geosms->setLocal($callingCode, $localAdapter);
}
return $geosms;
}
}