uniapp小程序订阅消息推送+Thinkphp5后端代码教程示例

news2024/12/25 9:09:32

记录一下通过uniapp开发小程序消息推送的实例,配合后端tp推送,之前写的项目是微信小程序而且后端是原生php,这次通过项目记录一下

在这里插入图片描述

目录

  • 回顾
    • access_token获取规则以及思路
  • 第一步:设计前端触发订阅事件
  • 第二步:设计将token存入redis并到期触发
  • 第三步:编写订阅消息推送代码

回顾

首先我们通过原生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 = 'obwuk5R-Jy04LO1xDGFAd7EKRd0o';//用户openid
        $template_id = 'vrGIn55_mYjwQmTGqL27fyYZNNO7wGHdVv4QpA_K1t0';//所需下发的订阅模板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过期");
          }
    }
    }

本次教程到此结束,如果排版有问题,不易看懂,请私信或者评论区留言,希望文章对你有用!!!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/645114.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

1140道Java常见面试题及详细答案

最近感慨面试难的人越来越多了&#xff0c;一方面是市场环境&#xff0c;更重要的一方面是企业对 Java 的人才要求越来越高了。 基本上这样感慨的分为两类人&#xff1a; 第一&#xff0c;虽然挂着 3、5 年经验&#xff0c;但肚子里货少&#xff0c;也没啥拿得出手的项目&#…

OPNET出现“Packet pointer references unowned packet(<pk_id>)”错误的解决办法

在使用 OPNET Modeler 软件时&#xff0c;会遇到很多奇奇怪怪的报错&#xff0c;今天要介绍的报错内容如下。 Packet pointer references unowned packet(<pk_id>). 程序中断的原因截图如下图所示。 由上图可以看到&#xff0c;引发错误的 OPNET 核心函数是 op_pk_send(…

快速幂应用之剪绳子问题

有这样一类问题&#xff0c;给你一个长度为n的绳子&#xff0c;要求你可以剪切任意次数&#xff0c;分为任意段&#xff0c;使得这些子段长度的乘积最大。我们把这类问题暂时先称为剪绳子&#xff0c;这种问题的解法也很简单&#xff0c;通过数学证明可以得出&#xff0c;我们优…

​Java容器的继承关系​

Java容器的继承关系 Collection接口 Collection接口中所定义的方法 int size(); boolean isEmpty(); void clear(); boolean contains(Object element);//是否包含某个对象 boolean add(Object element); Iterator iterator(); boolean containsAll(Collection c);//是否包含另…

MybatisPlus 实现数据拦截

基于配置文件实现&#xff08;关键key存储在配置文件&#xff0c;通过读取配置文件来实现动态拼接sql&#xff09; 1、创建注解类 UserDataPermission(id"app") 注&#xff1a;id用以区分是小程序还是应用程序 注解加的位置&#xff1a; 2、配置枚举类配置文件 E…

学了Python后还用学R语言吗?

学习R语言是否有必要取决于你的具体需求和背景。虽然R语言和Python都是数据科学领域广泛使用的编程语言&#xff0c;但它们之间还是存在一些差异。 如果你主要从事数据分析、统计建模或者数据可视化等工作&#xff0c;那么学习R语言可能更为适合。R语言在数据处理和统计分析方…

【gcc, cmake, eigen, opencv,ubuntu】四.opencv安装和使用,获取opencv matiax 的指针

文章目录 ubuntu系统安装opencv1.下载opencv和opencv_contrib2.安装指导3.Linux 下 fatal error: opencv2/opencv.hpp: 没有那个文件或目录4.g 和cmake 编译使用opencv的程序5.opencv,eigen速度比较6.opencv常用类型符号7.获取opencv matiax 的指针 ubuntu系统安装opencv 1.下…

Java实训日志03

文章目录 八、项目开发实现步骤&#xff08;五&#xff09;创建数据库连接管理类1、创建数据库实用工具包2、创建数据库连接管理类&#xff08;1&#xff09;定义数据库连接属性常量&#xff08;2&#xff09;创建私有化构造方法&#xff08;3&#xff09;编写获取数据库连接静…

关于C++数组名和指针的一些思考

在学习指针数组与数组指针一节时&#xff0c;了解到数组名其实是指向数组收个元素的指针。如下面代码所示 int main() {int a[5] {1, 2, 3, 4, 5};cout << "*a:" << *a << endl;cout << "*(a 1):" << *(a 1) << e…

注解开发bean

