mirror of
https://github.com/moodle/moodle.git
synced 2025-08-02 07:39:54 +02:00
MDL-81924 smsgateway_aws: Add AWS sms gateway plugin
Originally implemented as MDL-80961.
This commit is contained in:
parent
10c3e4b770
commit
a5f100e6dd
11 changed files with 511 additions and 1 deletions
|
@ -315,4 +315,33 @@ class manager {
|
|||
timecreated: $record->timecreated,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* This function internationalises a number to E.164 standard.
|
||||
* https://46elks.com/kb/e164
|
||||
*
|
||||
* @param string $phonenumber the phone number to format.
|
||||
* @param ?string $countrycode The country code of the phone number.
|
||||
* @return string the formatted phone number.
|
||||
*/
|
||||
public static function format_number(
|
||||
string $phonenumber,
|
||||
?string $countrycode = null,
|
||||
): string {
|
||||
// Remove all whitespace, dashes, and brackets in one step.
|
||||
$phonenumber = preg_replace('/[ ()-]/', '', $phonenumber);
|
||||
|
||||
// Check if the number is already in international format or if it starts with a 0.
|
||||
if (!str_starts_with($phonenumber, '+')) {
|
||||
// Strip leading 0.
|
||||
if (str_starts_with($phonenumber, '0')) {
|
||||
$phonenumber = substr($phonenumber, 1);
|
||||
}
|
||||
|
||||
// Prepend country code if not already in international format.
|
||||
$phonenumber = !empty($countrycode) ? '+' . $countrycode . $phonenumber : $phonenumber;
|
||||
}
|
||||
|
||||
return $phonenumber;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
This file should be removed when a gateway is added to core.
|
71
sms/gateway/aws/classes/gateway.php
Normal file
71
sms/gateway/aws/classes/gateway.php
Normal file
|
@ -0,0 +1,71 @@
|
|||
<?php
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Moodle is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
namespace smsgateway_aws;
|
||||
|
||||
use core_sms\manager;
|
||||
use core_sms\message;
|
||||
use MoodleQuickForm;
|
||||
|
||||
/**
|
||||
* AWS SMS gateway.
|
||||
*
|
||||
* @package smsgateway_aws
|
||||
* @copyright 2024 Safat Shahin <safat.shahin@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class gateway extends \core_sms\gateway {
|
||||
|
||||
#[\Override]
|
||||
public function send(
|
||||
message $message,
|
||||
): message {
|
||||
global $DB;
|
||||
// Get the config from the message record.
|
||||
$awsconfig = $DB->get_field(
|
||||
table: 'sms_gateways',
|
||||
return: 'config',
|
||||
conditions: ['id' => $message->gatewayid, 'enabled' => 1, 'gateway' => 'smsgateway_aws\gateway',],
|
||||
);
|
||||
$status = \core_sms\message_status::GATEWAY_NOT_AVAILABLE;
|
||||
if ($awsconfig) {
|
||||
$config = (object)json_decode($awsconfig, true, 512, JSON_THROW_ON_ERROR);
|
||||
$class = '\smsgateway_aws\local\service\\' . $config->gateway;
|
||||
$recipientnumber = manager::format_number(
|
||||
phonenumber: $message->recipientnumber,
|
||||
countrycode: isset($config->countrycode) ?? null,
|
||||
);
|
||||
|
||||
if (class_exists($class)) {
|
||||
$status = call_user_func(
|
||||
$class . '::send_sms_message',
|
||||
$message->content,
|
||||
$recipientnumber,
|
||||
$config,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return $message->with(
|
||||
status: $status,
|
||||
);
|
||||
}
|
||||
|
||||
#[\Override]
|
||||
public function get_send_priority(message $message): int {
|
||||
return 50;
|
||||
}
|
||||
}
|
28
sms/gateway/aws/classes/helper.php
Normal file
28
sms/gateway/aws/classes/helper.php
Normal file
|
@ -0,0 +1,28 @@
|
|||
<?php
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Moodle is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
namespace smsgateway_aws;
|
||||
|
||||
/**
|
||||
* AWS SMS gateway helpers.
|
||||
*
|
||||
* @package smsgateway_aws
|
||||
* @copyright 2024 Safat Shahin <safat.shahin@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class helper {
|
||||
|
||||
}
|
43
sms/gateway/aws/classes/local/aws_sms_service_provider.php
Normal file
43
sms/gateway/aws/classes/local/aws_sms_service_provider.php
Normal file
|
@ -0,0 +1,43 @@
|
|||
<?php
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Moodle is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
namespace smsgateway_aws\local;
|
||||
|
||||
use core_sms\message_status;
|
||||
use stdClass;
|
||||
|
||||
/**
|
||||
* AWS SMS service provider interface to provide a standard interface for different aws service providers like sns, sqs etc.
|
||||
*
|
||||
* @package smsgateway_aws
|
||||
* @copyright 2024 Safat Shahin <safat.shahin@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
interface aws_sms_service_provider {
|
||||
|
||||
/**
|
||||
* Sends an SMS message using the selected aws service provider.
|
||||
*
|
||||
* @param string $messagecontent the content to send in the SMS message.
|
||||
* @param string $phonenumber the destination for the message.
|
||||
* @return message_status Status of the message.
|
||||
*/
|
||||
public static function send_sms_message(
|
||||
string $messagecontent,
|
||||
string $phonenumber,
|
||||
stdclass $config,
|
||||
): message_status;
|
||||
}
|
90
sms/gateway/aws/classes/local/service/aws_sns.php
Normal file
90
sms/gateway/aws/classes/local/service/aws_sns.php
Normal file
|
@ -0,0 +1,90 @@
|
|||
<?php
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Moodle is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
namespace smsgateway_aws\local\service;
|
||||
|
||||
use core\aws\aws_helper;
|
||||
use core_sms\message_status;
|
||||
use smsgateway_aws\local\aws_sms_service_provider;
|
||||
use stdClass;
|
||||
|
||||
/**
|
||||
* AWS SNS service provider.
|
||||
*
|
||||
* @package smsgateway_aws
|
||||
* @copyright 2024 Safat Shahin <safat.shahin@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class aws_sns implements aws_sms_service_provider {
|
||||
|
||||
/**
|
||||
* Include the required calls.
|
||||
*/
|
||||
private static function require(): void {
|
||||
global $CFG;
|
||||
require_once($CFG->libdir . '/aws-sdk/src/functions.php');
|
||||
}
|
||||
|
||||
#[\Override]
|
||||
public static function send_sms_message(
|
||||
string $messagecontent,
|
||||
string $phonenumber,
|
||||
stdclass $config,
|
||||
): message_status {
|
||||
global $SITE;
|
||||
self::require();
|
||||
|
||||
// Setup client params and instantiate client.
|
||||
$params = [
|
||||
'version' => 'latest',
|
||||
'region' => $config->api_region,
|
||||
'http' => ['proxy' => aws_helper::get_proxy_string()],
|
||||
];
|
||||
if (!property_exists($config, 'usecredchain') || !$config->usecredchain) {
|
||||
$params['credentials'] = [
|
||||
'key' => $config->api_key,
|
||||
'secret' => $config->api_secret,
|
||||
];
|
||||
}
|
||||
$client = new \Aws\Sns\SnsClient($params);
|
||||
|
||||
// Set up the sender information.
|
||||
$senderid = $SITE->shortname;
|
||||
// Remove spaces and non-alphanumeric characters from ID.
|
||||
$senderid = preg_replace("/[^A-Za-z0-9]/", '', trim($senderid));
|
||||
// We have to truncate the senderID to 11 chars.
|
||||
$senderid = substr($senderid, 0, 11);
|
||||
|
||||
try {
|
||||
// These messages need to be transactional.
|
||||
$client->SetSMSAttributes([
|
||||
'attributes' => [
|
||||
'DefaultSMSType' => 'Transactional',
|
||||
'DefaultSenderID' => $senderid,
|
||||
],
|
||||
]);
|
||||
|
||||
// Actually send the message.
|
||||
$client->publish([
|
||||
'Message' => $messagecontent,
|
||||
'PhoneNumber' => $phonenumber,
|
||||
]);
|
||||
return \core_sms\message_status::GATEWAY_SENT;
|
||||
} catch (\Aws\Exception\AwsException $e) {
|
||||
return \core_sms\message_status::GATEWAY_NOT_AVAILABLE;
|
||||
}
|
||||
}
|
||||
}
|
35
sms/gateway/aws/classes/privacy/provider.php
Normal file
35
sms/gateway/aws/classes/privacy/provider.php
Normal file
|
@ -0,0 +1,35 @@
|
|||
<?php
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Moodle is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
namespace smsgateway_aws\privacy;
|
||||
|
||||
use core_privacy\local\metadata\null_provider;
|
||||
|
||||
/**
|
||||
* Privacy Subsystem for smsgateway_aws implementing null_provider.
|
||||
*
|
||||
* @package smsgateway_aws
|
||||
* @copyright 2024 Safat Shahin <safat.shahin@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
class provider implements null_provider {
|
||||
|
||||
#[\Override]
|
||||
public static function get_reason(): string {
|
||||
return 'privacy:metadata';
|
||||
}
|
||||
}
|
42
sms/gateway/aws/lang/en/smsgateway_aws.php
Normal file
42
sms/gateway/aws/lang/en/smsgateway_aws.php
Normal file
|
@ -0,0 +1,42 @@
|
|||
<?php
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Moodle is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
/**
|
||||
* Strings for component smsgateway_aws, language 'en'.
|
||||
*
|
||||
* @package smsgateway_aws
|
||||
* @copyright 2024 Safat Shahin <safat.shahin@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
$string['api_key'] = 'Key';
|
||||
$string['api_key_help'] = 'Amazon API key credential.';
|
||||
$string['api_region'] = 'Region';
|
||||
$string['api_region_help'] = 'Amazon API gateway region.';
|
||||
$string['api_secret'] = 'Secret';
|
||||
$string['api_secret_help'] = 'Amazon API secret credential.';
|
||||
$string['aws_sns'] = 'AWS SNS';
|
||||
$string['countrycode'] = 'Country number code';
|
||||
$string['countrycode_help'] = 'The calling code without the leading + as a default if users do not enter an international number with a + prefix.
|
||||
|
||||
See this link for a list of calling codes: {$a}';
|
||||
$string['gateway'] = 'SMS Gateway';
|
||||
$string['gateway_help'] = 'The SMS provider you wish to send messages via';
|
||||
$string['pluginname'] = 'AWS';
|
||||
$string['privacy:metadata'] = 'The AWS SMS gateway plugin does not store any personal data.';
|
||||
$string['usecredchain'] = 'Find AWS credentials using the default credential provider chain';
|
||||
|
||||
|
64
sms/gateway/aws/tests/gateway_test.php
Normal file
64
sms/gateway/aws/tests/gateway_test.php
Normal file
|
@ -0,0 +1,64 @@
|
|||
<?php
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Moodle is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
namespace smsgateway_aws;
|
||||
|
||||
use core_sms\message;
|
||||
|
||||
/**
|
||||
* AWS SMS gateway tests.
|
||||
*
|
||||
* @package smsgateway_aws
|
||||
* @category test
|
||||
* @copyright 2024 Safat Shahin <safat.shahin@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
* @covers \smsgateway_aws\gateway
|
||||
*/
|
||||
class gateway_test extends \advanced_testcase {
|
||||
|
||||
public function test_update_message_status(): void {
|
||||
$this->resetAfterTest();
|
||||
|
||||
$manager = \core\di::get(\core_sms\manager::class);
|
||||
$gw = $manager->create_gateway_instance(gateway::class, true);
|
||||
$othergw = $manager->create_gateway_instance(gateway::class, true);
|
||||
|
||||
$message = new message(
|
||||
recipientnumber: '1234567890',
|
||||
content: 'Hello, world!',
|
||||
component: 'smsgateway_aws',
|
||||
messagetype: 'test',
|
||||
recipientuserid: null,
|
||||
sensitive: false,
|
||||
gatewayid: $gw->id,
|
||||
);
|
||||
$message2 = new message(
|
||||
recipientnumber: '1234567890',
|
||||
content: 'Hello, world!',
|
||||
component: 'smsgateway_aws',
|
||||
messagetype: 'test',
|
||||
recipientuserid: null,
|
||||
sensitive: false,
|
||||
gatewayid: $gw->id,
|
||||
);
|
||||
|
||||
$updatedmessages = $gw->update_message_statuses([$message, $message2]);
|
||||
$this->assertEquals([$message, $message2], $updatedmessages);
|
||||
|
||||
$this->expectException(\coding_exception::class);
|
||||
$othergw->update_message_status($message);
|
||||
}
|
||||
}
|
79
sms/gateway/aws/tests/helper_test.php
Normal file
79
sms/gateway/aws/tests/helper_test.php
Normal file
|
@ -0,0 +1,79 @@
|
|||
<?php
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Moodle is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
namespace smsgateway_aws;
|
||||
|
||||
/**
|
||||
* AWS SMS gateway helper tests.
|
||||
*
|
||||
* @package smsgateway_aws
|
||||
* @category test
|
||||
* @copyright 2024 Safat Shahin <safat.shahin@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
* @covers \smsgateway_aws\helper
|
||||
*/
|
||||
class helper_test extends \advanced_testcase {
|
||||
|
||||
/**
|
||||
* Data provider for test_format_number().
|
||||
*
|
||||
* @return array of different country codes and phone numbers.
|
||||
*/
|
||||
public function format_number_provider(): array {
|
||||
|
||||
return [
|
||||
'Phone number with local format' => [
|
||||
'phonenumber' => '0123456789',
|
||||
'expected' => '+34123456789',
|
||||
'countrycode' => '34',
|
||||
],
|
||||
'Phone number with international format' => [
|
||||
'phonenumber' => '+39123456789',
|
||||
'expected' => '+39123456789',
|
||||
],
|
||||
'Phone number with spaces using international format' => [
|
||||
'phonenumber' => '+34 123 456 789',
|
||||
'expected' => '+34123456789',
|
||||
],
|
||||
'Phone number with spaces using local format with country code' => [
|
||||
'phonenumber' => '0 123 456 789',
|
||||
'expected' => '+34123456789',
|
||||
'countrycode' => '34',
|
||||
],
|
||||
'Phone number with spaces using local format without country code' => [
|
||||
'phonenumber' => '0 123 456 789',
|
||||
'expected' => '123456789',
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Test format number with different phones and different country codes.
|
||||
*
|
||||
* @dataProvider format_number_provider
|
||||
* @param string $phonenumber Phone number.
|
||||
* @param string $expected Expected value.
|
||||
* @param string|null $countrycode Country code.
|
||||
*/
|
||||
public function test_format_number(
|
||||
string $phonenumber,
|
||||
string $expected,
|
||||
?string $countrycode = null,
|
||||
): void {
|
||||
$this->resetAfterTest();
|
||||
$this->assertEquals($expected, \core_sms\manager::format_number($phonenumber, $countrycode));
|
||||
}
|
||||
}
|
30
sms/gateway/aws/version.php
Normal file
30
sms/gateway/aws/version.php
Normal file
|
@ -0,0 +1,30 @@
|
|||
<?php
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Moodle is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
/**
|
||||
* Version information for smsgateway_aws.
|
||||
*
|
||||
* @package smsgateway_aws
|
||||
* @copyright 2024 Safat Shahin <safat.shahin@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
$plugin->component = 'smsgateway_aws';
|
||||
$plugin->version = 2024042200;
|
||||
$plugin->requires = 2024041600;
|
||||
$plugin->maturity = MATURITY_STABLE;
|
Loading…
Add table
Add a link
Reference in a new issue