Files
hdk-core/src/Service/SmsService.php
李东云 8616c5f61c perf: 适配已弃用的命名空间
Signed-off-by: 李东云 <dongyu.li@luxcreo.ai>
2023-06-19 18:22:42 +08:00

121 lines
3.9 KiB
PHP

<?php
namespace Singularity\HDK\Core\Service;
use AlibabaCloud\SDK\Dysmsapi\V20170525\Dysmsapi;
use AlibabaCloud\SDK\Dysmsapi\V20170525\Models\SendSmsRequest;
use AlibabaCloud\Tea\Exception\TeaError;
use Darabonba\OpenApi\Models\Config;
use Hyperf\Codec\Json;
use Hyperf\HttpMessage\Exception\ServerErrorHttpException;
use Singularity\HDK\Core\Constants\CommonErrorCode;
use Singularity\HDK\Core\Exceptions\ValidateException;
use UnexpectedValueException;
use function Hyperf\Config\config;
/**
* 短信服务
*/
class SmsService
{
/**
* @var Dysmsapi
*/
private Dysmsapi $client;
public function __construct()
{
$this->client = $this->createClient();
}
/**
* 初始化实例
*
* @return Dysmsapi
*/
private function createClient(): Dysmsapi
{
$config = new Config();
// 访问的域名
$config->endpoint = "dysmsapi.aliyuncs.com";
$config->accessKeyId = config('common.third_party.sms.aliyun.access_key_id');
$config->accessKeySecret = config('common.third_party.sms.aliyun.access_key_secret');
return new Dysmsapi($config);
}
/**
* 国内短信
*
* @param string $phone 接收短信的手机号码
* @param string|null $templateCode 短信模板CODE
* @param array<string, string>|null $templateParam 短信模板变量对应的实际值(不支持空数组)
* @param string|null $signName 短信签名名称
*
* @return bool
* @throws UnexpectedValueException 参数校验
* @throws ValidateException 频率太高
* @throws ServerErrorHttpException 阿里云短信服务报错
* @link https://help.aliyun.com/document_detail/419273.htm
*
*/
public function sendSmsCountryside(
string $phone,
?string $templateCode = null,
?array $templateParam = null,
?string $signName = null,
): bool {
if (is_array($templateParam) && count($templateParam) <= 0) {
throw new UnexpectedValueException('不支持空数组,请用 null 代替或不传', CommonErrorCode::FORMATTER_ERROR);
}
$phone_number = strtr($phone, ['#' => '']);
$sendSmsRequest = new SendSmsRequest(
[
"signName" => $signName ?? config('common.third_party.sms.aliyun.sign_name'),
"phoneNumbers" => $phone_number,
"templateCode" => $templateCode ?? config('common.third_party.sms.aliyun.template_code'),
"templateParam" => Json::encode($templateParam),
]
);
try {
$response = $this->client->sendSms($sendSmsRequest);
$response_code = $response->body->code;
$message = $response->body->message;
if ($response_code !== 'OK') {
throw new TeaError($response->toMap(), $message);
}
} catch (TeaError $error) {
$data = $error->getErrorInfo();
$data = $data['data'] ?? $data['body'];
$code = $data['Code'];
$message = $data['Message'];
// 频率太高
if ($code === 'isv.BUSINESS_LIMIT_CONTROL') {
$error_code = match (mb_substr($message, 2, 2)) {
'天级' => CommonErrorCode::REQUEST_PARAMS_ERROR_CODE_MAX_TIMES_DAY,
'小时' => CommonErrorCode::REQUEST_PARAMS_ERROR_CODE_MAX_TIMES_HOUR,
'分钟' => CommonErrorCode::REQUEST_PARAMS_ERROR_CODE_MAX_TIMES_MINUTE,
default => null
};
if (isset($error_code)) {
throw new ValidateException($error_code);
}
}
throw new ServerErrorHttpException(
message: $message,
code: CommonErrorCode::SERVER_DEPENDENCY_SMS_ERROR,
previous: $error
);
}
return true;
}
}