回顾
首先我们通过原生php代码回顾一下,不考虑模板参数的话,主要就是“touser
”和“ACCESS_TOKEN
”
notify.php <?php // 微信小程序通知主要函数 //http_request 利用curl请求 两个参数 url连接地址 数据信息 function http_request($url,$data){ $ch = curl_init();//初始化 curl_setopt($ch, CURLOPT_URL, $url);//设置 curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE); curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE); curl_setopt($ch, CURLOPT_POST, 1); curl_setopt($ch, CURLOPT_POSTFIELDS, $data); $output = curl_exec($ch);//执行 curl_close($ch);//关闭 return $output;//返回结果 } //封装方法 //签到 function notify_sign($touser,$ACCESS_TOKEN) { $template=array( 'touser'=>"$touser",//接收方openid 'template_id'=>"6io5lFLo4OEdNjl2_FKxHErBqXv3EF1QRZEm6RMdHLQ", //模板的id 'page'=>"pages/jifen/jifen",//点击小程序订阅消息跳转的页 'data'=>array( // 'character_string1'=>array('value'=>"$out_trade_no",'color'=>"#00008B"), 'thing1'=>array('value'=>"积分签到提醒",'color'=>'#00008B'), // 'amount4'=>array('value'=>"15",'color'=>'#00008B'), 'thing2'=>array('value'=>"签到获得10积分",'color'=>'#00008B'), 'thing5'=>array('value'=>"点击立即签到",'color'=>'#00008B'), 'phrase6'=>array('value'=>"你还未签到",'color'=>'#00008B') ) // 'phrase1'=>array('value'=>urlencode($plan),'color'=>'#00008B'), //时间 ); $json_template=json_encode($template); $url="https://api.weixin.qq.com/cgi-bin/message/subscribe/send?access_token=".$ACCESS_TOKEN; $res=http_request($url,urldecode($json_template)); print_r($res); } ?>
push.php <?php //签到通知 header("Content-type:text/html;charset=utf-8");//字符编码设置 //通知 include 'notify.php';//引用通知模板文件 ini_set('session.save_handler', 'redis'); ini_set('session.save_path', 'tcp://127.0.0.1:6379'); $redis = new redis(); $redis->connect('127.0.0.1', 6379); $redius_token=$redis->get('wx_token');//鉴权 // $name=mb_substr($name,0,10,'utf-8'); // notify_sign("o8oTs5AwK3Roma4mwtj6oNE7BIbk",$redius_token,$name); //通知签到 include '../../conn.php'; $sql="SELECT openid FROM `user`"; $res=$conn->query($sql); while($rowss=$res->fetch_assoc()){ $openid=$rowss['openid']; notify_sign("$openid",$redius_token); }
上述代码大概就是基本流程,我们再看一下,官方的参数字段
access_token获取规则以及思路
微信希望我们存在自己的服务器里面,过期就换,不提倡每次都刷新使用新的
,否则可能会覆盖之前业务或导致失效,ok思路基本清楚了,开始干活了。
第一步:设计前端触发订阅事件
进入到小程序后台找到自己创建的订阅消息模板,复制订阅模板id
在合适的地方放入事件即可
uni.requestSubscribeMessage({ tmplIds: ['vrGIn55_mYjwQmTGqL27fyYZNNO7wGHdVv4QpA_K1t0'], success (res) { //that.$token.toast('订阅成功!等待书审结果',1000) } })
通过真机活着体验版访问授权一次,请注意长期订阅消息和一次性订阅消息不一样
,我们所使用的基本都是一次性,长期只能用于特殊单位使用,所以订阅一次就能收到一次,如果想让用户多次订阅建议放在几个用户必点区域
第二步:设计将token存入redis并到期触发
我个人不建议通过定时计划设置到期时间,不方便下次部署,我的建议
是:
直接将代码存放到触发请求的目标位置,每次调用都会检查一下redis中是否存在access_token没有的话重新获取并存入,有的话用就可以
通过curl获取到用access_token,以下是获取到的格式,我们将7200作为实效时间存入
获取access_token(填入自己的appid和secret)
$url = 'https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=w******be&secret=6a*************6'; $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); $response = curl_exec($ch); curl_close($ch); $data = json_decode(trim($response),true);
redis设置
将返回值与过期时间存入redis中让他自动到期
$Redis=new Redis(); $Redis->set('uniapp_demo_access_token',$data['access_token'],$data['expires_in']);
代码写好了,测试一下
访问接口
查看redis记录值,包含到期时间和记录值
再次访问接口,由于记录值存在,并不会重新去获取access_token,而是用现在未到期的access_token
附上该部分完整代码
(使用时需要加上 use think\cache\driver\Redis;使用时替换 ******部分即可)
//http://code.taila.club/index.php/index/api/send_notify // 测试订阅消息接口,后期移入admin控制器 public function send_notify(){ $token=input('token'); $redis = new Redis(); $result= $redis->get($token); if ($result){ $re= $redis->get("uniapp_demo_access_token"); if ($re) { // 存在记录 echo($re); } else { $url = 'https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=w*************e&secret=6*********************6'; $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); $response = curl_exec($ch); curl_close($ch); $data = json_decode(trim($response),true); echo( json_encode( array( 'code' => 200, 'data'=>$data, 'msg' => 'token获取成功' ),480) ); //access_token过期 $Redis=new Redis(); $Redis->set('uniapp_demo_access_token',$data['access_token'],$data['expires_in']); } } else{ die("token过期"); } }
第三步:编写订阅消息推送代码
public function sendMessage() { $touser = 'o**********o';//用户openid $template_id = 'v*********0';//所需下发的订阅模板id $page = '/pages/index/index';//跳转页面不填则模板无跳转。 $redis = new Redis(); $re= $redis->get("uniapp_demo_access_token"); $access_token = $re; //请求url $url = 'https://api.weixin.qq.com/cgi-bin/message/subscribe/send?access_token=' . $access_token; //发送内容 $data = []; //接收者(用户)的 openid $data['touser'] = $touser; //所需下发的订阅模板id $data['template_id'] = $template_id; //点击模板卡片后的跳转页面,仅限本小程序内的页面。支持带参数,(示例index?foo=bar)。该字段不填则模板无跳转。 $data['page'] = $page; //模板内容,格式形如 { "key1": { "value": any }, "key2": { "value": any } } $data['data'] = [ "thing1" => [ 'value' => '测试' ], "phrase3" => [ 'value' =>'大魔王' ], ]; //跳转小程序类型:developer为开发版;trial为体验版;formal为正式版;默认为正式版 $data['miniprogram_state'] = 'developer' ; return self::curlPost($url,json_encode($data)) ; } //发送post请求 static function curlPost($url,$data) { $ch = curl_init(); $params[CURLOPT_URL] = $url; //请求url地址 $params[CURLOPT_HEADER] = FALSE; //是否返回响应头信息 $params[CURLOPT_SSL_VERIFYPEER] = false; $params[CURLOPT_SSL_VERIFYHOST] = false; $params[CURLOPT_RETURNTRANSFER] = true; //是否将结果返回 $params[CURLOPT_POST] = true; $params[CURLOPT_POSTFIELDS] = $data; curl_setopt_array($ch, $params); //传入curl参数 $content = curl_exec($ch); //执行 curl_close($ch); //关闭连接 return $content; }
上述代码中,已经去掉appid等参数
,因为我们已经配置好了,已经将access_token记录到redis中去了,所以不再需要,只需要配置openid也就是touser还有对应的模板id,以及模板的参数即可,我们现在针对上述代码做一个解释
首先,将代码写入到控制器中,更改touser为自己的openid,方便自己做接收测试
$touser = 'obwu*********0o';//用户openid
第二步,登录小程序后台找到自己设置的模板id
$template_id = 'vr***********0';//所需下发的订阅模板id
第三步,选择点击跳转的页面
$page = '/pages/index/index';//跳转页面不填则模板无跳转。
第四步,接收redis中的access_token
$redis = new Redis(); $re= $redis->get("uniapp_demo_access_token"); $access_token = $re;
第五步,配置模板内容
根据自己的内容设置对应的参数,注意参数有类型和长度要求
,具体看这里
//模板内容,格式形如 { "key1": { "value": any }, "key2": { "value": any } } $data['data'] = [ "thing1" => [ 'value' => '测试' ], "phrase3" => [ 'value' =>'大魔王' ], ];
第六步,访问测试
可以看到,消息已经推送过来了
这里我是新建了一个方法,因为只是测试使用,所以没将代码完整的封装然后调用,这样的话对于新手比较容易理解,也能自己修改成自己的业务逻辑,另外redis的记录名可以自己更改我这里为了演示随意起的
后端完整代码:
ApiController.php <?php namespace app\index\controller; use think\Controller; use think\Db; use think\cache\driver\Redis; class ApiController extends Controller { public function sendMessage() { $touser = 'o**********o';//用户openid $template_id = 'vr**********1t0';//所需下发的订阅模板id $page = '/pages/index/index';//跳转页面不填则模板无跳转。 $redis = new Redis(); $re= $redis->get("uniapp_demo_access_token"); $access_token = $re; //请求url $url = 'https://api.weixin.qq.com/cgi-bin/message/subscribe/send?access_token=' . $access_token; //发送内容 $data = []; //接收者(用户)的 openid $data['touser'] = $touser; //所需下发的订阅模板id $data['template_id'] = $template_id; //点击模板卡片后的跳转页面,仅限本小程序内的页面。支持带参数,(示例index?foo=bar)。该字段不填则模板无跳转。 $data['page'] = $page; //模板内容,格式形如 { "key1": { "value": any }, "key2": { "value": any } } $data['data'] = [ "thing1" => [ 'value' => '测试' ], "phrase3" => [ 'value' =>'大魔王' ], ]; //跳转小程序类型:developer为开发版;trial为体验版;formal为正式版;默认为正式版 $data['miniprogram_state'] = 'developer' ; return self::curlPost($url,json_encode($data)) ; } //发送post请求 static function curlPost($url,$data) { $ch = curl_init(); $params[CURLOPT_URL] = $url; //请求url地址 $params[CURLOPT_HEADER] = FALSE; //是否返回响应头信息 $params[CURLOPT_SSL_VERIFYPEER] = false; $params[CURLOPT_SSL_VERIFYHOST] = false; $params[CURLOPT_RETURNTRANSFER] = true; //是否将结果返回 $params[CURLOPT_POST] = true; $params[CURLOPT_POSTFIELDS] = $data; curl_setopt_array($ch, $params); //传入curl参数 $content = curl_exec($ch); //执行 curl_close($ch); //关闭连接 return $content; } //http://code.taila.club/index.php/index/api/send_notify // 测试订阅消息接口,后期移入admin控制器 public function send_notify(){ $token=input('token'); $redis = new Redis(); $result= $redis->get($token); if ($result){ $re= $redis->get("uniapp_demo_access_token"); if ($re) { // 存在记录 echo($re); } else { $url = 'https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=w**********e&secret=6**********6'; $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); $response = curl_exec($ch); curl_close($ch); $data = json_decode(trim($response),true); echo( json_encode( array( 'code' => 200, 'data'=>$data, 'msg' => 'token获取成功' ),480) ); //access_token过期 $Redis=new Redis(); $Redis->set('uniapp_demo_access_token',$data['access_token'],$data['expires_in']); } } else{ die("token过期"); } } }
本次教程到此结束,如果排版有问题,不易看懂,请私信或者评论区留言,希望文章对你有用!!!