精华内容
下载资源
问答
  • 注意,如果模板消息发信息时有时无,不稳定,可能你的access_token令牌更新缓存不及时,过期了.可以根据日志文件查看.建议300秒更新一下.否则会很烦. 模板id需要自己去公众号中设置行业后得到. <?php //使用方法....
  • 最近做项目时需要用到公众号模板消息,所以在这里记录分享一下实现过程 一、什么是模板消息 ↓↓↓↓ 官方文档 微信公众号提供了多种消息能力,这里我们主要讲得是模板消息,有需要其他消息实现方式的朋友可以...


    前言

    最近做项目时需要用到公众号的模板消息,所以在这里记录分享一下实现过程


    一、什么是模板消息

    ↓↓↓↓
    官方文档

    微信公众号提供了多种消息能力,这里我们主要讲得是模板消息,有需要其他消息实现方式的朋友可以留言,出其他实现文章。

    功能介绍
    模板消息仅用于公众号向用户发送重要的服务通知,只能用于符合其要求的服务场景中,如信用卡刷卡通知,商品购买成功通知等。不支持广告等营销类消息以及其它所有可能对用户造成骚扰的消息。

    关于使用规则,请注意:

    所有服务号都可以在功能->添加功能插件处看到申请模板消息功能的入口,但只有认证后的服务号才可以申请模板消息的使用权限并获得该权限;
    需要选择公众账号服务所处的2个行业,每月可更改1次所选行业;
    在所选择行业的模板库中选用已有的模板进行调用;
    每个账号可以同时使用25个模板。
    当前每个账号的模板消息的日调用上限为10万次,单个模板没有特殊限制。【2014年11月18日将接口调用频率从默认的日1万次提升为日10万次,可在MP登录后的开发者中心查看】。当账号粉丝数超过10W/100W/1000W时,模板消息的日调用上限会相应提升,以公众号MP后台开发者中心页面中标明的数字为准。

    关于接口文档,请注意:

    1. 模板消息调用时主要需要模板ID和模板中各参数的赋值内容;
    2. 模板中参数内容必须以".DATA"结尾,否则视为保留字;
    3. 模板保留符号""。

    在这里插入图片描述

    二、获取模板ID

    百度搜索微信公众平台
    在这里插入图片描述
    微信扫码登录
    在这里插入图片描述
    找到新的功能

    在这里插入图片描述

    点击未开通,找到模板消息,点击开通
    在这里插入图片描述

    点击已开通,找到模板消息,点击模板消息
    在这里插入图片描述
    点击查看功能
    在这里插入图片描述

    点击模板库,选择想要的模板
    在这里插入图片描述

    在我的模板中就可以看到选择的模板,看到模板ID,这就是我们开发要用的
    在这里插入图片描述

    注意!注意!注意!重要的事说三遍,如果你是用的是微信公众号测试平台发送消息模板可不配置公众号对接相关功能,直接使用openId 发送模板信息功能即可,openId 可让用户关注公众号录入系统,
    或者在公众号添加h5 表单,绑定系统账号, 微信打开的h5 页面可获取当前用户的openId。

    如果是真正的公众号就必须配置公众号对接相关功能!必须!必须!必须!

    三、获取access_token

    首先来看下access_token是什么,下图是官方给出的:
    在这里插入图片描述
    其实通俗的讲,access_token就是小程序官方给我们提供的一个凭证,你要调用小程序官方的接口,就必须先拿到access_token。这个和我们做的项目调用后台接口必须登录后台给你一个token你带token访问相似。

    看一下官方文档:
    在这里插入图片描述

    grant_type是一个固定的值,只有appid和secret是需要我们填入的,这两个值在我们的公众号后台就可以拿到。

    下面就是Java后台代码的编写了

    我这里用的是springboot,这里要请求公众号官方接口,正常项目开发我都是用的自己写的接口请求工具类的,这里为了大家方便就用了springboot自带的RestTemplate来做网络请求。文章最后我会把我自己写的这个请求工具类贴出来有需要的朋友可以copy,具体代码如下。

    代码如下(示例):
    在这里插入图片描述

    这里代码很简单,就一个简单的get请求。不过要注意一点,这里获取的access_token是有两个小时的过期时间的
    在这里插入图片描述
    所以在获取到access_token的时候,把access_token存到数据库,或者存到本地缓存,并且还要记录当前时间,后面再用的时候先判断这个access_token有没有超过2个小时,如果超过2个小时的话,就要重新获取了。
    在这里插入图片描述

    四、发送消息

    官方文档

    老规矩还是先看官方文档
    在这里插入图片描述
    在这里插入图片描述

    上面的参数都是我们发送消息时需要的。

    然后微信就收到了
    在这里插入图片描述

    五、完整的代码

    1. 获取access_token
    @Data
    public class AccessToken {
    
        private String accessToken;
        //过期时间 当前系统时间+微信传来的过期时间
        private Long expiresTime;
    
        public AccessToken(String accessToken, String expiresIn) {
            this.accessToken = accessToken;
            this.expiresTime = System.currentTimeMillis()+Integer.parseInt(expiresIn)*1000;
        }
    
        /**
         * 判断token是否过期
         * @return
         */
        public boolean isExpired(){
            return System.currentTimeMillis()>expiresTime;
        }
    }
    

    下面的WX_OPEN_APP_ID,WX_OPEN_APP_SECRET替换成你们自己的,具体的可以去公众号后台查看

    public static final BASE_ACCESS_TOKEN_URL = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential" +
                "&appid=%s" +
                "&secret=%s";
    
     private static AccessToken at;
    
        public static String getToken(){
            if (at == null || at.isExpired()){
                getAccessToken();
            }
            return at.getAccessToken();
        }
    
        /**
         * 获取token
         */
        private static void getAccessToken() {
            String accessTokenUrl = String.format(
                    BASE_ACCESS_TOKEN_URL,
                    WX_OPEN_APP_ID,
                    WX_OPEN_APP_SECRET
            );
    
            //发送请求获取token
            String token = null;
            try {
                token = HttpClientUtils.get(accessTokenUrl);
            } catch (Exception e) {
                e.printStackTrace();
            }
            JSONObject jsonObject = JSONObject.parseObject(token);
            String accessToken = (String) jsonObject.get("access_token");
            Integer expiresIn = (Integer) jsonObject.get("expires_in");
            //创建token对象,并存储
            at = new AccessToken(accessToken,String.valueOf(expiresIn));
            System.out.println(token);
    
        }
    
    
    1. 发送消息
    public static final SEND_URL  = "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=ACCESS_TOKEN";
    
     /**
         * 1、发送模版消息-拼接数据(测试信息)
         * @param openId 微信用户的openId
         */
        public static String sendMessage(String openId, String templateId,String machineAlias,String shopName,String openStatus, String dropStatus,int number) {
                // 模板参数
                Map<String, WeChatTemplateMsg> sendMag = new HashMap<String, WeChatTemplateMsg>();
                String content = "店铺:"+shopName+",机器别名:"+machineAlias+",当前库存:"+number;
                sendMag.put("first", new WeChatTemplateMsg("请注意!"));
                sendMag.put("system", new WeChatTemplateMsg(content));
                sendMag.put("time", new WeChatTemplateMsg(DateUtils.getCurrDateTime()));
                sendMag.put("account", new WeChatTemplateMsg("1"));
                sendMag.put("remark", new WeChatTemplateMsg("请尽快补货,谢谢!"));
                // 发送
                String send = send(openId, templateId, sendMag);
                return send;
           
        }
    
    
        /**
         * 2、发送模版消息
         * openId     用户Id
         * templateId 模板Id   
         * data       模板参数
         * @param data
         */
        private static String send(String openId, String templateId, Map<String, WeChatTemplateMsg> data) {
            RestTemplate restTemplate = new RestTemplate();
            String accessToken = getToken();
            String url = SEND_URL.replace("ACCESS_TOKEN", accessToken);
            //拼接base参数
            Map<String, Object> sendBody = new HashMap<>();
            sendBody.put("touser", openId);               // openId
    //        sendBody.put("url", "www.baidu.com");         // 点击模板信息跳转地址
            sendBody.put("topcolor", "#FF0000");          // 顶色
            sendBody.put("data", data);                   // 模板参数
            sendBody.put("template_id", templateId);      // 模板Id
            ResponseEntity<String> forEntity = restTemplate.postForEntity(url, sendBody, String.class);
            return forEntity.getBody();
        }
    
    1. 消息封装实体类 (模板参数)
    @Data
    @ToString
    public class WeChatTemplateMsg {
        /**
         * 消息
         */
        private String value;
        /**
         * 消息颜色
         */
        private String color;
    
    
        public WeChatTemplateMsg(String value) {
            this.value = value;
            this.color = "#173177";
        }
    
        public WeChatTemplateMsg(String value, String color) {
            this.value = value;
            this.color = color;
        }
    }
    

    微信就能收到了
    在这里插入图片描述

    到这里我们就可以完整的实现Java发送公众号模板消息的功能了。完整代码也已经贴给大家了。

    总结

    以上就是今天要分享给大家的内容,本文简单的讲了怎么发送模板消息,其实大部分大家参考官方文档都是可以写出来的
    展开全文
  • (Java)微信公众号发送模板消息

    千次阅读 2019-07-18 16:14:14
    模板消息仅用于公众号向用户发送重要的服务通知,只能用于符合其要求的服务场景中,如信用卡刷卡通知,商品购买成功通知等。不支持广告等营销类消息以及其它所有可能对用户造成骚扰的消息。 1、模板消息调用时主要...

    模板消息仅用于公众号向用户发送重要的服务通知,只能用于符合其要求的服务场景中,如信用卡刷卡通知,商品购买成功通知等。不支持广告等营销类消息以及其它所有可能对用户造成骚扰的消息。

    1、模板消息调用时主要需要模板ID和模板中各参数的赋值内容;
    2、模板中参数内容必须以".DATA"结尾,否则视为保留字;
    3、模板保留符号"{{ }}"。

     Java项目里的实现方法:

    1、模板消息的模板内容组成有两种方式

    前台页面组装好传递到后台(eg:body):

    $.ajax({
    			type: "POST",//提交类型
    			url: "${pageContext.request.contextPath}/SendMs/sendTemplateMessages",
    			data: {
    		        body:JSON.stringify({
    		          touser: '接收消息用户的openId',
    		          template_id: '模板消息的模板Id',
    		          data: {
    		              'first': {
    		                  'value': '您的订单通知>_<',
    		                  'color': '#173177'
    		                },
    		                'keyword1': {
    		                  'value': '1001001010',
    		                  'color': '#173177'
    		                },
    		                'keyword2': {
    		                  'value': '蛋炒饭不加蛋',
    		                  'color': '#173177'
    		                },
    		                'keyword3': {
    			                  'value': '10¥',
    			                  'color': '#173177'
    			                },
    		                'remark': {
    		                  'value': '感谢您的光顾,祝您生活愉快!*_*',
    		                  'color': '#173177'
    		                }
    		              }
    		        })
    		      },
    	      dataType:"json",
    		  success: function(m){	
    		  }
    	   });

     前台没有传模板消息,则后台自己组装 (eg:wechatTemplateStr):

     注:JSONArray将类转换成模板消息字符串,转换之后会有一个中括号,需要用replace方法将中括号去掉才是模板消息的正确格式,不然调微信的发送模板消息接口会报格式不正确错误。(切记)

                //前台没有传模板消息内容,则后台自己组装 eg:wechatTemplateStr
                WechatTemplate wechatTemplate = new WechatTemplate();
                wechatTemplate.setTemplate_id(AlipayController.template_id);
                wechatTemplate.setTouser("oifR00Qa_h9TawBbnXa3S54mEpew");
                Map<String,TemplateData> mapdata = new HashMap<>();
                // 封装模板数据
                TemplateData first = new TemplateData();
                first.setValue(AlipayController.templateHead);
                first.setColor("#173177");
                mapdata.put("first", first);
             
                TemplateData keyword1 = new TemplateData();
                keyword1.setValue(orderNumber);
                keyword1.setColor("#173177");
                mapdata.put("keyword1", keyword1);
             
                TemplateData keyword2 = new TemplateData();
                keyword2.setValue(commodityDetails);
                keyword2.setColor("#173177");
                mapdata.put("keyword2", keyword2);
             
                TemplateData keyword3 = new TemplateData();
                keyword3.setValue(orderAmount);
                keyword3.setColor("#173177");
                mapdata.put("keyword3", keyword3);
                
                TemplateData remark = new TemplateData();
                remark.setValue(AlipayController.remark);
                remark.setColor("#173177");
                mapdata.put("remark", remark);
                wechatTemplate.setData(mapdata);
                
                //通过JSONArray将模板类转换为字符串
                JSONArray wechatTemplatearray =  JSONArray.fromObject(wechatTemplate);
                String wechatTemplateStr = wechatTemplatearray.toString().replace("[", " ");
                wechatTemplateStr = wechatTemplateStr.toString().replace("]", " ");

     2、后台调用微信公众号接口发送模板消息

            import net.sf.json.JSONArray;
            import com.alibaba.fastjson.JSONObject;
    
            public static String template_id = "模板消息的模板Id";
    
    	public static String templateHead = "您的订单通知>_<";
    	
    	public static String remark = "感谢您的光顾,祝您生活愉快!*_*";
    
            @ResponseBody
    	@RequestMapping(value = "sendTemplateMessages")
    	public String sendTemplateMessages(String body,String openId,String orderNumber,String commodityDetails,String orderAmount) { 
    		try {
    			//获取公众号access_token(GET请求)
    	        URL url = new URL("https://api.weixin.qq.com/cgi-bin/token?appid=&secret=&grant_type=client_credential");
    	        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
    	        // 在连接之前设置属性
    	        // Content-Type实体头用于向接收方指示实体的介质类型,指定HEAD方法送到接收方的实体介质类型,或GET方法发送的请求介质类型
    	        conn.setRequestProperty("Content-Type", "application/json; charset=utf-8");
    	        // 设置打开与此URLConnection引用的资源的通信链接时使用的指定超时值(以毫秒为单位)
    	        conn.setConnectTimeout(10000);
    	        // 将读取超时设置为指定的超时时间,以毫秒为单位。
    	        // conn.setReadTimeout(60000);
    	        conn.setRequestMethod("GET");
    	        // Post 请求不能使用缓存
    	        conn.setUseCaches(false);
    	        // 建立连接
    	        conn.connect();
    	        // 获取响应
    	        BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
    	        String line;
    	        String result = "";
    	        while ((line = reader.readLine()) != null) {
    	            result += line;
    	        }
    	        reader.close();
    	        conn.disconnect();
    	        JSONObject jsStr = JSONObject.parseObject(result);
    	        //Json对象转换成java对象,获取到公众号access_token
    	        WeChatToken weChatToken = (WeChatToken) JSONObject.toJavaObject(jsStr,WeChatToken.class);
    
    	        //发送模板消息(POST请求)
    	        URL msurl = new URL("https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=" + weChatToken.access_token);
                HttpURLConnection msconn = (HttpURLConnection) msurl.openConnection();
                // 在连接之前设置属性
                // Content-Type实体头用于向接收方指示实体的介质类型,指定HEAD方法送到接收方的实体介质类型,或GET方法发送的请求介质类型
                msconn.setRequestProperty("Content-Type", "application/json; charset=utf-8");
                // 设置打开与此URLConnection引用的资源的通信链接时使用的指定超时值(以毫秒为单位)
                msconn.setConnectTimeout(30000);
                // 将读取超时设置为指定的超时时间,以毫秒为单位。
                // conn.setReadTimeout(60000);
                // 发送POST请求必须设置如下两行
                msconn.setDoOutput(true);
                msconn.setDoInput(true);
                msconn.setRequestMethod("POST");
                // Post 请求不能使用缓存
                msconn.setUseCaches(false);
                // 建立连接
                msconn.connect();
                OutputStream outputStream = msconn.getOutputStream();
                //前台如果传来消息模板则直接使用,如果未传则自己创建消息模板
                //注意编码格式,防止中文乱码
                //前台组装好模板消息,则直接使用  eg:body
                //outputStream.write(body.getBytes("UTF-8"));
                
                //前台没有传模板消息,则后台自己组装 eg:wechatTemplateStr
                WechatTemplate wechatTemplate = new WechatTemplate();
                wechatTemplate.setTemplate_id(AlipayController.template_id);
                wechatTemplate.setTouser(openId);
                Map<String,TemplateData> mapdata = new HashMap<>();
                // 封装模板数据
                TemplateData first = new TemplateData();
                first.setValue(AlipayController.templateHead);
                first.setColor("#173177");
                mapdata.put("first", first);
             
                TemplateData keyword1 = new TemplateData();
                keyword1.setValue(orderNumber);
                keyword1.setColor("#173177");
                mapdata.put("keyword1", keyword1);
             
                TemplateData keyword2 = new TemplateData();
                keyword2.setValue(commodityDetails);
                keyword2.setColor("#173177");
                mapdata.put("keyword2", keyword2);
             
                TemplateData keyword3 = new TemplateData();
                keyword3.setValue(orderAmount);
                keyword3.setColor("#173177");
                mapdata.put("keyword3", keyword3);
                
                TemplateData remark = new TemplateData();
                remark.setValue(AlipayController.remark);
                remark.setColor("#173177");
                mapdata.put("remark", remark);
                wechatTemplate.setData(mapdata);
                
                //通过JSONArray将模板类转换为字符串
                JSONArray wechatTemplatearray =  JSONArray.fromObject(wechatTemplate);
                String wechatTemplateStr = wechatTemplatearray.toString().replace("[", " ");
                wechatTemplateStr = wechatTemplateStr.toString().replace("]", " ");
                
                outputStream.write(wechatTemplateStr.getBytes("UTF-8"));
                outputStream.close();
                
                // 获取响应
                BufferedReader msreader = new BufferedReader(new InputStreamReader(msconn.getInputStream()));
                String msline;
                String msresult = "";
                while ((msline = msreader.readLine()) != null) {
                    msresult += msline;
                }
                msreader.close();
    
                msconn.disconnect();
                return msresult;
    	        
    	    } catch (MalformedURLException e) {
    	
    	        e.printStackTrace();
    	    } catch (SocketTimeoutException e) {
    	        e.printStackTrace();
    	    } catch (IOException e) {
    	
    	        e.printStackTrace();
    	    }
    		return "send false";
        }

    3、组装模板消息需要用到的几个类

    import java.util.Map;
    
    
    public class WechatTemplate {
        private String touser;
     
        private String template_id;
     
        private String url;
     
        private Map<String, TemplateData> data;
     
        public String getTouser() {
            return touser;
        }
     
        public void setTouser(String touser) {
            this.touser = touser;
        }
     
        public String getTemplate_id() {
            return template_id;
        }
     
        public void setTemplate_id(String template_id) {
            this.template_id = template_id;
        }
     
        public String getUrl() {
            return url;
        }
     
        public void setUrl(String url) {
            this.url = url;
        }
     
        public Map<String, TemplateData> getData() {
            return data;
        }
     
        public void setData(Map<String, TemplateData> data) {
            this.data = data;
        }
    }
    public class TemplateData {
        private String value;
        private String color;
        public String getValue() {
            return value;
        }
     
        public void setValue(String value) {
            this.value = value;
        }
     
        public String getColor() {
            return color;
        }
     
        public void setColor(String color) {
            this.color = color;
        }
    }
    public class WeChatToken {
    	 public String access_token ;
         public int expires_in;
    }

     以上所说就可以完成公众号给微信用户发送模板消息,希望能帮助到您。(*^▽^*)

     

    展开全文
  • 公众号设置->功能设置,配置网页授权域名 进入基础设置,开通开发者密码(AppSecret),并保存起来 ip白名单设置你的服务器ip(用于获取access_token) 开通模板消息 选择模板 开发阶段 获取用户openid ...

    配置阶段

    1. 微信公众号为服务号且开通微信认证(其他类型账号不能发送)

    2. 申请备案个线上域名

    3. 公众号设置->功能设置,配置网页授权域名
      在这里插入图片描述
      在这里插入图片描述

    4. 进入基础设置,开通开发者密码(AppSecret),并保存起来

    5. ip白名单设置你的服务器ip(用于获取access_token)在这里插入图片描述

    6. 开通模板消息
      在这里插入图片描述

    7. 选择模板
      在这里插入图片描述

    开发阶段

    获取用户openid 官网文档

    1. 拼接用户授权url,用户同意授权,并根据redirect_uri回调获取code

      接口地址:https://open.weixin.qq.com/connect/oauth2/authorize?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=SCOPE#wechat_redirect
      
      请求方式: get
      
      appid:公众号appid基础设置里有(必填)
      
      redirect_uri:重定向地址,用于接收code(必填)
      
      response_type:返回类型,请填写code(必填)
      
      scope:应用授权作用域,snsapi_base (不弹出授权页面,直接跳转,只能获取用户openid),
      	snsapi_userinfo (弹出授权页面,可通过openid拿到昵称、性别、所在地。并且, 
      	即使在未关注的情况下,只要用户授权,也能获取其信息 )(必填)
      	
      wechat_redirect:无论直接打开还是做页面302重定向时候,必须带此参数(必填)
      
      完成参数填写后直接扔进你的自定义菜单栏里,点击跳转url
      
      如果用户同意授权,页面将跳转至 redirect_uri/?code=CODE&state=STATE
    2. 通过code获取特殊的网页授权access_token,refresh_token,openid

      接口地址:https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code
      
      请求方式: get
      
      appid:公众号appid基础设置里有(必填)
      
      secret:公众号secret基础配置里生成(必填)
      
      code:第一步获取的code(必填)
      
      grant_type:填写为authorization_code(必填)
      
      正确返回的结果:
      
      { "access_token":"ACCESS_TOKEN",
      
      "expires_in":7200,
      
      "refresh_token":"REFRESH_TOKEN",
      
      "openid":"OPENID",
      
      "scope":"SCOPE" }
      

    发送模板消息

    1. 获取access_token

      接口地址:https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=appid&secret=secret
      
      请求方式: get
      
      appid:公众号appid(必填)
      
      secret:开发者密码(AppSecret)(必填)
      
      grant_type:获取access_token填写client_credential(必填)
      
    2. 按模板消息详情,拼接模板消息数据
      在这里插入图片描述

      $data = [
          "touser"=>$openid, //对方的openid,前一步获取
          "template_id"=>"v2kBJOHxxxxxxx", //模板id
          // "miniprogram"=>[
          //     "appid"=>"xxx", //跳转小程序appid
          //     "pagepath"=>"pages/index/index"//跳转小程序页面
          // ],
          "data"=>[
              "first"=>[
                  "value"=> "通知头",
                  "color"=> '#173177'
              ],
              "keyword1"=>[
                  "value"=> '微信名称',
                  "color"=> '#173177'
              ],
              "keyword2"=>[
                  "value"=> date('Y-m-d H:i:s'),
                  "color"=> '#173177'
              ],
              "remark"=>[
                  "value"=> "如有疑问,请联系当地网点",
                  "color"=> '#173177'
              ],
          ]
      ];
      
    3. 发送模板消息

      接口地址:https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=access_token; 
      
      请求方式: post
      
      appid:公众号appid(必填)
      
      secret:开发者密码(AppSecret)(必填)
      
      access_token:前面第一步获取的access_token,此时再次请求access_token,与获取openid的接口不同!!!
      
      传输前面按模板消息详情,拼接的模板消息data数据
      
      
    4. 关注公众号后,即可实时接受发送的消息
      在这里插入图片描述

    注:

    发送模板消息时获取的access_token具有2小时的时效可丢进缓存中,不必每次发送都获取,每天只有两千次,模板消息发送次数为10万次,当然根据你公众号的关注人数来确定,人数超过10万肯定具有更高的次数

    如果您觉得本篇对你有帮助,可以点关注,给个赞,支持一下,过程有遇到什么问题也欢迎评论私信,进行交流

    展开全文
  • 微信公众号发送模板消息 1.创建模板,拿到模板ID 2.创建发送消息工具类 import cn.hutool.http.HttpUtil; import com.alibaba.fastjson.JSONObject; import org.slf4j.Logger; import org.slf4j.LoggerFactory...

    微信公众号发送模板消息

    1.创建模板,拿到模板ID

     2.创建发送消息工具类

    import cn.hutool.http.HttpUtil;
    import com.alibaba.fastjson.JSONObject;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.stereotype.Component;
    
    import java.util.HashMap;
    import java.util.List;
    import java.util.Map;
    
    @Component
    public class WeixinUtil {
        private static Logger logger = LoggerFactory.getLogger(WeixinUtil.class);
    
        private static final String WEIXIN_PREFIX = "https://api.weixin.qq.com/cgi-bin";
        @Value("${wx.appID}")
        private String appID;
    
        @Value("${wx.secret}")
        private String secret;
    
        @Value("${wx.domainName}")
        private String domainName;
    
        private static String PARAM_ACCESS_TOKEN = "";
        private static long TOKEN_START = 0;
        private static int expiresIn = 7200;
    
        /**
         * 做一个缓存的access_token
         */
        private String getAccessToken() {
            if (TOKEN_START == 0) {
                PARAM_ACCESS_TOKEN = getNormalAccessToken();
                TOKEN_START = System.currentTimeMillis();
            } else if (System.currentTimeMillis() - TOKEN_START > expiresIn) {
                PARAM_ACCESS_TOKEN = getNormalAccessToken();
                TOKEN_START = System.currentTimeMillis();
            }
            return PARAM_ACCESS_TOKEN;
        }
    
        /**
         * 发送信息
         *
         * @param params
         */
        private void sendInfo(String params) {
            String url = WEIXIN_PREFIX + "/message/template/send?access_token=" + getAccessToken();
            String result = HttpUtil.post(url, params);
            logger.info(">>>发送消息:" + result);
            System.out.println(">>>发送消息:" + result);
        }
    
        private static String getNormalAccessTokenURL() {
            return WEIXIN_PREFIX + "/token";
        }
    
        /**
         * 获取普通的AccessToken
         */
        private String getNormalAccessToken() {
            Map<String, Object> map = new HashMap<>();
            map.put("grant_type", "client_credential");
            map.put("appid", appID);
            map.put("secret", secret);
            String result = HttpUtil.get(getNormalAccessTokenURL(), map);
            if (result != null) {
                JSONObject jsonObject = JSONObject.parseObject(result);
                PARAM_ACCESS_TOKEN = jsonObject.getString("access_token");
                expiresIn = jsonObject.getInteger("expires_in");
            }
            return PARAM_ACCESS_TOKEN;
        }
    
    
        public void sendMessage(String toUser, String templateID, String subURL, String first,
                                List<String> keywordList, String remark) {
            MessageEntity messageEntity = new MessageEntity();
            messageEntity.setTouser(toUser);
            messageEntity.setTemplate_id(templateID);
            messageEntity.setUrl(domainName + subURL);
            messageEntity.setData(getMapData(first, keywordList, remark));
            sendInfo(messageEntity.toString());
        }
    
        private static Map<String, Map<String, String>> getMapData(String f1, List<String> keywordList, String rmk) {
            Map<String, Map<String, String>> data = new HashMap<>(5);
            Map<String, String> first = new HashMap<>(2);
            first.put("color", "#173177");
            first.put("value", f1);
            for (int i = 1; i <= keywordList.size(); i++) {
                Map<String, String> subMap = new HashMap<>(2);
                subMap.put("color", "#173177");
                subMap.put("value", keywordList.get(i - 1));
                data.put("keyword" + i, subMap);
            }
    
            Map<String, String> remark = new HashMap<>(2);
            remark.put("color", "#173177");
            remark.put("value", rmk);
    
            data.put("first", first);
            data.put("remark", remark);
            return data;
        }
    
        /**
         * 获取关注当前公共号人数,还可以获取光柱公众号的openid列表
         *
         * @return
         */
        public int getConcernedPeople() {
            String url = WEIXIN_PREFIX + "/user/get?access_token=" + getAccessToken();
            try {
                String result = HttpUtil.get(url);
                if (result != null) {
                    JSONObject jsonObject = JSONObject.parseObject(result);
                    return (int) jsonObject.get("total");
                }
            } catch (Exception e) {
                logger.error(e.getMessage());
                return 0;
            }
            return 0;
        }
    }

     

    /**
     * 消息的发送需要json格式
     */
    class MessageEntity {
        private String touser;
        private String template_id;
        private String url;
        private Map<String, Map<String, String>> data;
    
        public String getTouser() {
            return touser;
        }
    
        public void setTouser(String touser) {
            this.touser = touser;
        }
    
        public String getTemplate_id() {
            return template_id;
        }
    
        public void setTemplate_id(String template_id) {
            this.template_id = template_id;
        }
    
        public String getUrl() {
            return url;
        }
    
        public void setUrl(String url) {
            this.url = url;
        }
    
        public Map<String, Map<String, String>> getData() {
            return data;
        }
    
        public void setData(Map<String, Map<String, String>> data) {
            this.data = data;
        }
    
        @Override
        public String toString() {
            return JSONObject.toJSONString(this);
        }
    }

     在springboot中可以直接使用。其中appID和secret是微信公众号基础信息,domainName是网站域名(如果域名修改便于改动,也利于测试和生成环境部署)

    用户点击消息查看详情,如果网址是http://www.xxx.com/a/p/123.html,这时候domainName就可以设置为http://www.xxx.com,如果后期域名改动或者测试生成环境切换,都可以通过配置文件进行修改,比较简单方便。

    3.构建发送的信息并发送

            // 微信通知:先获取WeixinUtil对象,然后组织发送消息的信息
            String openid="openid";
            String templateID="templateID";
            String subURL = "/wx.html/p/detail?id=109&number=1591953944402";
            String first = "您的请假已被驳回";
            String remark = "备注消息";
            List<String> keywordList = new ArrayList<>(2);
            keywordList.add("已驳回");
            keywordList.add("请假时间过长");
            weixinUtil.sendMessage(openid, templateID, subURL, first, keywordList, remark);

     

     

    展开全文
  • 微信公众号消息模板发送微信公众号消息模板群发功能开通申请模板消息功能获取模板消息发送所需参数AccessToken pojo类TemplateData pojo类WxTagsEntity pojo类WxTemplate pojo类WxTemplateEntity pojo类微信公众号...
  • 做微信公众号和调试手机页面的时候,避免不了页面要跳转到微信浏览器打开,调试阶段,android版微信浏览器一直都默认缓存html静态资源,每次静态资源变化甚至新内容发布的时候在微信浏览器上都极有可能不能更新,很...
  • springboot 实现微信公众号模板消息推送

    千次阅读 热门讨论 2020-09-13 13:37:03
    发送消息模板可不配置公众号对接相关功能,直接使用openId 发送模板信息功能即可,openId 可让用户关注公众号录入系统, 或者在公众号添加h5 表单,绑定系统账号, 微信打开的h5 页面可获取当前用户的openId 二、实现...
  • 文章目录获取code获取openid获取用户信息获取基础access_token发送模版消息写在最后 获取code         就一个get请求连接,只要在微信内请求,弄个href访问就行,我在...
  • java实现微信公众号模板消息推送

    千次阅读 热门讨论 2019-02-28 13:21:59
    2、微信公众号提供的消息模板的Template_id access_token: 公众平台以access_token为接口调用凭据,来调用接口,所有接口的调用需要先获取access_token,access_token在2小时内有效,过期需要重新获取,但1天内...
  • 微信公众号开发之模板消息

    千次阅读 2018-11-27 15:09:56
    微信公众号发送模板消息其实很简单,调用下面的这个工具类即可(这个工具类是我在网上找的。。。)。工具类主要用于调用微信发送模板消息的接口。 首先会获取ACCESS_TOKEN,若之前获取的没过期则用之前的,若过期了...
  • 小程序关联公众号使用公众号模板消息做消息提示   最近在开发小程序中遇到一个需求:小程序的用户关注指定公众号,则小程序里需要通知用户的提醒消息可以做在公众号中。 首先我先把实现的整套流程先述说一遍,...
  • 微信公众号 模板消息

    2020-09-11 10:57:01
    现有一套在线客服系统,想用微信公众号模板消息来及时提醒客服 公众号文档地址 步骤: 1.设置行业 2.选择想要用的模板 3.获取模板列表,得到模板id 这里调用接口: GET ...4.根据模板参数,补充数据。...
  • 微信公众号模板消息 简易完整代码

    千次阅读 2019-12-12 12:11:54
    添加的模板信息详细内容: {{first.DATA}} 机构名称:{{keyword1.DATA}} 服务期限:{{keyword2.DATA}} {{remark.DATA}} */ //plan user time userid 将以下内容修改特别别是最后个参数userid为自己公众号下存在的...
  • 基于tp5 微信公众号模板消息

    千次阅读 2019-05-11 19:16:45
    发送模板消息前期准备 先通过appid appsecret获取code ,然后通过code获取...通过access_token获取到用户信息后就可以发送模板消息了 微信sdk <?php /** * 微信公众平台PHP-SDK, 官方API部分 * @author dodge ...
  • 现在,我们也要做这样一件事,不过我的业务场景是这样的:现在有一个公众号,还有一个小程序,我需要给指定的已关注我公众号的用户推送一条模板消息,当用户点击模板消息后可以调到我小程序中的指...
  • 开通模板消息并在模板库中选用模板 获取openid 发送模板消息 ip白名单 网页授权 开通模板消息并选用模板 获取openid [这是官方给出的文档] 用户同意授权,获取code 接口地...
  • 目录依赖包步骤功能描述 依赖包 步骤 获取 access_token; 构建数据; 发送推送请求。...所需跳转到的小程序appid(该小程序appid必须与发模板消息的公众号是绑定关联关系,暂不支持小游戏) page
  • *微信模板推送 * @param req 微信用户唯一标识 * @param response 处理给浏览器返回的数据 * @return 返回状态 */ @GetMapping("/tuisong") public String SendWxNotice(HttpServletRequest req, ...
  • 模板消息还是在商城类的微信项目中使用比较多,模板消息仅用于公众号向用户发送重要的服务通知,只能用于符合其要求的服务场景中,如绑定手机号通知,商品购买成功通知等,不支持广告等营销类消息以及其它所有可能对...
  • 微信公众号模板消息群发代码示例

    万次阅读 2016-12-29 11:20:00
    注意,如果模板消息发信息时有时无,不稳定,可能你的access_token令牌更新缓存不及时,过期了.可以根据日志文件查看.建议300秒更新一下.否则会很烦. 模板id需要自己去公众号中设置行业后得到.   function fahuo_...
  • 我们在微信公众号开发过程中经常会需要向用户推送消息,最常用到的就是微信公众号模板消息了,下面是代码工坊整理的php实现微信公众号模板消息的使用思路。1、开通模板消息功能。2、添加模板消息模板。3、代码中首先...
  • 二:获取使用微信公众号基本接口所需要的access_token,并全局缓存. 我在tp框架Application/Home/Common/function.php中定义公共方法getAccessToken方法获取access_token并全局缓存.   //该公共方法获取...
  • 发送模板消息,OKhttp3.* 基础接口封装
  • 使用shell通过微信公众号发送模板消息

    千次阅读 热门讨论 2017-05-05 23:10:51
    如下通过shell脚本实现,通过微信公众号发送模板消息到个人微信号。1.配置微信公众号由于没有认证的公众号,只能通过自己申请的个人订阅号(可以自行申请),并到开发者工具中开通公众平台测试帐号实现该功能。
  • 本篇文章实现模板、图文、文本、音乐、图片推送,前提是已经搭建了微信开发环境。读完本文后,实现的主要效果如下
  • // 获取微信用户基本信息 try { WxMpUser userWxInfo = weixinService.getUserService() .userInfo(wxMessage.getFromUser(), null); if (userWxInfo != null) { // TODO 添加关注用户到本地数据库 WxApp wxApp = ...
  • 微信 JSAPI 支付 微信内部起调H5支付 支付完成发送公众号消息模板 JSAPI支付 openID是必传的,所以这里先获取用户openID,想要获取openID,首先我们要拿到code,再获取openID JS: <script> // 强制关注...
  • ```$ACCESS_TOKEN = "";//ACCESS_TOKEN//openid数组$touser = ['ovMzR1HD6LOcbcWLw...//模板消息请求URL$url = "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=" . $ACCESS_TOKEN;//遍历发...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 8,865
精华内容 3,546
关键字:

公众号信息模板缓存

友情链接: structure.rar