对接华为云的消息&短信 MSGSMS
写在前面
记录对接华为云的消息&短信 (Message & SMS), 以便下次开发快速使用!
代码
我们通常使用短信服务接入web,来实现一些业务验证码,消息通知等功能。
华为云的 消息&短信 MSGSMS
和阿里云的 短信服务
几乎没啥区别。
如果有对接过短信服务那么都不需要了解,直接复制粘贴使用即可!
简单的说就是配置模板,调用接口发送短信。需要注意的是模板参数的定义/格式,通常踩坑的都是参数格式问题。ENV
配置:
# SMS配置
HW_SMS_APP_URL=https://smsapi.cn-north-4.myhuaweicloud.com:443/sms/batchSendSms/v1
HW_SMS_APP_KEY=
HW_SMS_APP_SECRET=
HW_SMS_APP_SENDER=
HW_SMS_APP_CALLBACK=
接口定义:
<?php
namespace App\Service\SMS;
interface ISMS
{
/**
* 发送短信
*
* @param array $mobiles
* @param string $templateId
* @param array $params
* @return mixed
*/
public function sendSMS(array $mobiles, string $templateId, array $params);
}
实现类:
<?php
namespace App\Service\SMS;
use GuzzleHttp\Client;
use GuzzleHttp\Exception\GuzzleException;
use Illuminate\Support\Facades\Log;
class HuaweiSMS implements ISMS
{
/**
*
* 已创建短信应用:
* APP接入地址:https://smsapi.cn-north-4.myhuaweicloud.com:443/sms/batchSendSms/v1
* @var string
*/
public $appUrl;
/**
* 短信应用:APP_Key
*
* @var string
*/
public $appKey;
/**
* 短信应用:APP_Secret
*
* @var string
*/
public $appSecret;
/**
* 签名通道号
* @var string
*/
public $sender;
/**
* 短信状态报告接收地址,为空或者不填表示不接收状态报告
*/
public $statusCallback;
public function __construct()
{
$this->appUrl = env('HW_SMS_APP_URL');
$this->appKey = env('HW_SMS_APP_KEY');
$this->appSecret = env('HW_SMS_APP_SECRET');
$this->sender = env('HW_SMS_APP_SENDER');
$this->statusCallback = env('HW_SMS_APP_CALLBACK');
}
/**
* 发送短信消息
* templateParas:选填,使用无变量模板时请赋空值 $templateParas = '';
* 格式:'["369751"]', 每个变量都必须赋值,且取值不能为空;验证码杜绝首位0,会丢失0
* 更多模板规范和变量规范:
* 产品介绍>短信模板须知和短信变量须知:https://support.huaweicloud.com/productdesc-msgsms/sms_templates.html
*
* @param array $mobiles | 发送给谁
* @param string $templateId | 短信模板id
* @param array $params | 短信模板参数,与模板id绑定
* @return array
*/
public function sendSMS(array $mobiles, string $templateId, array $params)
{
$receiver = $this->getReceiver($mobiles);
$templateParas = $params ? json_encode($params, JSON_UNESCAPED_UNICODE) : '';
$client = new Client();
try {
$data = [
'form_params' => [
'from' => $this->sender,
'to' => $receiver,
'templateId' => $templateId,
'templateParas' => $templateParas,
'statusCallback' => $this->statusCallback,
],
'headers' => [
'Authorization' => 'WSSE realm="SDP",profile="UsernameToken",type="Appkey"',
'X-WSSE' => $this->buildWsseHeader()
],
'verify' => false
];
$response = $client->request('POST', $this->appUrl, $data);
$content = $response->getBody()->getContents();
Log::info(__METHOD__, json_decode($content, true));
return ['ok' => true, 'data' => json_decode($content, true)];
} catch (GuzzleException $e) {
Log::error($e);
return ['ok' => false, 'msg' => '发送消息失败!' . $e->getMessage()];
}
}
/**
* 格式为:+{国家码}{地区码}{终端号码},国内短信:接收号码为国内手机号码时,所填号码可以不带+86,系统默认添加86
* @param $mobiles
* @return string
*/
public function getReceiver($mobiles): string
{
$prefix = '+86';
foreach ($mobiles as $key => $mobile) {
$mobiles[$key] = $prefix . $mobile;
}
return implode(',', $mobiles);
}
/**
* 构造X-WSSE参数值
*
* @return string
*/
public function buildWsseHeader(): string
{
$now = date('Y-m-d\TH:i:s\Z');
$nonce = uniqid(); //Nonce
$base64 = base64_encode(hash('sha256', ($nonce . $now . $this->appSecret))); //PasswordDigest
return sprintf("UsernameToken Username=\"%s\",PasswordDigest=\"%s\",Nonce=\"%s\",Created=\"%s\"",
$this->appKey, $base64, $nonce, $now);
}
}
附录
参考文档:
模板/变量须知:support.huaweicloud.com/productdes...
发送短信API说明:support.huaweicloud.com/api-msgsms...
本作品采用《CC 协议》,转载必须注明作者和本文链接