• 公众号一次性订阅消息


    洛塔服务号回复007获取代码。

    功能说明

    之前发布通知,要用订阅通知替代一次性订阅消息,不知道是被骂的太惨还是技术原因,一次性订阅消息还是一直能用。

    和模板消息不同的是,一次性订阅消息无需用户关注公众号,但是必须用户点击同意发送才能接收消息。

    • 模板消息:需要关注公众号,无需用户同意也可发送
    • 一次性订阅消息:无需关注公众号,需要用户同意才能发送
      如果用户关注了公众号,那么消息就在公众号里发送。如果没有关系,消息就在服务通知里。

    准备工作

    • 公众号后台设置ip白名单
      位置:设置与开发–>基本配置,右侧IP白名单
      将域名能够访问的服务器ip地址添加进去

    • 获取模板id
      此处的模板id和模板消息的完全不同,每个公众号都有固定值。
      模板Id位置:设置与开发–>接口权限,右侧一次性订阅消息,点击查看模板id

    • 设置业务域名
      设置位置:设置与开发–>公众号设置–>右侧功能设置,点击 业务域名 后面的设置。
      此处需要下载文件,然后部署到服务器访问根目录中,即可成功保存。可以直接用nginx或者tomcat的ROOT中,80端口访问。

    生成授权链接

    我最终的授权链接是:https://mp.weixin.qq.com/mp/subscribemsg?action=get_confirm&appid=wx276049d6a7551dca&scene=1000&template_id=FHIXqn7zsGh_CECK7oIfKAVdQFHzAInncglc6wctAWg&redirect_url=http://test.lootaa.com/lootaa-wechat/wx7&reserved=lootaatest7#wechat_redirect

    各个参数含义

    • action:固定值,用get_confirm
    • appid:公众号的appid
    • scene:场景值,0-10000任一数值,相同场景多次订阅就算一次
    • template_id:上面刚刚写到的获取模板Id
    • redirect_url:对应后台接收订阅跳转的路径,下面会介绍。必须是业务域名+后缀
    • reserved:防攻击用的,会原样返回给上面的路径中
    • wechat_redirect:必须都加上#wechat_redirect

    redirect_url对应方法

    后台使用springboot来开发,nginx做端口转发。
    nginx配置:

            location /lootaa-wechat/ {
                    proxy_pass http://127.0.0.1:2022/lootaa-wechat/;
                    proxy_set_header  X-Real-IP  $remote_addr;
                    proxy_set_header Host $host;
            }
    

    application.properties配置

    server.port=2022
    server.servlet.context-path=/lootaa-wechat
    

    对应的controller添加注解@RestController,方法添加注解@GetMapping

    • 可以根据接收到的参数做自身业务处理,本篇只做了打印操作
    • 发送一次性订阅消息也放到了接收代码中,真实业务肯定是在其他地方的,根据业务场景再调用发送消息
    • 返回值使用了response形式,订阅成功或者识别均可设置跳转页面
    • 发送订阅消息的参数与模板消息的比较类似,但是又不完全一样,避免直接复制出问题。
    package com.lootaa.wechat;
    
    import java.util.Objects;
    
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    import org.jsoup.Connection.Method;
    import org.jsoup.Jsoup;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    import com.alibaba.fastjson.JSON;
    import com.alibaba.fastjson.JSONObject;
    
    /**
     * 一次性订阅
     * 前置条件:公众号后台设置ip白名单;获取到了模板id;设置了业务域名
     * 入口链接:https://mp.weixin.qq.com/mp/subscribemsg?action=get_confirm&appid=wx276049d6a7551dca&scene=1000&template_id=FHIXqn7zsGh_CECK7oIfKAVdQFHzAInncglc6wctAWg&redirect_url=http://test.lootaa.com/lootaa-wechat/wx7&reserved=lootaatest7#wechat_redirect
     */
    @RestController
    public class Test007 {
    
    	public static final String APPID = "wx276049d6a7551dca";
    	public static final String SECRET = "cbe109fdf6f399bd72ed3a4afafa21b1";
    	
    	@GetMapping("wx7")
    	public void wxGet(HttpServletRequest request, HttpServletResponse response) throws Exception {
    		String openid = request.getParameter("openid"); //用户唯一标识,只在用户确认授权时才会带上
    		String templateId = request.getParameter("template_id"); //订阅消息模板ID
    		String action = request.getParameter("action"); //用户点击动作,"confirm"代表用户确认授权,"cancel"代表用户取消授权
    		String scene = request.getParameter("scene"); //订阅场景值
    		String reserved = request.getParameter("reserved"); //请求带入原样返回
    		System.out.println(openid);
    		System.out.println(templateId);
    		System.out.println(action);
    		System.out.println(scene);
    		System.out.println(reserved);
    		if(Objects.equals(action, "cancel")) { //取消授权
    			response.sendRedirect("https://blog.csdn.net/m0_58095675");
    			return;
    		}
    		
    		// 发送订阅消息,这部分可以放到其他任何地方,跳转适合的时机再发送。测试方便就直接发送了
    		// 先获取access_token,这部分正式环境需要配置定时获取,每天2000次调用限制
    		String url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=" + APPID + "&secret=" + SECRET;
    		String result = Jsoup.connect(url).ignoreContentType(true).method(Method.GET).execute().body();
    		System.out.println(result);
    		String accessToken = JSON.parseObject(result).getString("access_token");
    		// 发送模板消息
    		url = "https://api.weixin.qq.com/cgi-bin/message/template/subscribe?access_token=" + accessToken;
    		JSONObject param = new JSONObject();
    		param.put("touser", "ohUHp6iaFJq6SISTVwHS5lkb9Pb8"); //接收人的openid
    		param.put("template_id", templateId);
    		param.put("url", "https://blog.csdn.net/m0_58095675"); //非必填,点击后跳转的页面
    		param.put("scene", scene); 
    		param.put("title", "15字以内消息标题"); 
    		// 如果要调整小程序需要下面这个,非必填
    		JSONObject miniprogram = new JSONObject(); 
    		miniprogram.put("appid", "wxa3b096d8546b270d"); //小程序的appid
    		miniprogram.put("pagepath", "pages/station/station"); //不填就是默认首页,这个可以带参数
    		param.put("miniprogram", miniprogram); 
    		// 数据参数
    		JSONObject data = new JSONObject();
    		JSONObject content = new JSONObject();
    		content.put("value", "一次性订阅消息值");
    		content.put("color", "#666666"); //文字颜色
    		data.put("content", content);
    		param.put("data", data);
    		result = Jsoup.connect(url).ignoreContentType(true).method(Method.POST).requestBody(param.toString()).execute().body();
    		System.out.println(result);
    		
    		// 确认授权后跳转的目的展示页面
    		response.sendRedirect("https://blog.csdn.net/m0_58095675");
    			
    	}
    	
    }
    
    

    执行效果

    分别为确认授权、公众号收到订阅消息(已关注了公众号)、服务通知收到订阅消息(没有关注公众号)
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

  • 相关阅读:
    Linux内核调试工具——devmem
    【springboot&neo4j】版本差异对比
    浅谈线性基
    2022年上半年网络工程师上午真题及答案
    wpf C# 用USB虚拟串口最高速下载大文件 每包400万字节 平均0.7s/M,支持批量多设备同时下载。自动识别串口。源码示例可自由定制。
    Eureka-server集群都挂了,微服务之间还能调通吗
    java和vue视频点播系统视频弹幕系统
    Hexagon_V65_Programmers_Reference_Manual(46)
    力扣 26. 删除有序数组中的重复项
    解决JAVA对象属性首字母大写无法映射值
  • 原文地址:https://blog.csdn.net/m0_58095675/article/details/127109177