diff --git a/src/Utopia/Messaging/Adapter/SMS/AlibabaCloud.php b/src/Utopia/Messaging/Adapter/SMS/AlibabaCloud.php new file mode 100644 index 00000000..f3a59378 --- /dev/null +++ b/src/Utopia/Messaging/Adapter/SMS/AlibabaCloud.php @@ -0,0 +1,114 @@ +getType()); + + foreach ($message->getTo() as $to) { + $params = [ + 'AccessKeyId' => $this->accessKeyId, + 'Action' => 'SendSms', + 'Format' => 'JSON', + 'PhoneNumbers' => $to, + 'RegionId' => 'cn-hangzhou', + 'SignName' => $this->signName, + 'SignatureMethod' => 'HMAC-SHA1', + 'SignatureNonce' => \uniqid(), + 'SignatureVersion' => '1.0', + 'TemplateCode' => $this->templateCode, + 'TemplateParam' => \json_encode(['code' => $message->getContent()]), + 'Timestamp' => \gmdate('Y-m-d\TH:i:s\Z'), + 'Version' => '2017-05-25', + ]; + + $params['Signature'] = $this->generateSignature($params); + + $result = $this->request( + method: 'GET', + url: 'https://dysmsapi.aliyuncs.com', + headers: [], + body: $params + ); + + if ($result['statusCode'] >= 200 && $result['statusCode'] < 300 && ($result['response']['Code'] ?? '') === 'OK') { + $response->incrementDeliveredTo(); + $response->addResult($to); + } else { + $response->addResult($to, $result['response']['Message'] ?? 'Unknown error'); + } + } + + return $response->toArray(); + } + + /** + * Generate Alibaba Cloud API Signature. + */ + private function generateSignature(array $params): string + { + \ksort($params); + + $canonicalizedQueryString = ''; + foreach ($params as $key => $value) { + $canonicalizedQueryString .= '&' . $this->percentEncode($key) . '=' . $this->percentEncode($value); + } + + $stringToSign = 'GET&' . $this->percentEncode('/') . '&' . $this->percentEncode(\substr($canonicalizedQueryString, 1)); + + $signature = \base64_encode(\hash_hmac('sha1', $stringToSign, $this->accessKeySecret . '&', true)); + + return $signature; + } + + private function percentEncode(string $str): string + { + $res = \urlencode($str); + $res = \str_replace(['+', '*'], ['%20', '%2A'], $res); + $res = \preg_replace('/%7E/i', '~', $res); + + return $res; + } +} diff --git a/tests/Messaging/Adapter/SMS/AlibabaCloudTest.php b/tests/Messaging/Adapter/SMS/AlibabaCloudTest.php new file mode 100644 index 00000000..762d2700 --- /dev/null +++ b/tests/Messaging/Adapter/SMS/AlibabaCloudTest.php @@ -0,0 +1,32 @@ + '123456']), + ); + + $result = $sender->send($message); + + $this->assertResponse($result); + } +}