作者 SHW\戥岁。。

导入

  1 +{"files":[],"license":"regular","licenseto":"10789","licensekey":"o6mJaMsK4NpyHf9q psldq2tLvR9vsAcBNF\/P7cl4cmp82g9FH9Xpm96xhYw=","domains":[],"licensecodes":[],"validations":[]}
  1 +<?php
  2 +
  3 +namespace addons\qcloudsms;
  4 +
  5 +use addons\qcloudsms\library\SmsSingleSender;
  6 +use addons\qcloudsms\library\SmsVoicePromptSender;
  7 +use addons\qcloudsms\library\SmsVoiceverifyCodeSender;
  8 +use addons\qcloudsms\library\TtsVoiceSender;
  9 +use think\Addons;
  10 +use think\Config;
  11 +
  12 +/**
  13 + * 插件
  14 + */
  15 +class Qcloudsms extends Addons
  16 +{
  17 + private $appid = null;
  18 + private $appkey = null;
  19 + private $config = null;
  20 + private $sender = null;
  21 + private $sendError = '';
  22 +
  23 + public function ConfigInit()
  24 + {
  25 + $this->config = $this->getConfig();
  26 + //如果使用语音短信 更换成语音短信模板
  27 + if ($this->config['isVoice'] == 1) {
  28 + $this->config['template'] = $this->config['voiceTemplate'];
  29 + //语音短信 需要另行设置Aappid 与Appkey
  30 + $this->appid = $this->config['voiceAppid'];
  31 + $this->appkey = $this->config['voiceAppkey'];
  32 + } else {
  33 + $this->appid = $this->config['appid'];
  34 + $this->appkey = $this->config['appkey'];
  35 + }
  36 + }
  37 +
  38 + /**
  39 + * 短信发送行为
  40 + * @param Sms $params
  41 + * @return boolean
  42 + */
  43 + public function smsSend(&$params)
  44 + {
  45 + $this->ConfigInit();
  46 + try {
  47 + if ($this->config['isTemplateSender'] == 1) {
  48 + $templateID = $this->config['template'][$params->event];
  49 + if ($this->config['isVoice'] != 1) {
  50 + //普通短信发送
  51 + $this->sender = new SmsSingleSender($this->appid, $this->appkey);
  52 + $result = $this->sender->sendWithParam("86", $params['mobile'], $templateID, ["{$params->code}"], $this->config['sign'], "", "");
  53 + } else {
  54 + //语音短信发送
  55 + $this->sender = new TtsVoiceSender($this->appid, $this->appkey);
  56 + //参数: 国家码,手机号、模板ID、模板参数、播放次数(可选字段)、用户的session内容,服务器端原样返回(可选字段)
  57 + $result = $this->sender->send("86", $params['mobile'], $templateID, [$params->code]);
  58 + }
  59 + } else {
  60 + //判断是否是语音短信
  61 + if ($this->config['isVoice'] != 1) {
  62 + $this->sender = new SmsSingleSender($this->appid, $this->appkey);
  63 + //参数:短信类型{1营销短信,0普通短信 }、国家码、手机号、短信内容、扩展码(可留空)、服务的原样返回的参数
  64 + $result = $this->sender->send($params['type'], '86', $params['mobile'], $params['msg'], "", "");
  65 + } else {
  66 + $this->sender = new SmsVoiceVerifyCodeSender($this->appid, $this->appkey);
  67 + //参数:国家码、手机号、短信内容、播放次数(默认2次)、服务的原样返回的参数
  68 + $result = $this->sender->send('86', $params['mobile'], $params['msg']);
  69 + }
  70 + }
  71 +
  72 + $rsp = json_decode($result, true);
  73 + if ($rsp['result'] == 0 && $rsp['errmsg'] == 'OK') {
  74 + return true;
  75 + } else {
  76 + //记录错误信息
  77 + $this->setError($rsp);
  78 + return false;
  79 + }
  80 + } catch (\Exception $e) {
  81 + $this->setError($e->getMessage());
  82 + }
  83 + return false;
  84 + }
  85 +
  86 + /**
  87 + * 短信发送通知
  88 + * @param array $params
  89 + * @return boolean
  90 + */
  91 + public function smsNotice(&$params)
  92 + {
  93 + $this->ConfigInit();
  94 + try {
  95 + if ($this->config['isTemplateSender'] == 1) {
  96 + $templateID = $this->config['template'][$params['template']];
  97 +
  98 + if ($this->config['isVoice'] != 1) {
  99 + //普通短信发送
  100 + $this->sender = new SmsSingleSender($this->appid, $this->appkey);
  101 + $result = $this->sender->sendWithParam("86", $params['mobile'], $templateID, ["{$params['msg']}"], $this->config['sign'], "", "");
  102 + } else {
  103 + //语音短信发送
  104 + $this->sender = new TtsVoiceSender($this->appid, $this->appkey);
  105 + //参数: 国家码,手机号、模板ID、模板参数、播放次数(可选字段)、用户的session内容,服务器端原样返回(可选字段)
  106 + $result = $this->sender->send("86", $params['mobile'], $templateID, [$params['msg']]);
  107 + }
  108 + } else {
  109 + //判断是否是语音短信
  110 + if ($this->config['isVoice'] != 1) {
  111 + $this->sender = new SmsSingleSender($this->appid, $this->appkey);
  112 + //参数:短信类型{1营销短信,0普通短信 }、国家码、手机号、短信内容、扩展码(可留空)、服务的原样返回的参数
  113 + $result = $this->sender->send($params['type'], '86', $params['mobile'], $params['msg'], "", "");
  114 + } else {
  115 + $this->sender = new SmsVoicePromptSender($this->appid, $this->appkey);
  116 + //参数:国家码、手机号、语音类型(目前固定为2)、短信内容、播放次数(默认2次)、服务的原样返回的参数
  117 + $result = $this->sender->send('86', $params['mobile'], 2, $params['msg']);
  118 + }
  119 + }
  120 + $rsp = (array)json_decode($result, true);
  121 + if ($rsp['result'] == 0 && $rsp['errmsg'] == 'OK') {
  122 + return true;
  123 + } else {
  124 + //记录错误信息
  125 + $this->setError($rsp);
  126 + return false;
  127 + }
  128 + } catch (\Exception $e) {
  129 + var_dump($e);
  130 + exit();
  131 + }
  132 + }
  133 +
  134 + /**
  135 + * 记录失败信息
  136 + * @param [type] $err [description]
  137 + */
  138 + private function setError($err)
  139 + {
  140 + $this->sendError = $err;
  141 + }
  142 +
  143 + /**
  144 + * 获取失败信息
  145 + * @return [type] [description]
  146 + */
  147 + public function getError()
  148 + {
  149 + return $this->sendError;
  150 + }
  151 +
  152 + /**
  153 + * 检测验证是否正确
  154 + * @param Sms $params
  155 + * @return boolean
  156 + */
  157 + public function smsCheck(&$params)
  158 + {
  159 + return true;
  160 + }
  161 +
  162 + /**
  163 + * 插件安装方法
  164 + * @return bool
  165 + */
  166 + public function install()
  167 + {
  168 + return true;
  169 + }
  170 +
  171 + /**
  172 + * 插件卸载方法
  173 + * @return bool
  174 + */
  175 + public function uninstall()
  176 + {
  177 + return true;
  178 + }
  179 +
  180 + /**
  181 + * 插件启用方法
  182 + * @return bool
  183 + */
  184 + public function enable()
  185 + {
  186 + return true;
  187 + }
  188 +
  189 + /**
  190 + * 插件禁用方法
  191 + * @return bool
  192 + */
  193 + public function disable()
  194 + {
  195 + return true;
  196 + }
  197 +}
  1 +<?php
  2 +
  3 +return array(
  4 + array(
  5 + 'name' => 'appid',
  6 + 'title' => '应用AppID',
  7 + 'type' => 'string',
  8 + 'content' =>
  9 + array(),
  10 + 'value' => '',
  11 + 'rule' => 'required',
  12 + 'msg' => '',
  13 + 'tip' => '',
  14 + 'ok' => '',
  15 + 'extend' => '',
  16 + ),
  17 + array(
  18 + 'name' => 'appkey',
  19 + 'title' => '应用AppKEY',
  20 + 'type' => 'string',
  21 + 'content' =>
  22 + array(),
  23 + 'value' => '',
  24 + 'rule' => 'required',
  25 + 'msg' => '',
  26 + 'tip' => '',
  27 + 'ok' => '',
  28 + 'extend' => '',
  29 + ),
  30 + array(
  31 + 'name' => 'voiceAppid',
  32 + 'title' => '语音短信AppID',
  33 + 'type' => 'string',
  34 + 'content' =>
  35 + array(),
  36 + 'value' => '',
  37 + 'rule' => 'required',
  38 + 'msg' => '使用语音短信必须设置',
  39 + 'tip' => '',
  40 + 'ok' => '',
  41 + 'extend' => '',
  42 + ),
  43 + array(
  44 + 'name' => 'voiceAppkey',
  45 + 'title' => '语音短信AppKEY',
  46 + 'type' => 'string',
  47 + 'content' =>
  48 + array(),
  49 + 'value' => '',
  50 + 'rule' => 'required',
  51 + 'msg' => '使用语音短信必须设置',
  52 + 'tip' => '',
  53 + 'ok' => '',
  54 + 'extend' => '',
  55 + ),
  56 + array(
  57 + 'name' => 'sign',
  58 + 'title' => '签名',
  59 + 'type' => 'string',
  60 + 'content' =>
  61 + array(),
  62 + 'value' => 'your sign',
  63 + 'rule' => 'required',
  64 + 'msg' => '',
  65 + 'tip' => '',
  66 + 'ok' => '',
  67 + 'extend' => '',
  68 + ),
  69 + array(
  70 + 'name' => 'isVoice',
  71 + 'title' => '是否使用语音短信',
  72 + 'type' => 'radio',
  73 + 'content' =>
  74 + array(
  75 + 0 => '否',
  76 + 1 => '是',
  77 + ),
  78 + 'value' => '0',
  79 + 'rule' => 'required',
  80 + 'msg' => '',
  81 + 'tip' => '',
  82 + 'ok' => '',
  83 + 'extend' => '',
  84 + ),
  85 + array(
  86 + 'name' => 'isTemplateSender',
  87 + 'title' => '是否使用短信模板发送',
  88 + 'type' => 'radio',
  89 + 'content' =>
  90 + array(
  91 + 0 => '否',
  92 + 1 => '是',
  93 + ),
  94 + 'value' => '1',
  95 + 'rule' => 'required',
  96 + 'msg' => '',
  97 + 'tip' => '',
  98 + 'ok' => '',
  99 + 'extend' => '',
  100 + ),
  101 + array(
  102 + 'name' => 'template',
  103 + 'title' => '短信模板',
  104 + 'type' => 'array',
  105 + 'content' =>
  106 + array(),
  107 + 'value' =>
  108 + array(
  109 + 'register' => '',
  110 + 'resetpwd' => '',
  111 + 'changepwd' => '',
  112 + 'profile' => '',
  113 + ),
  114 + 'rule' => 'required',
  115 + 'msg' => '',
  116 + 'tip' => '',
  117 + 'ok' => '',
  118 + 'extend' => '',
  119 + ),
  120 + array(
  121 + 'name' => 'voiceTemplate',
  122 + 'title' => '语音短信模板',
  123 + 'type' => 'array',
  124 + 'content' =>
  125 + array(),
  126 + 'value' =>
  127 + array(
  128 + 'register' => '',
  129 + 'resetpwd' => '',
  130 + 'changepwd' => '',
  131 + 'profile' => '',
  132 + ),
  133 + 'rule' => 'required',
  134 + 'msg' => '',
  135 + 'tip' => '',
  136 + 'ok' => '',
  137 + 'extend' => '',
  138 + ),
  139 +);
  1 +<?php
  2 +
  3 +namespace addons\qcloudsms\controller;
  4 +
  5 +use think\addons\Controller;
  6 +
  7 +class Index extends Controller
  8 +{
  9 +
  10 + public function index()
  11 + {
  12 + $this->error("当前插件暂无前台页面");
  13 + }
  14 +
  15 +}
  1 +name = qcloudsms
  2 +title = 腾讯云短信发送插件
  3 +intro = 腾讯云短信发送插件
  4 +author = Seacent
  5 +website = https://www.seacent.com
  6 +version = 1.0.3
  7 +state = 1
  8 +url = /addons/qcloudsms
  9 +license = regular
  10 +licenseto = 10789
  1 +<?php
  2 +
  3 +namespace addons\qcloudsms\library;
  4 +
  5 +use addons\qcloudsms\library\SmsSenderUtil;
  6 +
  7 +
  8 +/**
  9 + * 按语音文件fid发送语音通知类
  10 + *
  11 + */
  12 +class FileVoiceSender
  13 +{
  14 + private $url;
  15 + private $appid;
  16 + private $appkey;
  17 + private $util;
  18 +
  19 + /**
  20 + * 构造函数
  21 + *
  22 + * @param string $appid sdkappid
  23 + * @param string $appkey sdkappid对应的appkey
  24 + */
  25 + public function __construct($appid, $appkey)
  26 + {
  27 + $this->url = "https://cloud.tim.qq.com/v5/tlsvoicesvr/sendfvoice";
  28 + $this->appid = $appid;
  29 + $this->appkey = $appkey;
  30 + $this->util = new SmsSenderUtil();
  31 + }
  32 +
  33 + /**
  34 + *
  35 + * 按语音文件fid发送语音通知
  36 + *
  37 + * @param string $nationCode 国家码,如 86 为中国
  38 + * @param string $phoneNumber 不带国家码的手机号
  39 + * @param string $fid 语音文件fid
  40 + * @param string $playtimes 播放次数,可选,最多3次,默认2次
  41 + * @param string $ext 用户的session内容,服务端原样返回,可选字段,不需要可填空串
  42 + * @return string 应答json字符串,详细内容参见腾讯云协议文档
  43 + */
  44 + public function send($nationCode, $phoneNumber, $fid, $playtimes = 2, $ext = "")
  45 + {
  46 + $random = $this->util->getRandom();
  47 + $curTime = time();
  48 + $wholeUrl = $this->url . "?sdkappid=" . $this->appid . "&random=" . $random;
  49 +
  50 + // 按照协议组织 post 包体
  51 + $data = new \stdClass();
  52 + $tel = new \stdClass();
  53 + $tel->nationcode = "".$nationCode;
  54 + $tel->mobile = "".$phoneNumber;
  55 + $data->tel = $tel;
  56 + $data->fid = $fid;
  57 + $data->playtimes = $playtimes;
  58 +
  59 + // app凭证
  60 + $data->sig = $this->util->calculateSig($this->appkey, $random,
  61 + $curTime, array($phoneNumber));
  62 +
  63 + // unix时间戳,请求发起时间,如果和系统时间相差超过10分钟则会返回失败
  64 + $data->time = $curTime;
  65 + $data->ext = $ext;
  66 +
  67 + return $this->util->sendCurlPost($wholeUrl, $data);
  68 + }
  69 +}
  1 +<?php
  2 +
  3 +namespace addons\qcloudsms\library;
  4 +
  5 +use addons\qcloudsms\library\SmsSenderUtil;
  6 +
  7 +/**
  8 + * 拉取单个手机短信状态类
  9 + *
  10 + */
  11 +class SmsMobileStatusPuller
  12 +{
  13 + private $url;
  14 + private $appid;
  15 + private $appkey;
  16 + private $util;
  17 +
  18 + /**
  19 + * 构造函数
  20 + *
  21 + * @param string $appid sdkappid
  22 + * @param string $appkey sdkappid对应的appkey
  23 + */
  24 + public function __construct($appid, $appkey)
  25 + {
  26 + $this->url = "https://yun.tim.qq.com/v5/tlssmssvr/pullstatus4mobile";
  27 + $this->appid = $appid;
  28 + $this->appkey = $appkey;
  29 + $this->util = new SmsSenderUtil();
  30 + }
  31 +
  32 + /**
  33 + * 拉取回执结果
  34 + *
  35 + * @param int $type 拉取类型,0表示回执结果,1表示回复信息
  36 + * @param string $nationCode 国家码,如 86 为中国
  37 + * @param string $mobile 不带国家码的手机号
  38 + * @param int $beginTime 开始时间(unix timestamp)
  39 + * @param int $endTime 结束时间(unix timestamp)
  40 + * @param int $max 拉取最大条数,最多100
  41 + * @return string 应答json字符串,详细内容参见腾讯云协议文档
  42 + */
  43 + private function pull($type, $nationCode, $mobile, $beginTime, $endTime, $max)
  44 + {
  45 + $random = $this->util->getRandom();
  46 + $curTime = time();
  47 + $wholeUrl = $this->url . "?sdkappid=" . $this->appid . "&random=" . $random;
  48 +
  49 + $data = new \stdClass();
  50 + $data->sig = $this->util->calculateSigForPuller($this->appkey, $random, $curTime);
  51 + $data->time = $curTime;
  52 + $data->type = $type;
  53 + $data->max = $max;
  54 + $data->begin_time = $beginTime;
  55 + $data->end_time = $endTime;
  56 + $data->nationcode = $nationCode;
  57 + $data->mobile = $mobile;
  58 +
  59 + return $this->util->sendCurlPost($wholeUrl, $data);
  60 + }
  61 +
  62 + /**
  63 + * 拉取回执结果
  64 + *
  65 + * @param string $nationCode 国家码,如 86 为中国
  66 + * @param string $mobile 不带国家码的手机号
  67 + * @param int $beginTime 开始时间(unix timestamp)
  68 + * @param int $endTime 结束时间(unix timestamp)
  69 + * @param int $max 拉取最大条数,最多100
  70 + * @return string 应答json字符串,详细内容参见腾讯云协议文档
  71 + */
  72 + public function pullCallback($nationCode, $mobile, $beginTime, $endTime, $max)
  73 + {
  74 + return $this->pull(0, $nationCode, $mobile, $beginTime, $endTime, $max);
  75 + }
  76 +
  77 + /**
  78 + * 拉取回复信息
  79 + *
  80 + * @param string $nationCode 国家码,如 86 为中国
  81 + * @param string $mobile 不带国家码的手机号
  82 + * @param int $beginTime 开始时间(unix timestamp)
  83 + * @param int $endTime 结束时间(unix timestamp)
  84 + * @param int $max 拉取最大条数,最多100
  85 + * @return string 应答json字符串,详细内容参见腾讯云协议文档
  86 + */
  87 + public function pullReply($nationCode, $mobile, $beginTime, $endTime, $max)
  88 + {
  89 + return $this->pull(1, $nationCode, $mobile, $beginTime, $endTime, $max);
  90 + }
  91 +}
  1 +<?php
  2 +
  3 +namespace addons\qcloudsms\library;
  4 +
  5 +use addons\qcloudsms\library\SmsSenderUtil;
  6 +
  7 +/**
  8 + * 群发短信类
  9 + *
  10 + */
  11 +class SmsMultiSender
  12 +{
  13 + private $url;
  14 + private $appid;
  15 + private $appkey;
  16 + private $util;
  17 +
  18 + /**
  19 + * 构造函数
  20 + *
  21 + * @param string $appid sdkappid
  22 + * @param string $appkey sdkappid对应的appkey
  23 + */
  24 + public function __construct($appid, $appkey)
  25 + {
  26 + $this->url = "https://yun.tim.qq.com/v5/tlssmssvr/sendmultisms2";
  27 + $this->appid = $appid;
  28 + $this->appkey = $appkey;
  29 + $this->util = new SmsSenderUtil();
  30 + }
  31 +
  32 + /**
  33 + * 普通群发
  34 + *
  35 + * 普通群发需明确指定内容,如果有多个签名,请在内容中以【】的方式添加到信息内容中,
  36 + * 否则系统将使用默认签名。
  37 + *
  38 + *
  39 + * @param int $type 短信类型,0 为普通短信,1 营销短信
  40 + * @param string $nationCode 国家码,如 86 为中国
  41 + * @param array $phoneNumbers 不带国家码的手机号列表
  42 + * @param string $msg 信息内容,必须与申请的模板格式一致,否则将返回错误
  43 + * @param string $extend 扩展码,可填空串
  44 + * @param string $ext 服务端原样返回的参数,可填空串
  45 + * @return string 应答json字符串,详细内容参见腾讯云协议文档
  46 + */
  47 + public function send($type, $nationCode, $phoneNumbers, $msg, $extend = "", $ext = "")
  48 + {
  49 + $random = $this->util->getRandom();
  50 + $curTime = time();
  51 + $wholeUrl = $this->url . "?sdkappid=" . $this->appid . "&random=" . $random;
  52 +
  53 + $data = new \stdClass();
  54 + $data->tel = $this->util->phoneNumbersToArray($nationCode, $phoneNumbers);
  55 + $data->type = $type;
  56 + $data->msg = $msg;
  57 + $data->sig = $this->util->calculateSig($this->appkey, $random,
  58 + $curTime, $phoneNumbers);
  59 + $data->time = $curTime;
  60 + $data->extend = $extend;
  61 + $data->ext = $ext;
  62 +
  63 + return $this->util->sendCurlPost($wholeUrl, $data);
  64 + }
  65 +
  66 + /**
  67 + * 指定模板群发
  68 + *
  69 + *
  70 + * @param string $nationCode 国家码,如 86 为中国
  71 + * @param array $phoneNumbers 不带国家码的手机号列表
  72 + * @param int $templId 模板id
  73 + * @param array $params 模板参数列表,如模板 {1}...{2}...{3},那么需要带三个参数
  74 + * @param string $sign 签名,如果填空串,系统会使用默认签名
  75 + * @param string $extend 扩展码,可填空串
  76 + * @param string $ext 服务端原样返回的参数,可填空串
  77 + * @return string 应答json字符串,详细内容参见腾讯云协议文档
  78 + */
  79 + public function sendWithParam($nationCode, $phoneNumbers, $templId, $params,
  80 + $sign = "", $extend = "", $ext = "")
  81 + {
  82 + $random = $this->util->getRandom();
  83 + $curTime = time();
  84 + $wholeUrl = $this->url . "?sdkappid=" . $this->appid . "&random=" . $random;
  85 +
  86 + $data = new \stdClass();
  87 + $data->tel = $this->util->phoneNumbersToArray($nationCode, $phoneNumbers);
  88 + $data->sign = $sign;
  89 + $data->tpl_id = $templId;
  90 + $data->params = $params;
  91 + $data->sig = $this->util->calculateSigForTemplAndPhoneNumbers(
  92 + $this->appkey, $random, $curTime, $phoneNumbers);
  93 + $data->time = $curTime;
  94 + $data->extend = $extend;
  95 + $data->ext = $ext;
  96 +
  97 + return $this->util->sendCurlPost($wholeUrl, $data);
  98 + }
  99 +}
  1 +<?php
  2 +
  3 +namespace addons\qcloudsms\library;
  4 +
  5 +/**
  6 + * 发送Util类
  7 + *
  8 + */
  9 +class SmsSenderUtil
  10 +{
  11 + /**
  12 + * 生成随机数
  13 + *
  14 + * @return int 随机数结果
  15 + */
  16 + public function getRandom()
  17 + {
  18 + return rand(100000, 999999);
  19 + }
  20 +
  21 + /**
  22 + * 生成签名
  23 + *
  24 + * @param string $appkey sdkappid对应的appkey
  25 + * @param string $random 随机正整数
  26 + * @param string $curTime 当前时间
  27 + * @param array $phoneNumbers 手机号码
  28 + * @return string 签名结果
  29 + */
  30 + public function calculateSig($appkey, $random, $curTime, $phoneNumbers)
  31 + {
  32 + $phoneNumbersString = $phoneNumbers[0];
  33 + for ($i = 1; $i < count($phoneNumbers); $i++) {
  34 + $phoneNumbersString .= ("," . $phoneNumbers[$i]);
  35 + }
  36 +
  37 + return hash("sha256", "appkey=".$appkey."&random=".$random
  38 + ."&time=".$curTime."&mobile=".$phoneNumbersString);
  39 + }
  40 +
  41 + /**
  42 + * 生成签名
  43 + *
  44 + * @param string $appkey sdkappid对应的appkey
  45 + * @param string $random 随机正整数
  46 + * @param string $curTime 当前时间
  47 + * @param array $phoneNumbers 手机号码
  48 + * @return string 签名结果
  49 + */
  50 + public function calculateSigForTemplAndPhoneNumbers($appkey, $random,
  51 + $curTime, $phoneNumbers)
  52 + {
  53 + $phoneNumbersString = $phoneNumbers[0];
  54 + for ($i = 1; $i < count($phoneNumbers); $i++) {
  55 + $phoneNumbersString .= ("," . $phoneNumbers[$i]);
  56 + }
  57 +
  58 + return hash("sha256", "appkey=".$appkey."&random=".$random
  59 + ."&time=".$curTime."&mobile=".$phoneNumbersString);
  60 + }
  61 +
  62 + public function phoneNumbersToArray($nationCode, $phoneNumbers)
  63 + {
  64 + $i = 0;
  65 + $tel = array();
  66 + do {
  67 + $telElement = new \stdClass();
  68 + $telElement->nationcode = $nationCode;
  69 + $telElement->mobile = $phoneNumbers[$i];
  70 + array_push($tel, $telElement);
  71 + } while (++$i < count($phoneNumbers));
  72 +
  73 + return $tel;
  74 + }
  75 +
  76 + /**
  77 + * 生成签名
  78 + *
  79 + * @param string $appkey sdkappid对应的appkey
  80 + * @param string $random 随机正整数
  81 + * @param string $curTime 当前时间
  82 + * @param array $phoneNumber 手机号码
  83 + * @return string 签名结果
  84 + */
  85 + public function calculateSigForTempl($appkey, $random, $curTime, $phoneNumber)
  86 + {
  87 + $phoneNumbers = array($phoneNumber);
  88 +
  89 + return $this->calculateSigForTemplAndPhoneNumbers($appkey, $random,
  90 + $curTime, $phoneNumbers);
  91 + }
  92 +
  93 + /**
  94 + * 生成签名
  95 + *
  96 + * @param string $appkey sdkappid对应的appkey
  97 + * @param string $random 随机正整数
  98 + * @param string $curTime 当前时间
  99 + * @return string 签名结果
  100 + */
  101 + public function calculateSigForPuller($appkey, $random, $curTime)
  102 + {
  103 + return hash("sha256", "appkey=".$appkey."&random=".$random
  104 + ."&time=".$curTime);
  105 + }
  106 +
  107 + /**
  108 + * 生成上传文件授权
  109 + *
  110 + * @param string $appkey sdkappid对应的appkey
  111 + * @param string $random 随机正整数
  112 + * @param string $curTime 当前时间
  113 + * @param array $fileSha1Sum 文件sha1sum
  114 + * @return string 授权结果
  115 + */
  116 + public function calculateAuth($appkey, $random, $curTime, $fileSha1Sum)
  117 + {
  118 + return hash("sha256", "appkey=".$appkey."&random=".$random
  119 + ."&time=".$curTime."&content-sha1=".$fileSha1Sum);
  120 + }
  121 +
  122 + /**
  123 + * 生成sha1sum
  124 + *
  125 + * @param string $content 内容
  126 + * @return string 内容sha1散列值
  127 + */
  128 + public function sha1sum($content)
  129 + {
  130 + return hash("sha1", $content);
  131 + }
  132 +
  133 + /**
  134 + * 发送请求
  135 + *
  136 + * @param string $url 请求地址
  137 + * @param array $dataObj 请求内容
  138 + * @return string 应答json字符串
  139 + */
  140 + public function sendCurlPost($url, $dataObj)
  141 + {
  142 + $curl = curl_init();
  143 + curl_setopt($curl, CURLOPT_URL, $url);
  144 + curl_setopt($curl, CURLOPT_HEADER, 0);
  145 + curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
  146 + curl_setopt($curl, CURLOPT_POST, 1);
  147 + curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 60);
  148 + curl_setopt($curl, CURLOPT_POSTFIELDS, json_encode($dataObj));
  149 + curl_setopt($curl, CURLOPT_HTTPHEADER, array(
  150 + 'Content-Type: application/json; charset=utf-8',
  151 + 'Content-Length: ' . strlen(json_encode($dataObj)))
  152 + );
  153 + curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 0);
  154 + curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, 0);
  155 +
  156 + $ret = curl_exec($curl);
  157 + if (false == $ret) {
  158 + // curl_exec failed
  159 + $result = "{ \"result\":" . -2 . ",\"errmsg\":\"" . curl_error($curl) . "\"}";
  160 + } else {
  161 + $rsp = curl_getinfo($curl, CURLINFO_HTTP_CODE);
  162 + if (200 != $rsp) {
  163 + $result = "{ \"result\":" . -1 . ",\"errmsg\":\"". $rsp
  164 + . " " . curl_error($curl) ."\"}";
  165 + } else {
  166 + $result = $ret;
  167 + }
  168 + }
  169 +
  170 + curl_close($curl);
  171 +
  172 + return $result;
  173 + }
  174 +
  175 + /**
  176 + * 发送请求
  177 + *
  178 + * @param string $req 请求对象
  179 + * @return string 应答json字符串
  180 + */
  181 + public function fetch($req)
  182 + {
  183 + $curl = curl_init();
  184 +
  185 + curl_setopt($curl, CURLOPT_URL, $req->url);
  186 + curl_setopt($curl, CURLOPT_HTTPHEADER, $req->headers);
  187 + curl_setopt($curl, CURLOPT_POSTFIELDS, $req->body);
  188 + curl_setopt($curl, CURLOPT_HEADER, 0);
  189 + curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
  190 + curl_setopt($curl, CURLOPT_POST, 1);
  191 + curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 60);
  192 + curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 0);
  193 + curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, 0);
  194 +
  195 + $result = curl_exec($curl);
  196 +
  197 + if (false == $result) {
  198 + // curl_exec failed
  199 + $result = "{ \"result\":" . -2 . ",\"errmsg\":\"" . curl_error($curl) . "\"}";
  200 + } else {
  201 + $code = curl_getinfo($curl, CURLINFO_HTTP_CODE);
  202 + if (200 != $code) {
  203 + $result = "{ \"result\":" . -1 . ",\"errmsg\":\"". $rsp
  204 + . " " . curl_error($curl) ."\"}";
  205 + }
  206 + }
  207 + curl_close($curl);
  208 +
  209 + return $result;
  210 + }
  211 +}
  1 +<?php
  2 +
  3 +namespace addons\qcloudsms\library;
  4 +
  5 +use addons\qcloudsms\library\SmsSenderUtil;
  6 +
  7 +/**
  8 + * 单发短信类
  9 + *
  10 + */
  11 +class SmsSingleSender
  12 +{
  13 + private $url;
  14 + private $appid;
  15 + private $appkey;
  16 + private $util;
  17 +
  18 + /**
  19 + * 构造函数
  20 + *
  21 + * @param string $appid sdkappid
  22 + * @param string $appkey sdkappid对应的appkey
  23 + */
  24 + public function __construct($appid, $appkey)
  25 + {
  26 + $this->url = "https://yun.tim.qq.com/v5/tlssmssvr/sendsms";
  27 + $this->appid = $appid;
  28 + $this->appkey = $appkey;
  29 + $this->util = new SmsSenderUtil();
  30 + }
  31 +
  32 + /**
  33 + * 普通单发
  34 + *
  35 + * 普通单发需明确指定内容,如果有多个签名,请在内容中以【】的方式添加到信息内容中,否则系统将使用默认签名。
  36 + *
  37 + * @param int $type 短信类型,0 为普通短信,1 营销短信
  38 + * @param string $nationCode 国家码,如 86 为中国
  39 + * @param string $phoneNumber 不带国家码的手机号
  40 + * @param string $msg 信息内容,必须与申请的模板格式一致,否则将返回错误
  41 + * @param string $extend 扩展码,可填空串
  42 + * @param string $ext 服务端原样返回的参数,可填空串
  43 + * @return string 应答json字符串,详细内容参见腾讯云协议文档
  44 + */
  45 + public function send($type, $nationCode, $phoneNumber, $msg, $extend = "", $ext = "")
  46 + {
  47 + $random = $this->util->getRandom();
  48 + $curTime = time();
  49 + $wholeUrl = $this->url . "?sdkappid=" . $this->appid . "&random=" . $random;
  50 +
  51 + // 按照协议组织 post 包体
  52 + $data = new \stdClass();
  53 + $tel = new \stdClass();
  54 + $tel->nationcode = "".$nationCode;
  55 + $tel->mobile = "".$phoneNumber;
  56 +
  57 + $data->tel = $tel;
  58 + $data->type = (int)$type;
  59 + $data->msg = $msg;
  60 + $data->sig = hash("sha256",
  61 + "appkey=".$this->appkey."&random=".$random."&time="
  62 + .$curTime."&mobile=".$phoneNumber, FALSE);
  63 + $data->time = $curTime;
  64 + $data->extend = $extend;
  65 + $data->ext = $ext;
  66 +
  67 + return $this->util->sendCurlPost($wholeUrl, $data);
  68 + }
  69 +
  70 + /**
  71 + * 指定模板单发
  72 + *
  73 + * @param string $nationCode 国家码,如 86 为中国
  74 + * @param string $phoneNumber 不带国家码的手机号
  75 + * @param int $templId 模板 id
  76 + * @param array $params 模板参数列表,如模板 {1}...{2}...{3},那么需要带三个参数
  77 + * @param string $sign 签名,如果填空串,系统会使用默认签名
  78 + * @param string $extend 扩展码,可填空串
  79 + * @param string $ext 服务端原样返回的参数,可填空串
  80 + * @return string 应答json字符串,详细内容参见腾讯云协议文档
  81 + */
  82 + public function sendWithParam($nationCode, $phoneNumber, $templId = 0, $params,
  83 + $sign = "", $extend = "", $ext = "")
  84 + {
  85 + $random = $this->util->getRandom();
  86 + $curTime = time();
  87 + $wholeUrl = $this->url . "?sdkappid=" . $this->appid . "&random=" . $random;
  88 +
  89 + // 按照协议组织 post 包体
  90 + $data = new \stdClass();
  91 + $tel = new \stdClass();
  92 + $tel->nationcode = "".$nationCode;
  93 + $tel->mobile = "".$phoneNumber;
  94 +
  95 + $data->tel = $tel;
  96 + $data->sig = $this->util->calculateSigForTempl($this->appkey, $random,
  97 + $curTime, $phoneNumber);
  98 + $data->tpl_id = $templId;
  99 + $data->params = $params;
  100 + $data->sign = $sign;
  101 + $data->time = $curTime;
  102 + $data->extend = $extend;
  103 + $data->ext = $ext;
  104 +
  105 + return $this->util->sendCurlPost($wholeUrl, $data);
  106 + }
  107 +}
  1 +<?php
  2 +
  3 +namespace addons\qcloudsms\library;
  4 +
  5 +use addons\qcloudsms\library\SmsSenderUtil;
  6 +
  7 +/**
  8 + * 拉取短信状态类
  9 + *
  10 + */
  11 +class SmsStatusPuller
  12 +{
  13 + private $url;
  14 + private $appid;
  15 + private $appkey;
  16 + private $util;
  17 +
  18 + /**
  19 + * 构造函数
  20 + *
  21 + * @param string $appid sdkappid
  22 + * @param string $appkey sdkappid对应的appkey
  23 + */
  24 + public function __construct($appid, $appkey)
  25 + {
  26 + $this->url = "https://yun.tim.qq.com/v5/tlssmssvr/pullstatus";
  27 + $this->appid = $appid;
  28 + $this->appkey = $appkey;
  29 + $this->util = new SmsSenderUtil();
  30 + }
  31 +
  32 + /**
  33 + * 拉取回执结果
  34 + *
  35 + * @param int $type 拉取类型,0表示回执结果,1表示回复信息
  36 + * @param int $max 最大条数,最多100
  37 + * @return string 应答json字符串,详细内容参见腾讯云协议文档
  38 + */
  39 + private function pull($type, $max)
  40 + {
  41 + $random = $this->util->getRandom();
  42 + $curTime = time();
  43 + $wholeUrl = $this->url . "?sdkappid=" . $this->appid . "&random=" . $random;
  44 +
  45 + $data = new \stdClass();
  46 + $data->sig = $this->util->calculateSigForPuller($this->appkey, $random, $curTime);
  47 + $data->time = $curTime;
  48 + $data->type = $type;
  49 + $data->max = $max;
  50 +
  51 + return $this->util->sendCurlPost($wholeUrl, $data);
  52 + }
  53 +
  54 + /**
  55 + * 拉取回执结果
  56 + *
  57 + * @param int $max 拉取最大条数,最多100
  58 + * @return string 应答json字符串,详细内容参见腾讯云协议文档
  59 + */
  60 + public function pullCallback($max)
  61 + {
  62 + return $this->pull(0, $max);
  63 + }
  64 +
  65 + /**
  66 + * 拉取回复信息
  67 + *
  68 + * @param int $max 拉取最大条数,最多100
  69 + * @return string 应答json字符串,详细内容参见腾讯云协议文档
  70 + */
  71 + public function pullReply($max)
  72 + {
  73 + return $this->pull(1, $max);
  74 + }
  75 +}
  1 +<?php
  2 +
  3 +namespace addons\qcloudsms\library;
  4 +
  5 +use addons\qcloudsms\library\SmsSenderUtil;
  6 +
  7 +/**
  8 + * 发送语音通知类
  9 + *
  10 + */
  11 +class SmsVoicePromptSender
  12 +{
  13 + private $url;
  14 + private $appid;
  15 + private $appkey;
  16 + private $util;
  17 +
  18 + /**
  19 + * 构造函数
  20 + *
  21 + * @param string $appid sdkappid
  22 + * @param string $appkey sdkappid对应的appkey
  23 + */
  24 + public function __construct($appid, $appkey)
  25 + {
  26 + $this->url = "https://yun.tim.qq.com/v5/tlsvoicesvr/sendvoiceprompt";
  27 + $this->appid = $appid;
  28 + $this->appkey = $appkey;
  29 + $this->util = new SmsSenderUtil();
  30 + }
  31 +
  32 + /**
  33 + *
  34 + * 发送语音通知
  35 + *
  36 + * @param string $nationCode 国家码,如 86 为中国
  37 + * @param string $phoneNumber 不带国家码的手机号
  38 + * @param string $prompttype 语音类型,目前固定为2
  39 + * @param string $msg 信息内容,必须与申请的模板格式一致,否则将返回错误
  40 + * @param string $playtimes 播放次数,可选,最多3次,默认2次
  41 + * @param string $ext 用户的session内容,服务端原样返回,可选字段,不需要可填空串
  42 + * @return string 应答json字符串,详细内容参见腾讯云协议文档
  43 + */
  44 + public function send($nationCode, $phoneNumber, $prompttype, $msg, $playtimes = 2, $ext = "")
  45 + {
  46 + $random = $this->util->getRandom();
  47 + $curTime = time();
  48 + $wholeUrl = $this->url . "?sdkappid=" . $this->appid . "&random=" . $random;
  49 +
  50 + // 按照协议组织 post 包体
  51 + $data = new \stdClass();
  52 + $tel = new \stdClass();
  53 + $tel->nationcode = "".$nationCode;
  54 + $tel->mobile = "".$phoneNumber;
  55 +
  56 + $data->tel = $tel;
  57 + // 通知内容,utf8编码,支持中文英文、数字及组合,需要和语音内容模版相匹配
  58 + $data->promptfile = $msg;
  59 + // 固定值 2
  60 + $data->prompttype = $prompttype;
  61 + $data->playtimes = $playtimes;
  62 + // app凭证
  63 + $data->sig = hash("sha256",
  64 + "appkey=".$this->appkey."&random=".$random."&time="
  65 + .$curTime."&mobile=".$phoneNumber, FALSE);
  66 + // unix时间戳,请求发起时间,如果和系统时间相差超过10分钟则会返回失败
  67 + $data->time = $curTime;
  68 + $data->ext = $ext;
  69 + return $this->util->sendCurlPost($wholeUrl, $data);
  70 + }
  71 +}
  1 +<?php
  2 +
  3 +namespace addons\qcloudsms\library;
  4 +
  5 +use addons\qcloudsms\library\SmsSenderUtil;
  6 +
  7 +/**
  8 + * 发送语音验证码类
  9 + *
  10 + */
  11 +class SmsVoiceVerifyCodeSender
  12 +{
  13 + private $url;
  14 + private $appid;
  15 + private $appkey;
  16 + private $util;
  17 +
  18 + /**
  19 + * 构造函数
  20 + *
  21 + * @param string $appid sdkappid
  22 + * @param string $appkey sdkappid对应的appkey
  23 + */
  24 + public function __construct($appid, $appkey)
  25 + {
  26 + $this->url = "https://yun.tim.qq.com/v5/tlsvoicesvr/sendvoice";
  27 + $this->appid = $appid;
  28 + $this->appkey = $appkey;
  29 + $this->util = new SmsSenderUtil();
  30 + }
  31 +
  32 + /**
  33 + * 发送语音验证码
  34 + *
  35 + * @param string $nationCode 国家码,如 86 为中国
  36 + * @param string $phoneNumber 不带国家码的手机号
  37 + * @param string $msg 信息内容,必须与申请的模板格式一致,否则将返回错误
  38 + * @param int $playtimes 播放次数,可选,最多3次,默认2次
  39 + * @param string $ext 用户的session内容,服务端原样返回,可选字段,不需要可填空串
  40 + * @return string 应答json字符串,详细内容参见腾讯云协议文档
  41 + */
  42 + public function send($nationCode, $phoneNumber, $msg, $playtimes = 2, $ext = "")
  43 + {
  44 + $random = $this->util->getRandom();
  45 + $curTime = time();
  46 + $wholeUrl = $this->url . "?sdkappid=" . $this->appid . "&random=" . $random;
  47 +
  48 + // 按照协议组织 post 包体
  49 + $data = new \stdClass();
  50 + $tel = new \stdClass();
  51 + $tel->nationcode = "".$nationCode;
  52 + $tel->mobile = "".$phoneNumber;
  53 +
  54 + $data->tel = $tel;
  55 + $data->msg = $msg;
  56 + $data->playtimes = $playtimes;
  57 + // app凭证
  58 + $data->sig = hash("sha256",
  59 + "appkey=".$this->appkey."&random=".$random."&time="
  60 + .$curTime."&mobile=".$phoneNumber, FALSE);
  61 + // unix时间戳,请求发起时间,如果和系统时间相差超过10分钟则会返回失败
  62 + $data->time = $curTime;
  63 + $data->ext = $ext;
  64 +
  65 + return $this->util->sendCurlPost($wholeUrl, $data);
  66 + }
  67 +}
  1 +<?php
  2 +
  3 +namespace addons\qcloudsms\library;
  4 +
  5 +use addons\qcloudsms\library\SmsSenderUtil;
  6 +
  7 +
  8 +/**
  9 + * 指定模板发送语音通知类
  10 + *
  11 + */
  12 +class TtsVoiceSender
  13 +{
  14 + private $url;
  15 + private $appid;
  16 + private $appkey;
  17 + private $util;
  18 +
  19 + /**
  20 + * 构造函数
  21 + *
  22 + * @param string $appid sdkappid
  23 + * @param string $appkey sdkappid对应的appkey
  24 + */
  25 + public function __construct($appid, $appkey)
  26 + {
  27 + $this->url = "https://cloud.tim.qq.com/v5/tlsvoicesvr/sendtvoice";
  28 + $this->appid = $appid;
  29 + $this->appkey = $appkey;
  30 + $this->util = new SmsSenderUtil();
  31 + }
  32 +
  33 + /**
  34 + *
  35 + * 指定模板发送语音短信
  36 + *
  37 + * @param string $nationCode 国家码,如 86 为中国
  38 + * @param string $phoneNumber 不带国家码的手机号
  39 + * @param int $templId 模板 id
  40 + * @param array $params 模板参数列表,如模板 {1}...{2}...{3},需要带三个参数
  41 + * @param string $playtimes 播放次数,可选,最多3次,默认2次
  42 + * @param string $ext 用户的session内容,服务端原样返回,可选字段,不需要可填空串
  43 + * @return string 应答json字符串,详细内容参见腾讯云协议文档
  44 + */
  45 + public function send($nationCode, $phoneNumber, $templId, $params, $playtimes = 2, $ext = "")
  46 + {
  47 + /*var_dump($nationCode);
  48 + var_dump($phoneNumber);
  49 + var_dump($templId);
  50 + var_dump($params);
  51 + var_dump($playtimes);
  52 + exit();*/
  53 + $random = $this->util->getRandom();
  54 + $curTime = time();
  55 + $wholeUrl = $this->url . "?sdkappid=" . $this->appid . "&random=" . $random;
  56 +
  57 + // 按照协议组织 post 包体
  58 + $data = new \stdClass();
  59 + $tel = new \stdClass();
  60 + $tel->nationcode = "".$nationCode;
  61 + $tel->mobile = "".$phoneNumber;
  62 + $data->tel = $tel;
  63 + $data->tpl_id = $templId;
  64 + $data->params = $params;
  65 + $data->playtimes = $playtimes;
  66 +
  67 + // app凭证
  68 + $data->sig = $this->util->calculateSig($this->appkey, $random,
  69 + $curTime, array($phoneNumber));
  70 +
  71 + // unix时间戳,请求发起时间,如果和系统时间相差超过10分钟则会返回失败
  72 + $data->time = $curTime;
  73 + $data->ext = $ext;
  74 + //var_dump($data);exit();
  75 + return $this->util->sendCurlPost($wholeUrl, $data);
  76 + }
  77 +}