You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
91 lines
3.3 KiB
PHP
91 lines
3.3 KiB
PHP
<?php
|
|
|
|
namespace App\Services;
|
|
|
|
use Illuminate\Support\Facades\Http;
|
|
use Illuminate\Support\Str;
|
|
|
|
class TencentSmsApiService
|
|
{
|
|
protected string $secretId;
|
|
protected string $secretKey;
|
|
protected string $sdkAppId;
|
|
protected string $signName;
|
|
protected string $templateId;
|
|
protected string $endpoint = 'sms.tencentcloudapi.com';
|
|
protected string $service = 'sms';
|
|
protected string $host = 'sms.tencentcloudapi.com';
|
|
protected string $region = 'ap-guangzhou'; // 根据你的需求调整
|
|
protected string $version = '2021-01-11';
|
|
|
|
public function __construct()
|
|
{
|
|
$this->secretId ="AKIDvxuqiU3OYbR3RcZJrBIDuOegU5YxEQWa";
|
|
$this->secretKey = "xnUyGK9lAnHYcS3SecOyLi2GOOOH4h7K";
|
|
$this->sdkAppId = "1401058974";
|
|
$this->signName ="秦皇岛安尔然";
|
|
$this->templateId = "2564483";
|
|
}
|
|
|
|
public function send(string $phoneNumber,string $templateId, array $params = [])
|
|
{
|
|
$action = 'SendSms';
|
|
$timestamp = time();
|
|
$date = gmdate('Y-m-d', $timestamp);
|
|
|
|
// 构造请求体
|
|
$body = [
|
|
'PhoneNumberSet' => [$phoneNumber],
|
|
'SmsSdkAppId' => $this->sdkAppId,
|
|
'SignName' => $this->signName,
|
|
'TemplateId' => $templateId,
|
|
];
|
|
|
|
if (!empty($params)) {
|
|
$body['TemplateParamSet'] = $params;
|
|
}
|
|
|
|
$payload = json_encode($body, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
|
|
|
|
// Canonical Request
|
|
$canonicalUri = '/';
|
|
$canonicalQueryString = '';
|
|
$canonicalHeaders = "content-type:application/json; charset=utf-8\nhost:{$this->host}\n";
|
|
$signedHeaders = 'content-type;host';
|
|
$hashedPayload = hash('sha256', $payload);
|
|
$canonicalRequest = "POST\n{$canonicalUri}\n{$canonicalQueryString}\n{$canonicalHeaders}\n{$signedHeaders}\n{$hashedPayload}";
|
|
|
|
// String to Sign
|
|
$algorithm = 'TC3-HMAC-SHA256';
|
|
$date = gmdate('Y-m-d', $timestamp);
|
|
$credentialScope = "{$date}/{$this->service}/tc3_request";
|
|
$hashedCanonicalRequest = hash('sha256', $canonicalRequest);
|
|
$stringToSign = "{$algorithm}\n{$timestamp}\n{$credentialScope}\n{$hashedCanonicalRequest}";
|
|
|
|
// Signature
|
|
$kSecret = 'TC3' . $this->secretKey;
|
|
$kDate = hash_hmac('sha256', $date, $kSecret, true);
|
|
$kService = hash_hmac('sha256', $this->service, $kDate, true);
|
|
$kSigning = hash_hmac('sha256', 'tc3_request', $kService, true);
|
|
$signature = hash_hmac('sha256', $stringToSign, $kSigning, true);
|
|
$signature = bin2hex($signature); // 转为小写 hex 字符串!
|
|
|
|
// Authorization
|
|
$authorization = "{$algorithm} Credential={$this->secretId}/{$credentialScope}, SignedHeaders={$signedHeaders}, Signature={$signature}";
|
|
|
|
// 发送请求:必须用 $payload 字符串,不能传数组!
|
|
$response = Http::withHeaders([
|
|
'Authorization' => $authorization,
|
|
'Content-Type' => 'application/json; charset=utf-8',
|
|
'Host' => $this->host,
|
|
'X-TC-Action' => $action,
|
|
'X-TC-Timestamp' => $timestamp,
|
|
'X-TC-Version' => $this->version,
|
|
'X-TC-Region' => $this->region,
|
|
])->withBody($payload, 'application/json; charset=utf-8')
|
|
->post("https://{$this->endpoint}");
|
|
|
|
return $response->json();
|
|
}
|
|
}
|