feat: 后端全量更新 - 含所有本次需求

- Contract.php: 返回合约账户余额(balance_contract)
- My.php: 地址管理增加BTC/ETH
- AppContract.php: 一键平仓(closeall)
- AppProxy.php: 代理专属注册链接 + 分级权限(L1/L2)
- site.php: 手续费减半(0.018→0.009)
- agent_permission_setup.sql: 代理权限SQL
- crypto_news_crawler.py: 新闻自动采集脚本
This commit is contained in:
li
2026-03-30 20:16:32 +08:00
commit 1b24994e74
6721 changed files with 1308571 additions and 0 deletions
+1
View File
@@ -0,0 +1 @@
{"license":"regular","licenseto":"16556","licensekey":"7P9ZKjXLBSIwWObi 9uI02YSv\/lACsiPp+RDcR1UdyqzclNt9TjhV5+sAPbg="}
+264
View File
@@ -0,0 +1,264 @@
<?php
namespace addons\qcloudsms;
use addons\qcloudsms\library\SmsSingleSender;
use addons\qcloudsms\library\SmsVoicePromptSender;
use addons\qcloudsms\library\SmsVoiceverifyCodeSender;
use addons\qcloudsms\library\TtsVoiceSender;
use think\Addons;
use think\Config;
use telesign\sdk\messaging\MessagingClient;
use telesign\sdk\voice\VoiceClient;
use AlibabaCloud\Client\AlibabaCloud;
use AlibabaCloud\Client\Exception\ClientException;
use AlibabaCloud\Client\Exception\ServerException;
// 导入对应产品模块的client
use TencentCloud\Sms\V20210111\SmsClient;
// 导入要请求接口对应的Request类
use TencentCloud\Sms\V20210111\Models\SendSmsRequest;
use TencentCloud\Common\Exception\TencentCloudSDKException;
use TencentCloud\Common\Credential;
// 导入可选配置类
use TencentCloud\Common\Profile\ClientProfile;
use TencentCloud\Common\Profile\HttpProfile;
/**
* 插件
*/
class Qcloudsms extends Addons
{
private $appid = null;
private $appkey = null;
private $config = null;
private $sender = null;
private $sendError = '';
public function ConfigInit()
{
$this->config = $this->getConfig();
//如果使用语音短信 更换成语音短信模板
if ($this->config['isVoice'] == 1) {
$this->config['template'] = $this->config['voiceTemplate'];
//语音短信 需要另行设置Aappid 与Appkey
$this->appid = $this->config['voiceAppid'];
$this->appkey = $this->config['voiceAppkey'];
} else {
$this->appid = $this->config['appid'];
$this->appkey = $this->config['appkey'];
}
}
/**
* 短信发送行为
* @param Sms $params
* @return boolean
*/
public function smsSend(&$params) {
//腾讯
try {
/* 必要步骤:
* 实例化一个认证对象,入参需要传入腾讯云账户密钥对secretIdsecretKey。
* 这里采用的是从环境变量读取的方式,需要在环境变量中先设置这两个值。
* 你也可以直接在代码中写死密钥对,但是小心不要将代码复制、上传或者分享给他人,
* 以免泄露密钥对危及你的财产安全。
* CAM密匙查询: https://console.cloud.tencent.com/cam/capi*/
$cred = new Credential("IKIDhLn151pT0bItU3UsBQabWNYacdVIuoYF", "lPzb9sTGuNsZ6c3MugUOAmNq9874vrlb");
//$cred = new Credential(getenv("TENCENTCLOUD_SECRET_ID"), getenv("TENCENTCLOUD_SECRET_KEY"));
// 实例化一个http选项,可选的,没有特殊需求可以跳过
$httpProfile = new HttpProfile();
// 配置代理
// $httpProfile->setProxy("https://ip:port");
$httpProfile->setReqMethod("GET"); // post请求(默认为post请求)
$httpProfile->setReqTimeout(30); // 请求超时时间,单位为秒(默认60秒)
$httpProfile->setEndpoint("sms.tencentcloudapi.com"); // 指定接入地域域名(默认就近接入)
// 实例化一个client选项,可选的,没有特殊需求可以跳过
$clientProfile = new ClientProfile();
$clientProfile->setSignMethod("TC3-HMAC-SHA256"); // 指定签名算法(默认为HmacSHA256)
$clientProfile->setHttpProfile($httpProfile);
// 实例化要请求产品(以sms为例)的client对象,clientProfile是可选的
// 第二个参数是地域信息,根据您选择的国际站地域,如您选择的是新加坡国际站,则应该填入字符串ap-singapore,地域列表可参考https://intl.cloud.tencent.com/document/api/382/40466?lang=en#region-list
$client = new SmsClient($cred, "ap-singapore", $clientProfile);
// 实例化一个 sms 发送短信请求对象,每个接口都会对应一个request对象。
$req = new SendSmsRequest();
/* 短信应用ID: 短信SdkAppId在 [短信控制台] 添加应用后生成的实际SdkAppId,示例如1400006666 */
$req->SmsSdkAppId = "2400000981";
/* 短信签名内容: 使用 UTF-8 编码,必须填写已审核通过的签名,签名信息可登录 [短信控制台] 查看 */
$req->SignName = "";
/* 短信码号扩展号: 默认未开通,如需开通请联系 [sms helper] */
$req->ExtendCode = "";
/* 下发手机号码,采用 E.164 标准,+[国家或地区码][手机号]
* 示例如:+8613711112222, 其中前面有一个+号 86为国家码,13711112222为手机号,最多不要超过200个手机号*/
$phone_number = $params['m_prefix'] . $params['mobile'];
$req->PhoneNumberSet = array($phone_number);
/* 国际/港澳台短信 SenderId: 中国大陆地区短信填空,默认未开通,如需开通请联系 [sms helper] */
$req->SenderId = "";
/* 用户的 session 内容: 可以携带用户侧 ID 等上下文信息,server 会原样返回 */
$req->SessionContext = "【turkey global】Your OTP code is {1} Don't share this code with others dated!";
/* 模板 ID: 必须填写已审核通过的模板 ID。模板ID可登录 [短信控制台] 查看 */
$req->TemplateId = "2905310"; //2905133
/* 模板参数: 若无模板参数,则设置为空*/
$req->TemplateParamSet = array($params['code']);
// 通过client对象调用SendSms方法发起请求。注意请求方法名与请求对象是对应的
// 返回的resp是一个SendSmsResponse类的实例,与请求对象对应
$resp = $client->SendSms($req);
// 输出json格式的字符串回包
// print_r($resp->toJsonString());
// 也可以取出单个值。
// 您可以通过官网接口文档或跳转到response对象的定义处查看返回字段的定义
// print_r($resp->TotalCount);
return true;
}
catch(TencentCloudSDKException $e) {
// echo $e;
return true;
}
// AlibabaCloud::accessKeyClient('LTAI5tGjBhYq4u2e13f4cAQ6', 'X20XXcrKZHbGjpHHeTo3rfNuhMgeKg')
// ->regionId('ap-southeast-1')
// ->asGlobalClient();
// $phone_number = $params['m_prefix'] . $params['mobile'];
// $result = AlibabaCloud::rpcRequest()
// ->product('Dysmsapi')
// ->host('dysmsapi.ap-southeast-1.aliyuncs.com')
// ->version('2018-05-01')
// ->action('SendMessageToGlobe')
// ->method('POST')
// ->options([
// 'query' => [
// "To" => $phone_number,
// // "From" => "1234567890",
// "Message" => "【Poly】Your OTP code is " . $params['code'] . " Don't share this code with others dated",
// ],
// ])
// ->request();
//// print_r($result->toArray());
//
// return true;
// if ($send_res['status']['code'] == 200) {
// return true;
// } else {
// return true;
// }
// die;
}
/**
* 短信发送通知
* @param array $params
* @return boolean
*/
public function smsNotice(&$params)
{
$this->ConfigInit();
try {
if ($this->config['isTemplateSender'] == 1) {
$templateID = $this->config['template'][$params['template']];
if ($this->config['isVoice'] != 1) {
//普通短信发送
$this->sender = new SmsSingleSender($this->appid, $this->appkey);
$result = $this->sender->sendWithParam("86", $params['mobile'], $templateID, ["{$params['msg']}"], $this->config['sign'], "", "");
} else {
//语音短信发送
$this->sender = new TtsVoiceSender($this->appid, $this->appkey);
//参数: 国家码,手机号、模板ID、模板参数、播放次数(可选字段)、用户的session内容,服务器端原样返回(可选字段)
$result = $this->sender->send("86", $params['mobile'], $templateID, [$params['msg']]);
}
} else {
//判断是否是语音短信
if ($this->config['isVoice'] != 1) {
$this->sender = new SmsSingleSender($this->appid, $this->appkey);
//参数:短信类型{1营销短信,0普通短信 }、国家码、手机号、短信内容、扩展码(可留空)、服务的原样返回的参数
$result = $this->sender->send($params['type'], '86', $params['mobile'], $params['msg'], "", "");
} else {
$this->sender = new SmsVoicePromptSender($this->appid, $this->appkey);
//参数:国家码、手机号、语音类型(目前固定为2)、短信内容、播放次数(默认2次)、服务的原样返回的参数
$result = $this->sender->send('86', $params['mobile'], 2, $params['msg']);
}
}
$rsp = (array)json_decode($result, true);
if ($rsp['result'] == 0 && $rsp['errmsg'] == 'OK') {
return true;
} else {
//记录错误信息
$this->setError($rsp);
return false;
}
} catch (\Exception $e) {
var_dump($e);
exit();
}
}
/**
* 记录失败信息
* @param [type] $err [description]
*/
private function setError($err)
{
$this->sendError = $err;
}
/**
* 获取失败信息
* @return [type] [description]
*/
public function getError()
{
return $this->sendError;
}
/**
* 检测验证是否正确
* @param Sms $params
* @return boolean
*/
public function smsCheck(&$params)
{
return true;
}
/**
* 插件安装方法
* @return bool
*/
public function install()
{
return true;
}
/**
* 插件卸载方法
* @return bool
*/
public function uninstall()
{
return true;
}
/**
* 插件启用方法
* @return bool
*/
public function enable()
{
return true;
}
/**
* 插件禁用方法
* @return bool
*/
public function disable()
{
return true;
}
}
+139
View File
@@ -0,0 +1,139 @@
<?php
return array(
array(
'name' => 'appid',
'title' => '应用AppID',
'type' => 'string',
'content' =>
array(),
'value' => '',
'rule' => 'required',
'msg' => '',
'tip' => '',
'ok' => '',
'extend' => '',
),
array(
'name' => 'appkey',
'title' => '应用AppKEY',
'type' => 'string',
'content' =>
array(),
'value' => '',
'rule' => 'required',
'msg' => '',
'tip' => '',
'ok' => '',
'extend' => '',
),
array(
'name' => 'voiceAppid',
'title' => '语音短信AppID',
'type' => 'string',
'content' =>
array(),
'value' => '',
'rule' => 'required',
'msg' => '使用语音短信必须设置',
'tip' => '',
'ok' => '',
'extend' => '',
),
array(
'name' => 'voiceAppkey',
'title' => '语音短信AppKEY',
'type' => 'string',
'content' =>
array(),
'value' => '',
'rule' => 'required',
'msg' => '使用语音短信必须设置',
'tip' => '',
'ok' => '',
'extend' => '',
),
array(
'name' => 'sign',
'title' => '签名',
'type' => 'string',
'content' =>
array(),
'value' => 'your sign',
'rule' => 'required',
'msg' => '',
'tip' => '',
'ok' => '',
'extend' => '',
),
array(
'name' => 'isVoice',
'title' => '是否使用语音短信',
'type' => 'radio',
'content' =>
array(
0 => '否',
1 => '是',
),
'value' => '0',
'rule' => 'required',
'msg' => '',
'tip' => '',
'ok' => '',
'extend' => '',
),
array(
'name' => 'isTemplateSender',
'title' => '是否使用短信模板发送',
'type' => 'radio',
'content' =>
array(
0 => '否',
1 => '是',
),
'value' => '1',
'rule' => 'required',
'msg' => '',
'tip' => '',
'ok' => '',
'extend' => '',
),
array(
'name' => 'template',
'title' => '短信模板',
'type' => 'array',
'content' =>
array(),
'value' =>
array(
'register' => '',
'resetpwd' => '',
'changepwd' => '',
'profile' => '',
),
'rule' => 'required',
'msg' => '',
'tip' => '',
'ok' => '',
'extend' => '',
),
array(
'name' => 'voiceTemplate',
'title' => '语音短信模板',
'type' => 'array',
'content' =>
array(),
'value' =>
array(
'register' => '',
'resetpwd' => '',
'changepwd' => '',
'profile' => '',
),
'rule' => 'required',
'msg' => '',
'tip' => '',
'ok' => '',
'extend' => '',
),
);
+15
View File
@@ -0,0 +1,15 @@
<?php
namespace addons\qcloudsms\controller;
use think\addons\Controller;
class Index extends Controller
{
public function index()
{
$this->error("当前插件暂无前台页面");
}
}
+10
View File
@@ -0,0 +1,10 @@
name = qcloudsms
title = 腾讯云短信发送插件
intro = 腾讯云短信发送插件
author = Seacent
website = https://www.seacent.com
version = 1.0.3
state = 1
url = /addons/qcloudsms
license = regular
licenseto = 16556
+69
View File
@@ -0,0 +1,69 @@
<?php
namespace addons\qcloudsms\library;
use addons\qcloudsms\library\SmsSenderUtil;
/**
* 按语音文件fid发送语音通知类
*
*/
class FileVoiceSender
{
private $url;
private $appid;
private $appkey;
private $util;
/**
* 构造函数
*
* @param string $appid sdkappid
* @param string $appkey sdkappid对应的appkey
*/
public function __construct($appid, $appkey)
{
$this->url = "https://cloud.tim.qq.com/v5/tlsvoicesvr/sendfvoice";
$this->appid = $appid;
$this->appkey = $appkey;
$this->util = new SmsSenderUtil();
}
/**
*
* 按语音文件fid发送语音通知
*
* @param string $nationCode 国家码,如 86 为中国
* @param string $phoneNumber 不带国家码的手机号
* @param string $fid 语音文件fid
* @param string $playtimes 播放次数,可选,最多3次,默认2次
* @param string $ext 用户的session内容,服务端原样返回,可选字段,不需要可填空串
* @return string 应答json字符串,详细内容参见腾讯云协议文档
*/
public function send($nationCode, $phoneNumber, $fid, $playtimes = 2, $ext = "")
{
$random = $this->util->getRandom();
$curTime = time();
$wholeUrl = $this->url . "?sdkappid=" . $this->appid . "&random=" . $random;
// 按照协议组织 post 包体
$data = new \stdClass();
$tel = new \stdClass();
$tel->nationcode = "".$nationCode;
$tel->mobile = "".$phoneNumber;
$data->tel = $tel;
$data->fid = $fid;
$data->playtimes = $playtimes;
// app凭证
$data->sig = $this->util->calculateSig($this->appkey, $random,
$curTime, array($phoneNumber));
// unix时间戳,请求发起时间,如果和系统时间相差超过10分钟则会返回失败
$data->time = $curTime;
$data->ext = $ext;
return $this->util->sendCurlPost($wholeUrl, $data);
}
}
+91
View File
@@ -0,0 +1,91 @@
<?php
namespace addons\qcloudsms\library;
use addons\qcloudsms\library\SmsSenderUtil;
/**
* 拉取单个手机短信状态类
*
*/
class SmsMobileStatusPuller
{
private $url;
private $appid;
private $appkey;
private $util;
/**
* 构造函数
*
* @param string $appid sdkappid
* @param string $appkey sdkappid对应的appkey
*/
public function __construct($appid, $appkey)
{
$this->url = "https://yun.tim.qq.com/v5/tlssmssvr/pullstatus4mobile";
$this->appid = $appid;
$this->appkey = $appkey;
$this->util = new SmsSenderUtil();
}
/**
* 拉取回执结果
*
* @param int $type 拉取类型,0表示回执结果,1表示回复信息
* @param string $nationCode 国家码,如 86 为中国
* @param string $mobile 不带国家码的手机号
* @param int $beginTime 开始时间(unix timestamp)
* @param int $endTime 结束时间(unix timestamp)
* @param int $max 拉取最大条数,最多100
* @return string 应答json字符串,详细内容参见腾讯云协议文档
*/
private function pull($type, $nationCode, $mobile, $beginTime, $endTime, $max)
{
$random = $this->util->getRandom();
$curTime = time();
$wholeUrl = $this->url . "?sdkappid=" . $this->appid . "&random=" . $random;
$data = new \stdClass();
$data->sig = $this->util->calculateSigForPuller($this->appkey, $random, $curTime);
$data->time = $curTime;
$data->type = $type;
$data->max = $max;
$data->begin_time = $beginTime;
$data->end_time = $endTime;
$data->nationcode = $nationCode;
$data->mobile = $mobile;
return $this->util->sendCurlPost($wholeUrl, $data);
}
/**
* 拉取回执结果
*
* @param string $nationCode 国家码,如 86 为中国
* @param string $mobile 不带国家码的手机号
* @param int $beginTime 开始时间(unix timestamp)
* @param int $endTime 结束时间(unix timestamp)
* @param int $max 拉取最大条数,最多100
* @return string 应答json字符串,详细内容参见腾讯云协议文档
*/
public function pullCallback($nationCode, $mobile, $beginTime, $endTime, $max)
{
return $this->pull(0, $nationCode, $mobile, $beginTime, $endTime, $max);
}
/**
* 拉取回复信息
*
* @param string $nationCode 国家码,如 86 为中国
* @param string $mobile 不带国家码的手机号
* @param int $beginTime 开始时间(unix timestamp)
* @param int $endTime 结束时间(unix timestamp)
* @param int $max 拉取最大条数,最多100
* @return string 应答json字符串,详细内容参见腾讯云协议文档
*/
public function pullReply($nationCode, $mobile, $beginTime, $endTime, $max)
{
return $this->pull(1, $nationCode, $mobile, $beginTime, $endTime, $max);
}
}
+99
View File
@@ -0,0 +1,99 @@
<?php
namespace addons\qcloudsms\library;
use addons\qcloudsms\library\SmsSenderUtil;
/**
* 群发短信类
*
*/
class SmsMultiSender
{
private $url;
private $appid;
private $appkey;
private $util;
/**
* 构造函数
*
* @param string $appid sdkappid
* @param string $appkey sdkappid对应的appkey
*/
public function __construct($appid, $appkey)
{
$this->url = "https://yun.tim.qq.com/v5/tlssmssvr/sendmultisms2";
$this->appid = $appid;
$this->appkey = $appkey;
$this->util = new SmsSenderUtil();
}
/**
* 普通群发
*
* 普通群发需明确指定内容,如果有多个签名,请在内容中以【】的方式添加到信息内容中,
* 否则系统将使用默认签名。
*
*
* @param int $type 短信类型,0 为普通短信,1 营销短信
* @param string $nationCode 国家码,如 86 为中国
* @param array $phoneNumbers 不带国家码的手机号列表
* @param string $msg 信息内容,必须与申请的模板格式一致,否则将返回错误
* @param string $extend 扩展码,可填空串
* @param string $ext 服务端原样返回的参数,可填空串
* @return string 应答json字符串,详细内容参见腾讯云协议文档
*/
public function send($type, $nationCode, $phoneNumbers, $msg, $extend = "", $ext = "")
{
$random = $this->util->getRandom();
$curTime = time();
$wholeUrl = $this->url . "?sdkappid=" . $this->appid . "&random=" . $random;
$data = new \stdClass();
$data->tel = $this->util->phoneNumbersToArray($nationCode, $phoneNumbers);
$data->type = $type;
$data->msg = $msg;
$data->sig = $this->util->calculateSig($this->appkey, $random,
$curTime, $phoneNumbers);
$data->time = $curTime;
$data->extend = $extend;
$data->ext = $ext;
return $this->util->sendCurlPost($wholeUrl, $data);
}
/**
* 指定模板群发
*
*
* @param string $nationCode 国家码,如 86 为中国
* @param array $phoneNumbers 不带国家码的手机号列表
* @param int $templId 模板id
* @param array $params 模板参数列表,如模板 {1}...{2}...{3},那么需要带三个参数
* @param string $sign 签名,如果填空串,系统会使用默认签名
* @param string $extend 扩展码,可填空串
* @param string $ext 服务端原样返回的参数,可填空串
* @return string 应答json字符串,详细内容参见腾讯云协议文档
*/
public function sendWithParam($nationCode, $phoneNumbers, $templId, $params,
$sign = "", $extend = "", $ext = "")
{
$random = $this->util->getRandom();
$curTime = time();
$wholeUrl = $this->url . "?sdkappid=" . $this->appid . "&random=" . $random;
$data = new \stdClass();
$data->tel = $this->util->phoneNumbersToArray($nationCode, $phoneNumbers);
$data->sign = $sign;
$data->tpl_id = $templId;
$data->params = $params;
$data->sig = $this->util->calculateSigForTemplAndPhoneNumbers(
$this->appkey, $random, $curTime, $phoneNumbers);
$data->time = $curTime;
$data->extend = $extend;
$data->ext = $ext;
return $this->util->sendCurlPost($wholeUrl, $data);
}
}
+211
View File
@@ -0,0 +1,211 @@
<?php
namespace addons\qcloudsms\library;
/**
* 发送Util类
*
*/
class SmsSenderUtil
{
/**
* 生成随机数
*
* @return int 随机数结果
*/
public function getRandom()
{
return rand(100000, 999999);
}
/**
* 生成签名
*
* @param string $appkey sdkappid对应的appkey
* @param string $random 随机正整数
* @param string $curTime 当前时间
* @param array $phoneNumbers 手机号码
* @return string 签名结果
*/
public function calculateSig($appkey, $random, $curTime, $phoneNumbers)
{
$phoneNumbersString = $phoneNumbers[0];
for ($i = 1; $i < count($phoneNumbers); $i++) {
$phoneNumbersString .= ("," . $phoneNumbers[$i]);
}
return hash("sha256", "appkey=".$appkey."&random=".$random
."&time=".$curTime."&mobile=".$phoneNumbersString);
}
/**
* 生成签名
*
* @param string $appkey sdkappid对应的appkey
* @param string $random 随机正整数
* @param string $curTime 当前时间
* @param array $phoneNumbers 手机号码
* @return string 签名结果
*/
public function calculateSigForTemplAndPhoneNumbers($appkey, $random,
$curTime, $phoneNumbers)
{
$phoneNumbersString = $phoneNumbers[0];
for ($i = 1; $i < count($phoneNumbers); $i++) {
$phoneNumbersString .= ("," . $phoneNumbers[$i]);
}
return hash("sha256", "appkey=".$appkey."&random=".$random
."&time=".$curTime."&mobile=".$phoneNumbersString);
}
public function phoneNumbersToArray($nationCode, $phoneNumbers)
{
$i = 0;
$tel = array();
do {
$telElement = new \stdClass();
$telElement->nationcode = $nationCode;
$telElement->mobile = $phoneNumbers[$i];
array_push($tel, $telElement);
} while (++$i < count($phoneNumbers));
return $tel;
}
/**
* 生成签名
*
* @param string $appkey sdkappid对应的appkey
* @param string $random 随机正整数
* @param string $curTime 当前时间
* @param array $phoneNumber 手机号码
* @return string 签名结果
*/
public function calculateSigForTempl($appkey, $random, $curTime, $phoneNumber)
{
$phoneNumbers = array($phoneNumber);
return $this->calculateSigForTemplAndPhoneNumbers($appkey, $random,
$curTime, $phoneNumbers);
}
/**
* 生成签名
*
* @param string $appkey sdkappid对应的appkey
* @param string $random 随机正整数
* @param string $curTime 当前时间
* @return string 签名结果
*/
public function calculateSigForPuller($appkey, $random, $curTime)
{
return hash("sha256", "appkey=".$appkey."&random=".$random
."&time=".$curTime);
}
/**
* 生成上传文件授权
*
* @param string $appkey sdkappid对应的appkey
* @param string $random 随机正整数
* @param string $curTime 当前时间
* @param array $fileSha1Sum 文件sha1sum
* @return string 授权结果
*/
public function calculateAuth($appkey, $random, $curTime, $fileSha1Sum)
{
return hash("sha256", "appkey=".$appkey."&random=".$random
."&time=".$curTime."&content-sha1=".$fileSha1Sum);
}
/**
* 生成sha1sum
*
* @param string $content 内容
* @return string 内容sha1散列值
*/
public function sha1sum($content)
{
return hash("sha1", $content);
}
/**
* 发送请求
*
* @param string $url 请求地址
* @param array $dataObj 请求内容
* @return string 应答json字符串
*/
public function sendCurlPost($url, $dataObj)
{
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_HEADER, 0);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($curl, CURLOPT_POST, 1);
curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 60);
curl_setopt($curl, CURLOPT_POSTFIELDS, json_encode($dataObj));
curl_setopt($curl, CURLOPT_HTTPHEADER, array(
'Content-Type: application/json; charset=utf-8',
'Content-Length: ' . strlen(json_encode($dataObj)))
);
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, 0);
$ret = curl_exec($curl);
if (false == $ret) {
// curl_exec failed
$result = "{ \"result\":" . -2 . ",\"errmsg\":\"" . curl_error($curl) . "\"}";
} else {
$rsp = curl_getinfo($curl, CURLINFO_HTTP_CODE);
if (200 != $rsp) {
$result = "{ \"result\":" . -1 . ",\"errmsg\":\"". $rsp
. " " . curl_error($curl) ."\"}";
} else {
$result = $ret;
}
}
curl_close($curl);
return $result;
}
/**
* 发送请求
*
* @param string $req 请求对象
* @return string 应答json字符串
*/
public function fetch($req)
{
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, $req->url);
curl_setopt($curl, CURLOPT_HTTPHEADER, $req->headers);
curl_setopt($curl, CURLOPT_POSTFIELDS, $req->body);
curl_setopt($curl, CURLOPT_HEADER, 0);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($curl, CURLOPT_POST, 1);
curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 60);
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, 0);
$result = curl_exec($curl);
if (false == $result) {
// curl_exec failed
$result = "{ \"result\":" . -2 . ",\"errmsg\":\"" . curl_error($curl) . "\"}";
} else {
$code = curl_getinfo($curl, CURLINFO_HTTP_CODE);
if (200 != $code) {
$result = "{ \"result\":" . -1 . ",\"errmsg\":\"". $rsp
. " " . curl_error($curl) ."\"}";
}
}
curl_close($curl);
return $result;
}
}
+107
View File
@@ -0,0 +1,107 @@
<?php
namespace addons\qcloudsms\library;
use addons\qcloudsms\library\SmsSenderUtil;
/**
* 单发短信类
*
*/
class SmsSingleSender
{
private $url;
private $appid;
private $appkey;
private $util;
/**
* 构造函数
*
* @param string $appid sdkappid
* @param string $appkey sdkappid对应的appkey
*/
public function __construct($appid, $appkey)
{
$this->url = "https://yun.tim.qq.com/v5/tlssmssvr/sendsms";
$this->appid = $appid;
$this->appkey = $appkey;
$this->util = new SmsSenderUtil();
}
/**
* 普通单发
*
* 普通单发需明确指定内容,如果有多个签名,请在内容中以【】的方式添加到信息内容中,否则系统将使用默认签名。
*
* @param int $type 短信类型,0 为普通短信,1 营销短信
* @param string $nationCode 国家码,如 86 为中国
* @param string $phoneNumber 不带国家码的手机号
* @param string $msg 信息内容,必须与申请的模板格式一致,否则将返回错误
* @param string $extend 扩展码,可填空串
* @param string $ext 服务端原样返回的参数,可填空串
* @return string 应答json字符串,详细内容参见腾讯云协议文档
*/
public function send($type, $nationCode, $phoneNumber, $msg, $extend = "", $ext = "")
{
$random = $this->util->getRandom();
$curTime = time();
$wholeUrl = $this->url . "?sdkappid=" . $this->appid . "&random=" . $random;
// 按照协议组织 post 包体
$data = new \stdClass();
$tel = new \stdClass();
$tel->nationcode = "".$nationCode;
$tel->mobile = "".$phoneNumber;
$data->tel = $tel;
$data->type = (int)$type;
$data->msg = $msg;
$data->sig = hash("sha256",
"appkey=".$this->appkey."&random=".$random."&time="
.$curTime."&mobile=".$phoneNumber, FALSE);
$data->time = $curTime;
$data->extend = $extend;
$data->ext = $ext;
return $this->util->sendCurlPost($wholeUrl, $data);
}
/**
* 指定模板单发
*
* @param string $nationCode 国家码,如 86 为中国
* @param string $phoneNumber 不带国家码的手机号
* @param int $templId 模板 id
* @param array $params 模板参数列表,如模板 {1}...{2}...{3},那么需要带三个参数
* @param string $sign 签名,如果填空串,系统会使用默认签名
* @param string $extend 扩展码,可填空串
* @param string $ext 服务端原样返回的参数,可填空串
* @return string 应答json字符串,详细内容参见腾讯云协议文档
*/
public function sendWithParam($nationCode, $phoneNumber, $templId = 0, $params,
$sign = "", $extend = "", $ext = "")
{
$random = $this->util->getRandom();
$curTime = time();
$wholeUrl = $this->url . "?sdkappid=" . $this->appid . "&random=" . $random;
// 按照协议组织 post 包体
$data = new \stdClass();
$tel = new \stdClass();
$tel->nationcode = "".$nationCode;
$tel->mobile = "".$phoneNumber;
$data->tel = $tel;
$data->sig = $this->util->calculateSigForTempl($this->appkey, $random,
$curTime, $phoneNumber);
$data->tpl_id = $templId;
$data->params = $params;
$data->sign = $sign;
$data->time = $curTime;
$data->extend = $extend;
$data->ext = $ext;
return $this->util->sendCurlPost($wholeUrl, $data);
}
}
+75
View File
@@ -0,0 +1,75 @@
<?php
namespace addons\qcloudsms\library;
use addons\qcloudsms\library\SmsSenderUtil;
/**
* 拉取短信状态类
*
*/
class SmsStatusPuller
{
private $url;
private $appid;
private $appkey;
private $util;
/**
* 构造函数
*
* @param string $appid sdkappid
* @param string $appkey sdkappid对应的appkey
*/
public function __construct($appid, $appkey)
{
$this->url = "https://yun.tim.qq.com/v5/tlssmssvr/pullstatus";
$this->appid = $appid;
$this->appkey = $appkey;
$this->util = new SmsSenderUtil();
}
/**
* 拉取回执结果
*
* @param int $type 拉取类型,0表示回执结果,1表示回复信息
* @param int $max 最大条数,最多100
* @return string 应答json字符串,详细内容参见腾讯云协议文档
*/
private function pull($type, $max)
{
$random = $this->util->getRandom();
$curTime = time();
$wholeUrl = $this->url . "?sdkappid=" . $this->appid . "&random=" . $random;
$data = new \stdClass();
$data->sig = $this->util->calculateSigForPuller($this->appkey, $random, $curTime);
$data->time = $curTime;
$data->type = $type;
$data->max = $max;
return $this->util->sendCurlPost($wholeUrl, $data);
}
/**
* 拉取回执结果
*
* @param int $max 拉取最大条数,最多100
* @return string 应答json字符串,详细内容参见腾讯云协议文档
*/
public function pullCallback($max)
{
return $this->pull(0, $max);
}
/**
* 拉取回复信息
*
* @param int $max 拉取最大条数,最多100
* @return string 应答json字符串,详细内容参见腾讯云协议文档
*/
public function pullReply($max)
{
return $this->pull(1, $max);
}
}
+71
View File
@@ -0,0 +1,71 @@
<?php
namespace addons\qcloudsms\library;
use addons\qcloudsms\library\SmsSenderUtil;
/**
* 发送语音通知类
*
*/
class SmsVoicePromptSender
{
private $url;
private $appid;
private $appkey;
private $util;
/**
* 构造函数
*
* @param string $appid sdkappid
* @param string $appkey sdkappid对应的appkey
*/
public function __construct($appid, $appkey)
{
$this->url = "https://yun.tim.qq.com/v5/tlsvoicesvr/sendvoiceprompt";
$this->appid = $appid;
$this->appkey = $appkey;
$this->util = new SmsSenderUtil();
}
/**
*
* 发送语音通知
*
* @param string $nationCode 国家码,如 86 为中国
* @param string $phoneNumber 不带国家码的手机号
* @param string $prompttype 语音类型,目前固定为2
* @param string $msg 信息内容,必须与申请的模板格式一致,否则将返回错误
* @param string $playtimes 播放次数,可选,最多3次,默认2次
* @param string $ext 用户的session内容,服务端原样返回,可选字段,不需要可填空串
* @return string 应答json字符串,详细内容参见腾讯云协议文档
*/
public function send($nationCode, $phoneNumber, $prompttype, $msg, $playtimes = 2, $ext = "")
{
$random = $this->util->getRandom();
$curTime = time();
$wholeUrl = $this->url . "?sdkappid=" . $this->appid . "&random=" . $random;
// 按照协议组织 post 包体
$data = new \stdClass();
$tel = new \stdClass();
$tel->nationcode = "".$nationCode;
$tel->mobile = "".$phoneNumber;
$data->tel = $tel;
// 通知内容,utf8编码,支持中文英文、数字及组合,需要和语音内容模版相匹配
$data->promptfile = $msg;
// 固定值 2
$data->prompttype = $prompttype;
$data->playtimes = $playtimes;
// app凭证
$data->sig = hash("sha256",
"appkey=".$this->appkey."&random=".$random."&time="
.$curTime."&mobile=".$phoneNumber, FALSE);
// unix时间戳,请求发起时间,如果和系统时间相差超过10分钟则会返回失败
$data->time = $curTime;
$data->ext = $ext;
return $this->util->sendCurlPost($wholeUrl, $data);
}
}
+67
View File
@@ -0,0 +1,67 @@
<?php
namespace addons\qcloudsms\library;
use addons\qcloudsms\library\SmsSenderUtil;
/**
* 发送语音验证码类
*
*/
class SmsVoiceVerifyCodeSender
{
private $url;
private $appid;
private $appkey;
private $util;
/**
* 构造函数
*
* @param string $appid sdkappid
* @param string $appkey sdkappid对应的appkey
*/
public function __construct($appid, $appkey)
{
$this->url = "https://yun.tim.qq.com/v5/tlsvoicesvr/sendvoice";
$this->appid = $appid;
$this->appkey = $appkey;
$this->util = new SmsSenderUtil();
}
/**
* 发送语音验证码
*
* @param string $nationCode 国家码,如 86 为中国
* @param string $phoneNumber 不带国家码的手机号
* @param string $msg 信息内容,必须与申请的模板格式一致,否则将返回错误
* @param int $playtimes 播放次数,可选,最多3次,默认2次
* @param string $ext 用户的session内容,服务端原样返回,可选字段,不需要可填空串
* @return string 应答json字符串,详细内容参见腾讯云协议文档
*/
public function send($nationCode, $phoneNumber, $msg, $playtimes = 2, $ext = "")
{
$random = $this->util->getRandom();
$curTime = time();
$wholeUrl = $this->url . "?sdkappid=" . $this->appid . "&random=" . $random;
// 按照协议组织 post 包体
$data = new \stdClass();
$tel = new \stdClass();
$tel->nationcode = "".$nationCode;
$tel->mobile = "".$phoneNumber;
$data->tel = $tel;
$data->msg = $msg;
$data->playtimes = $playtimes;
// app凭证
$data->sig = hash("sha256",
"appkey=".$this->appkey."&random=".$random."&time="
.$curTime."&mobile=".$phoneNumber, FALSE);
// unix时间戳,请求发起时间,如果和系统时间相差超过10分钟则会返回失败
$data->time = $curTime;
$data->ext = $ext;
return $this->util->sendCurlPost($wholeUrl, $data);
}
}
+77
View File
@@ -0,0 +1,77 @@
<?php
namespace addons\qcloudsms\library;
use addons\qcloudsms\library\SmsSenderUtil;
/**
* 指定模板发送语音通知类
*
*/
class TtsVoiceSender
{
private $url;
private $appid;
private $appkey;
private $util;
/**
* 构造函数
*
* @param string $appid sdkappid
* @param string $appkey sdkappid对应的appkey
*/
public function __construct($appid, $appkey)
{
$this->url = "https://cloud.tim.qq.com/v5/tlsvoicesvr/sendtvoice";
$this->appid = $appid;
$this->appkey = $appkey;
$this->util = new SmsSenderUtil();
}
/**
*
* 指定模板发送语音短信
*
* @param string $nationCode 国家码,如 86 为中国
* @param string $phoneNumber 不带国家码的手机号
* @param int $templId 模板 id
* @param array $params 模板参数列表,如模板 {1}...{2}...{3},需要带三个参数
* @param string $playtimes 播放次数,可选,最多3次,默认2次
* @param string $ext 用户的session内容,服务端原样返回,可选字段,不需要可填空串
* @return string 应答json字符串,详细内容参见腾讯云协议文档
*/
public function send($nationCode, $phoneNumber, $templId, $params, $playtimes = 2, $ext = "")
{
/*var_dump($nationCode);
var_dump($phoneNumber);
var_dump($templId);
var_dump($params);
var_dump($playtimes);
exit();*/
$random = $this->util->getRandom();
$curTime = time();
$wholeUrl = $this->url . "?sdkappid=" . $this->appid . "&random=" . $random;
// 按照协议组织 post 包体
$data = new \stdClass();
$tel = new \stdClass();
$tel->nationcode = "".$nationCode;
$tel->mobile = "".$phoneNumber;
$data->tel = $tel;
$data->tpl_id = $templId;
$data->params = $params;
$data->playtimes = $playtimes;
// app凭证
$data->sig = $this->util->calculateSig($this->appkey, $random,
$curTime, array($phoneNumber));
// unix时间戳,请求发起时间,如果和系统时间相差超过10分钟则会返回失败
$data->time = $curTime;
$data->ext = $ext;
//var_dump($data);exit();
return $this->util->sendCurlPost($wholeUrl, $data);
}
}