注解开发定义bean 使用component定义bean Component("bookDao") public class BookDaoImpl implements BookDao{} 核心配置文件中通过组件扫描加载bean <context:component-scan base-package"com.tsj"/> Spring提供Component注解的三个衍生注解…

科研人必看 | 学术期刊论文作者署名新规

【SciencePub学术干货】在期刊上发表学术论文&#xff0c;是研究人员发布和传播学术研究成果的重要方式之一。学术期刊论文文献各项著录内容中&#xff0c;作者署名是最主要的组成部分之一。 随着经济的发展和社会的进步&#xff0c;人们面临的科学问题和社会问题日趋复杂&…

KaiwuDB 受邀亮相 IOTE 2023 第十九届国际物联网展

5月17日&#xff0c;IOTE 2023 第十九届国际物联网展在上海拉开序幕&#xff0c;全球超过 350 家参展企业到场展示先进的物联网技术和产品&#xff0c;行业专家、领军企业代表等人物齐聚一堂&#xff0c;共话 IoT 未来趋势。KaiwuDB 受邀亮相参展并就《工业物联网产业数字化转型…

基于SpringBoot+vue的网上图书商城系统设计和实现

博主介绍&#xff1a; 大家好&#xff0c;我是一名在Java圈混迹十余年的程序员&#xff0c;精通Java编程语言&#xff0c;同时也熟练掌握微信小程序、Python和Android等技术&#xff0c;能够为大家提供全方位的技术支持和交流。 我擅长在JavaWeb、SSH、SSM、SpringBoot等框架下…

通用方案px2rem 处理 内联样式、element-ui表头折行、label折行、表单项换行异常

通用方案-处理element-ui 表单项label折行、换行异常&#xff0c;表头折行问题 背景简介&#xff1a;在实际的生产环境中&#xff0c;客户用到的屏幕大大小小分辨率各有异同&#xff0c;但是为了布局的统一和美观&#xff0c;我们采用了postcss-px2rem插件对element-ui进行响应…

仓库拣货标签——仓库16代

6432 全彩 LED 点阵显示屏 ​ 一、产品特性 采用2048 RGB LED全彩显示&#xff0c;亮度可调 无线通信 它可以显示文本、图片或动画 支持24V外置电源 支持系统对接&#xff0c;模板可DIY 二、PTL系统电子标签概述 电子标签拣选系统是利用先进的电子技术和通信技术开发的物…

选择合适的采购系统,实现企业数字化转型

随着数字化技术的飞速发展&#xff0c;企业数字化转型已经成为了当今市场的必然趋势。而采购系统作为企业数字化转型的重要组成部分&#xff0c;选择合适的采购系统对于企业来说至关重要。本文将围绕选择合适的采购系统&#xff0c;实现企业数字化转型展开讨论。 一、企业数字化…

数字门户的创新引擎:小程序容器

小程序容器技术的发展为数字门户带来了许多机会和优势。通过引入第三方生态&#xff0c;数字门户可以快速丰富自身的功能和服务&#xff0c;提高用户留存率&#xff0c;并打造一个开放的生态系统。这种创新的技术手段让数字门户能够更灵活地满足用户多样化的需求&#xff0c;提…

强化学习复现笔记(2)策略迭代

摘要&#xff1a; 上一节的压缩映射在实际迭代时可以分成两种方法&#xff0c;分别称作值迭代和策略迭代。本文用走迷宫的例子&#xff08;将1维迷宫扩展到2维&#xff09;讲这两种迭代。对应第一节参考链接[2]的前4章。 拆分压缩映射 上一节的压缩映射 v f ( v ) vf(v) vf(…

打造科学新高地|2023开放原子全球开源峰会科学智能分论坛圆满举行

6 月 11 日&#xff0c;以“AI 框架助力科学智能&#xff0c;打造科学新高地”为主题的 2023 开放原子全球开源峰会科学智能分论坛在北京圆满举行。北京航空航天大学计算机学院党委书记、教授李建欣参加并致辞&#xff1b;华为昇思 MindSpore 架构师倪宁曦、研究员徐旭升&#…

const用于C++引用(注意事项)

const用于C引用 存在的问题解决方法原理 存在的问题 左值是可以被引用的数据对象&#xff0c;可以通过地址访问它们&#xff0c;例如&#xff1a;变量、数组元素、结构体成员、引用和解引用的指针。 非左值包括字面常量&#xff08;用双引号包含的字符串除外&#xff09;和包含…