精华内容
下载资源
问答
  • 微信公众号推送小程序模板消息的实现 准备: 微信小程序认证 微信公众号认证 微信开发平台认证(绑定微信小程序和公众号(unionid)) unionid:同一用户,对同一个微信开放平台下的不同应用,unionid是相同的 思路: 1. ...

    微信公众号推送小程序模板消息的实现

    准备:
    微信小程序认证
    微信公众号认证
    微信开发平台认证(绑定微信小程序和公众号(unionid))
    unionid:同一用户,对同一个微信开放平台下的不同应用,unionid是相同的
    思路:
    1. 获取小程序信息(用户openid小程序用户唯一ID)
    将小程序与公众号绑定(绑定后才可获取unionid)

        /**
         * 小程序用户登录授权
         */
        @GetMapping("/getUserOpenId")
        public AjaxResult getUserOpenId(String code){
            if (StringUtils.isEmpty(code)){
                return AjaxResult.error("请输入code");
            }
            Map<String, Object> result = new LinkedHashMap();
            String oAuth = WxAppletUserInfo.getOAuth(code, userAppId, userSecret);
            JSONObject jsonObject = JSONObject.fromObject(oAuth);
            //获取openId和sessionKey
            String openid = jsonObject.get("openid").toString();
            String session_key = jsonObject.get("session_key").toString();
            String unionid= jsonObject.get("unionid").toString();
    		......
        }
    

    2.获取公众号的openid(公众号用户唯一ID)

    
    --公众号回调
    https://open.weixin.qq.com/connect/oauth2/authorize?appid=&redirect_uri=https%3A%2F%2Fty.breezedi.com%2Fadmin%2Fapi%2Fwx%2FscanQRCode&response_type=code&scope=snsapi_userinfo&state=0078d70e-68c#wechat_redirect
    
    
    
         /**
         * 微信授权回调
         * @param request
         * @param resp
         * @throws IOException
         */
        @RequestMapping(value = "/scanQRCode", method = {RequestMethod.GET,RequestMethod.POST})
        public void scanQRCode(HttpServletRequest request,HttpServletResponse resp) throws IOException {
            String code = request.getParameter("code");
            if (null == code || code.trim().equals("")){
                log.info("***********code为空************");
            }
            String state = request.getParameter("state");
            if (null != state || !code.trim().equals("")){
                log.info("state参数:{}",state);
            }
            //根据code获取token
            String accessTokenCode = WxAppletUserInfo.getAccessTokenCode(code);
            //获取openid
            JSONObject jsonObject = JSONObject.fromObject(accessTokenCode);
            log.info("微信回调后获取公众号参数:{}",jsonObject);
            //获取openid和session_key
            String openid = jsonObject.get("openid").toString();
            String accessToken = jsonObject.get("access_token").toString();
            //获取用户信息网页授权
            String wxUserInfo = WxAppletUserInfo.getWxUserInfo(accessToken,openid);
            log.info("用户信息{}",wxUserInfo);
            JSONObject fromObject = JSONObject.fromObject(wxUserInfo);
            String nickName = fromObject.getString("nickname");
            String sex = fromObject.getString("sex");
            String province = fromObject.getString("province");
            String city = fromObject.getString("city");
            String country = fromObject.getString("country");
            String headImgUrl = fromObject.getString("headimgurl");
            String privilege = fromObject.getString("privilege");
            String unionId = fromObject.getString("unionid");
            TyWxPatform patform = new TyWxPatform();
            //授权判断用户是否关注公众号
            //获取用户信息所需要的token
            String token = WxAppletUserInfo.getAccessToken();
            String infoSub = WxAppletUserInfo.getWxUserInfoSub(token, openid);
            JSONObject json = JSONObject.fromObject(infoSub);
            String  subscribe = json.getString("subscribe");
           //业务方法........
        }
    

    获取小程序公众号信息

    package com.ty.common.wx;
    
    import com.ty.common.utils.http.HttpUtils;
    import lombok.extern.slf4j.Slf4j;
    import net.sf.json.JSONObject;
    import org.apache.commons.codec.binary.Base64;
    
    import javax.crypto.Cipher;
    import javax.crypto.KeyGenerator;
    import javax.crypto.spec.IvParameterSpec;
    import javax.crypto.spec.SecretKeySpec;
    import java.security.AlgorithmParameters;
    import java.security.Key;
    import java.security.Security;
    
    @Slf4j
    public class WxAppletUserInfo {
    
        //获取小程序登录信息
        private final static String GET_CODE_SESSION_URL="https://api.weixin.qq.com/sns/jscode2session";
    
        // 算法名
        private static final String KEY_NAME = "AES";
    
        // ECB模式只用密钥即可对数据进行加密解密,CBC模式需要添加一个iv 加解密算法/模式/填充方式
        private static final String CIPHER_ALGORITHM = "AES/CBC/PKCS7Padding";
    
        //公众号AppID
        private static final String appId = "";
    
        //公众号秘钥
        private static final String appSecret = "";
    
        //通过code换取网页授权access_token
        private static final String wxAuthLoginUrl = "https://api.weixin.qq.com/sns/oauth2/access_token";
    
        //公众号网页登陆url
        private static final String urlToken = "https://api.weixin.qq.com/cgi-bin/token";
    
        //获取微信公众号信息--是否关注
        private static final String userInfoSub = "https://api.weixin.qq.com/cgi-bin/user/info";
    
        //获取微信公众号信息--网页授权 拉取用户信息
        private static final String userInfo = "https://api.weixin.qq.com/sns/userinfo";
    
        /**
         * 获取小程序用户登陆信息
         * @param code
         * @param appId
         * @param secret
         * @return
         */
        public static String getOAuth(String code,String appId,String secret) {
            StringBuffer url = new StringBuffer(GET_CODE_SESSION_URL);
            url.append("?appid="+appId).append("&secret="+secret)
                    .append("&js_code="+code)
                    .append("&grant_type=authorization_code");
            return HttpUtils.sendGet(url.toString());
        }
    
        /**
         * 微信 数据解密<br/>
         * 对称解密使用的算法为 AES-128-CBC,数据采用PKCS#7填充<br/>
         * 对称解密的目标密文:encrypted=Base64_Decode(encryptData)<br/>
         * 对称解密秘钥:key = Base64_Decode(session_key),aeskey是16字节<br/>
         * 对称解密算法初始向量:iv = Base64_Decode(iv),同样是16字节<br/>
         *
         * @param encryptedData 目标密文
         * @param session_key 会话ID
         * @param iv 加密算法的初始向量
         */
        public static JSONObject wxDecrypt(String encryptedData, String session_key, String iv) {
            log.info("手机号解密所需要的数据:\n{},\n{},\n{}\n",encryptedData,session_key,iv);
            String json = null;
            byte[] encrypted64 = Base64.decodeBase64(encryptedData);
            byte[] key64 = Base64.decodeBase64(session_key);
            byte[] iv64 = Base64.decodeBase64(iv);
            byte[] data;
            try {
                init();
                json = new String(decrypt(encrypted64, key64, generateIV(iv64)));
            } catch (Exception e) {
                log.error("*********解密微信手机号失败:**********" + e.getMessage());
            }
            return JSONObject.fromObject(json);
        }
    
        /**
         * 初始化密钥
         */
        public static void init() throws Exception {
            Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
            KeyGenerator.getInstance(KEY_NAME).init(128);
        }
    
        /**
         * 生成iv
         */
        public static AlgorithmParameters generateIV(byte[] iv) throws Exception {
            // iv 为一个 16 字节的数组,这里采用和 iOS 端一样的构造方法,数据全为0
            // Arrays.fill(iv, (byte) 0x00);
            AlgorithmParameters params = AlgorithmParameters.getInstance(KEY_NAME);
            params.init(new IvParameterSpec(iv));
            return params;
        }
    
        /**
         * 生成解密
         */
        public static byte[] decrypt(byte[] encryptedData, byte[] keyBytes, AlgorithmParameters iv)throws Exception {
            Key key = new SecretKeySpec(keyBytes, KEY_NAME);
            Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);
            // 设置为解密模式
            cipher.init(Cipher.DECRYPT_MODE, key, iv);
            return cipher.doFinal(encryptedData);
        }
    
        /**
         * 获取模板消息所需要的access_token(获取微信公众号的access_token(7200秒有效))
         * @param
         * @return
         */
        public static String getAccessToken() {
            StringBuffer url = new StringBuffer(urlToken);
            url.append("?appid="+appId)
                    .append("&secret="+appSecret)
                    .append("&grant_type=client_credential");
            String token = HttpUtils.sendGet(url.toString());
            log.info("获取模板消息所的认证参数access_token:{}",token);
            JSONObject Json = JSONObject.fromObject(token);
            String access_token = String.valueOf(Json.get("access_token").toString());
            return access_token;
        }
    
        /**
         * 公众号
         * 根据code获取到网页授权access_token
         * @param code
         * @return  微信回调后带有的参数code值
         */
        public static String getAccessTokenCode(String code) {
            StringBuffer url = new StringBuffer(wxAuthLoginUrl);
            url.append("?appid="+appId)
                    .append("&secret="+appSecret)
                    .append("&code="+code)
                    .append("&grant_type=authorization_code");
            log.info("根据code获取到网页授权access_token:{}",url.toString());
            return HttpUtils.sendGet(url.toString());
        }
    
        /**
         * 公众号
         * 获取微信用户 (判断有无关注)获取用户信息
         * @param accessToken
         * @param openId
         * @return
         */
        public static String getWxUserInfoSub(String accessToken,String openId) {
            StringBuffer url = new StringBuffer(userInfoSub);
            url.append("?access_token="+accessToken)
                    .append("&openid="+openId)
                    .append("&lang=zh_CN");
            log.info("获取微信用户信息(是否关注公众号):{}",url.toString());
            return HttpUtils.sendGet(url.toString());
        }
    
        /**
         * 公众号
         * 获取微信用户--网页授权获取用户信息
         * @param accessToken
         * @param openId
         * @return
         */
        public static String getWxUserInfo(String accessToken,String openId) {
            StringBuffer url = new StringBuffer(userInfo);
            url.append("?access_token="+accessToken)
                    .append("&openid="+openId)
                    .append("&lang=zh_CN");
            String urlUserInfo = url.toString();
            log.info("获取微信用户信息url:{}",urlUserInfo);
            return HttpUtils.sendGet(urlUserInfo);
        }
    
    }
    
    

    HTTPUtils

     /**
         *
         * @Title: get
         * @Description: TODO(get请求)
         * @param @param url
         * @param @return    设定文件
         * @return String    返回类型
         * @throws
         */
        public static String sendGet(String url) {
            String result = "";
            // 设置请求配置
            RequestConfig globalConfig = RequestConfig.custom().setCookieSpec(CookieSpecs.STANDARD)
                    .setConnectionRequestTimeout(10000).setConnectTimeout(10000).setSocketTimeout(50000). build();
            // 打开浏览器
            CloseableHttpClient httpClient = HttpClients.custom().setDefaultRequestConfig(globalConfig).build();
            HttpGet httpGet = new HttpGet(url);
            RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(30000).setConnectionRequestTimeout(30000).setSocketTimeout(30000).build();
            httpGet.setConfig(requestConfig);
            httpGet.addHeader("Content-type", "application/json;charset=utf-8");
            httpGet.setHeader("Accept", "application/json");
            // 设置头
            httpGet.addHeader("User-Agent",
                    "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2311.152 Safari/537.36");
            httpGet.addHeader("Cookie", "_gat=1; nsfw-click-load=off; gif-click-load=on; _ga=GA1.2.1861846600.1423061484");
            // 收到回复
            CloseableHttpResponse response;
            try {
                response = httpClient.execute(httpGet);
                log.info("HTTPGet请求状态,status:{}" , response.getStatusLine().getStatusCode());
                result = EntityUtils.toString(response.getEntity(), "utf-8");
                EntityUtils.consume(response.getEntity());
                response.close();
                httpGet.releaseConnection();
                httpClient.close();
            } catch (ClientProtocolException e) {
                log.info("发送GET请求出现异常!" + e);
                e.printStackTrace();
            } catch (IOException e) {
                log.info("发送GET请求出现异常!" + e);
                e.printStackTrace();
            }
            return result;
        }
    

    3.推送消息服务
    公众号模板申请:一个月只能有三次,审核7-15个工作日

    //1.获取access_token
    https请求方式: GET 
    urlToken = 'https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET'
      
    String TemplateId = "";  
    
    //2.模板消息类
    //openid 是用户公众号的openid
      public static JSONObject packJsonDoctorMsg(String openid,String AppId,String pagePath){
            //医生发送公众号模板消息
            WechatTemplate wechatTemplate = new WechatTemplate();
            wechatTemplate.setTouser(openid);
            wechatTemplate.setTemplate_id(TemplateId);
            MiniprogramData miniprogramData = new MiniprogramData();
            miniprogramData.setAppid(AppId);
            miniprogramData.setPagepath(pagePath);//所需跳转到小程序的具体页面路径,支持带参数,(示例index?foo=bar),要求该小程序已发布,暂不支持小游戏
            wechatTemplate.setMiniprogram(miniprogramData);
            Map<String,TemplateData> dataMap = new HashMap<>();
            TemplateData title = new TemplateData();
            title.setValue("所发送消息内容");
            title.setColor("#000000");
            dataMap.put("title",title);
            TemplateData first = new TemplateData();
            first.setValue("所发送消息内容";
            first.setColor("#000000");
            dataMap.put("first",first);
            TemplateData keyword = new TemplateData();
            keyword.setValue("所发送消息内容");
            keyword.setColor("#000000");
            dataMap.put("keyword",keyword);
            TemplateData keyword = new TemplateData();
            keyword.setValue("所发送消息内容");
            keyword.setColor("#000000");
            dataMap.put("keyword", keyword);
            TemplateData keyword = new TemplateData();
            keyword.setValue("所发送消息内容");
            keyword.setColor("#000000");
            dataMap.put("keyword", keyword);
            TemplateData keyword = new TemplateData();
            keyword.setValue("所发送消息内容");
            keyword.setColor("#000000");
            dataMap.put("keyword", keyword);
            TemplateData remark = new TemplateData();
            remark.setValue("所发送消息内容");
            remark.setColor("#000000");
            dataMap.put("remark", remark);
            wechatTemplate.setData(dataMap);
            JSONObject json = JSONObject.fromObject(wechatTemplate);
            return json;
        }
    
    //3.用户发送模板消息
    JSONObject userMsgDate = MessageModel.packJsonUserMsg(openid, AppId, userPagePath);
    
    JSONObject jsonobjUser = HttpUtils.httpRequest(send+WxAppUserInfo.getAccessToken(urlToken,appId,appSecret),"POST",userMsgDate.toString());
                   
    

    over~

    展开全文
  • 2.yml中增加小程序公众号id及消息模板配置 3.增加配置类 @Data @Component @ConfigurationProperties() public class WxMiniConfigVo { /**小程序appid*/ @Value("${wxmini.id}") private String ...

    点个赞哦

    背景

    最近开发的一个小程序项目需要通过服务号来推送通知。但是在最开始开发小程序的时候使用了一次性消息推送,不是很友好。

    在做消息推送时也是踩了无数坑,因为在2021年2月前其他人的文章所使用的案例中调用的小程序模板消息接口都没有用,也没有实质性的帮助,所以我在这篇文章中给出自己摸索出针对统一消息接口做推送的解决方案。

    1.首先将小程序绑定到指定的公众号下

    2.申请公众号模板

     3.yml中增加小程序和公众号id及消息模板配置

     4.增加配置类

    @Data
    @Component
    @ConfigurationProperties()
    public class WxMiniConfigVo {
    
        /**小程序appid*/
        @Value("${wxmini.id}")
        private String WxMiniAPPID;
    
        /**小程序秘钥*/
        @Value("${wxmini.secret}")
        private String WxMiniSECRET;
    
        /**小程序数据加密方式*/
        @Value("${wxmini.grant_type}")
        private String WxMinigrantType;
    
        /**公众号id*/
        @Value("${wxmini.gzh_id}")
        private String WxGzhId;
    
        /**公众号模板*/
        @Value("${wxmini.gzh_template}")
        private String WxGzhTemplate;
    }

    5.编写接口

    @Slf4j
    @Service
    public class SendMiniAppServiceImpl implements SendMiniAppService {
    
        @Autowired
        private WxMiniConfigVo wxMiniConfigVo;
    
        @Autowired
        private RedisUtil redisUtil;
    
        @Override
        public String getAccessToken() {
            RestTemplate restTemplate = new RestTemplate();
            Map<String, String> params = new HashMap<>();
            params.put("APPID", wxMiniConfigVo.getWxMiniAPPID());
            params.put("APPSECRET", wxMiniConfigVo.getWxMiniSECRET());
            params.put("grant_type", "client_credential");
            String tokenUrl="https://api.weixin.qq.com/cgi-bin/token?appid={APPID}&secret={APPSECRET}&grant_type={grant_type}";
            ResponseEntity<String> responseEntity = restTemplate.getForEntity(tokenUrl, String.class, params);
            String body = responseEntity.getBody();
            JSONObject object = JSON.parseObject(body);
            String Access_Token = object.getString("access_token");
            redisUtil.set("wxMiniToken", Access_Token);
            redisUtil.expire("wxMiniToken", Long.parseLong(object.getString("expires_in")));
            return Access_Token;
        }
    
        @Override
        public String push(String openid, Map<String, String> content) {
            //获取用户token
            String token = String.valueOf(redisUtil.get("wxMiniToken"));
            if (token == "null") {
                token = getAccessToken();
            }
            String resultStatus = "0";//0:失败,1:成功
            try {
                //小程序统一消息推送
                String path = "https://api.weixin.qq.com/cgi-bin/message/wxopen/template/uniform_send?access_token=" + token;
                //封装参数
                JSONObject jsonData = new JSONObject();
                jsonData.put("touser", openid); // 小程序openid
    
                JSONObject jsonObject = new JSONObject();
                jsonObject.put("appid", wxMiniConfigVo.getWxGzhId());// 公众号id
                jsonObject.put("template_id", wxMiniConfigVo.getWxGzhTemplate());// 公众号消息模板id
    
                //公众号消息数据封装
                JSONObject data = new JSONObject();
                data.put("first", getValue("请注意!有新告警产生"));//标题
                data.put("keyword1", getValue(content.get("deviceId")));//设备编号
                data.put("keyword2", getValue(content.get("alarmName")));//设备名称
                data.put("keyword3", getValue(content.get("alarmAddress")));//设备地址
                data.put("keyword4", getValue(content.get("content")));//告警描述
                data.put("keyword5", getValue(content.get("alarmTime")));//告警时间
                data.put("remark", getValue("请及时排查并处理!"));
                jsonObject.put("data", data);
    
                jsonData.put("mp_template_msg", jsonObject);
                HttpRequest.sendPost(path, jsonData.toJSONString());
                resultStatus="1";
            } catch (Exception e) {
                log.error("微信公众号发送消息失败!",e.getMessage());
                resultStatus="0";
            }
            return resultStatus;
        }
        private JSONObject getValue(String value) {
            // TODO Auto-generated method stub
            JSONObject json = new JSONObject();
            json.put("value", value);
            json.put("color", "#173177");
            return json;
        }

    展开全文
  • 首先公众号需要开通客服功能,没有的在公众号插件里添加 //验证signature /* $signature = $_GET["signature"]; $timestamp = $_GET["timestamp"]; $nonce = $_GET["nonce"]; $echostr=$_GET["echostr"]; $token = ...

    首先公众号需要开通客服功能,没有的在公众号插件里添加

    //验证signature
    /*
    $signature = $_GET["signature"];
    $timestamp = $_GET["timestamp"];
    $nonce = $_GET["nonce"];
    $echostr=$_GET["echostr"];
    $token = "TOKEN"; //这里个token 需要跟公众号配置的一直才能通过验证 ,验证通过就可以注释掉了
    $tmpArr = array($token, $timestamp, $nonce);
    sort($tmpArr, SORT_STRING);
    $tmpStr = implode( $tmpArr );
    $tmpStr = sha1( $tmpStr );
    if ($tmpStr == $signature ) {
        return $echostr;
    } else {
        ErrorLogger($echostr);
        return false;
    }
    */
    
     $xml = file_get_contents('php://input');
     $postArr = fromXml($xml);
     $accessToken = getAccessToken();
     //thumb_media_id  生成方法https://blog.csdn.net/u013071763/article/details/115264560
     $thumb_media_id = '-sVDfOirXgF1yzlwqD1i2RrkZal1wjxtSaChPmF2f_nVFos0qrVm1GRVB0fJtyh-99'; 
     
     $url = "https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token=" . $accessToken;
     $data['touser'] = $postArr['FromUserName'];
     $data['msgtype'] = "miniprogrampage";
     $data['miniprogrampage'] = [
      "title" => "Hello World",
      "pagepath" => "pages/index/index?foo=bar",
      "appid" =>"xxxx",
      "thumb_media_id"=>$thumb_media_id 
      ];
     $json = json_encode($data, JSON_UNESCAPED_UNICODE);
     $res = postCurlWxapp( $url,$json);
    
    
    function getAccessToken(){
        
        $appid = 'xx';
        $srcret = 'xx';
        $url = 'https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid='.$appid.'&secret='.$srcret;
    	$data= getCurlWxapp($url);
    	$data = json_decode($data,true);
    	return $data["access_token"];
    
    		
    }
    
    function postCurlWxapp($url,$data){
    	$ch = curl_init();
    	$header = "Accept-Charset: utf-8";
    	curl_setopt($ch, CURLOPT_URL, $url);
    	curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
    	curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
    	curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
    	curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
    	curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (compatible; MSIE 5.01; Windows NT 5.0)');
    	curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
    	curl_setopt($ch, CURLOPT_AUTOREFERER, 1);
    	curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
    	curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    	$tmpInfo = curl_exec($ch);
    	if(curl_errno($ch)){
    		return false;
    	}else{
    		return $tmpInfo;
    	}
    }
    
    
    /**
     * 将xml转为array
     * @param $xml
     * @return mixed
     */
     function fromXml($xml)
    {
        // 禁止引用外部xml实体
        libxml_disable_entity_loader(true);
        return json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), true);
    }
    
    
    
    

    参考
    https://developers.weixin.qq.com/doc/offiaccount/Message_Management/Service_Center_messages.html#6

    展开全文
  • 在微信的官网上查询到,绑定在同一个微信开放者平台上,则会生成一个unionId,这个unionId在小程序端和在微信公众号端都是一样的,所以我们拿这个来实现向微信公众号推送模板消息的功能。 前期准备: 微信公众号:...
    • 描述:

      因小程序是被动触发推送消息,所以要做成推送到该用户的微信公众号上

      代码推送模板消息则是通过用户的openId来进行推送,但是小程序和微信公众号的openId不同,所以只能另找办法。

      在微信的官网上查询到,绑定在同一个微信开放者平台上,则会生成一个unionId,这个unionId在小程序端和在微信公众号端都是一样的,所以我们拿这个来实现向微信公众号推送模板消息的功能。

    • 前期准备:

      微信公众号:AppId和APPSecret(必须认证)

      微信小程序:AppId和APPSecret(必须认证)

      微信开放者平台(小程序和公众号必须绑定同一个开放者平台,必须认证

      认证方法找微信文档或度娘即可

    • 获取微信公众号的所有用户信息

      注:其中的APPID和APPSECRET换成自己微信公众号的appId和APPSecret

    1. 通过微信公众号的AppId和AppSecret(当前ip地址必须在微信公众号的白名单内),获取微信公众号的access_token(7200秒有效)

      地址:https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET

      返回结果:

    {
     "access_token": "ACCESS_TOKEN",
     "expires_in": 7200
    }
    
    1. 通过刚才获取到的access_token去获取所有用户的openId
      地址:https://api.weixin.qq.com/cgi-bin/user/get?access_token=ACCESS_TOKEN&next_openid=NEXT_OPENID

      返回结果:
    {
    "count": 2,
    "data": {
      "openid": [
        "OPENID1",
        "OPENID2"
      ]
    },
    # NEXT_OPENID为超出10000个取10001继续请求,这个会在每次请求后返回的json字符串中有
    "next_openid": "NEXT_OPENID",
    "total": 2
    }
    
    1. 将所有的openId全部放在一个新的数组中,然后for循环,循环次数为openId的数组的长度,循环请求每个用户的基本信息

      地址:https://api.weixin.qq.com/cgi-bin/user/info?access_token=ACCESS_TOKEN&openid=OPENID&lang=zh_CN

      返回结果:

    {
    "subscribe": 1,
    "openid": "o6_bmjrPTlm6_2sgVt7hMZOPfL2M",
    "nickname": "Band",
    "sex": 1,
    "language": "zh_CN",
    "city": "广州",
    "province": "广东",
    "country": "中国",
    "headimgurl": "http://thirdwx.qlogo.cn/mmopen/g3MonUZtNHkdmzicIlibx6iaFqAc56vxLSUfpb6n5WKSYVY0ChQKkiaJSgQ1dZuTOgvLLrhJbERQQ4eMsv84eavHiaiceqxibJxCfHe/0",
    "subscribe_time": 1382694957,
    # 其中的unionid绑定了开放者平台才会有的
    "unionid": " o6_bmasdasdsad6_2sgVt7hMZOPfL",
    "remark": "",
    "groupid": 0,
    "tagid_list": [
      128,
      2
    ],
    "subscribe_scene": "ADD_SCENE_QR_CODE",
    "qr_scene": 98765,
    "qr_scene_str": ""
    }
    
    1. 将所有的用户信息存储在自己的数据库中
    • 获取小程序用户信息

    1. 小程序端通过调用wx.login()会获取到一个用户登录凭证code(有效期五分钟)
    2. 将code传给后台,后台通过appId、APPSecret和code能够获取到这个用户的微信基本信息

      地址:https://api.weixin.qq.com/sns/jscode2session?appid=APPID&secret=SECRET&js_code=JSCODE&grant_type=authorization_code

      返回结果:

    {
     "sex": 1,
     "photoUrl": "https://wx.qlogo.cn/mmopen/vi_32/DYAIOgq83eofr4W1SptUJ9M1PUiaqA4XBZiapCN98sPYOjNDXZSrUp1JcicibeLiaHZ56qlQnibQEUSFGLnEatu1TyiaA/132",
     "openId": "oDl465JGG54ezszjG3K2spJV1TNM",
     "uniodId": "otjNb03MD_IipC8XRdL68GOKLVgs"
    }
    

    注:其中的unionid绑定了开放者平台才会有的,如果绑定后还是没有unionId,则这个小程序用户没有关注相同主体的公众号

    1. 将用户信息保存在自己的数据里
    • 微信公众号推送:

    1. 本地数据库中存放着小程序用户表和微信公众号的表,下面就是向某一个小程序用户推送微信公众号信息
    2. 在小程序用户表中任意取一个用户A信息,用户A的openId和unionId,通过unionId到公众号表里去检索对应的A用户微信公众号的openId
    3. 在微信公众号上选择一个模板消息,编辑完要发送的的内容后,再请求发送模板消息的接口

    地址:https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=ACCESS_TOKEN
    请求参数:

    {
      "touser": "OPENID",
      "template_id": "ngqIpbwh8bUfcSsECmogfXcV14J0tQlEpBO27izEYtY",
      "url": "http://weixin.qq.com/download",
      "miniprogram": {
        "appid": "xiaochengxuappid12345",
        "pagepath": "index?foo=bar"
      },
      "data": {
        "first": {
          "value": "恭喜你购买成功!",
          "color": "#173177"
        },
        "keyword1": {
          "value": "巧克力",
          "color": "#173177"
        },
        "keyword2": {
          "value": "39.8元",
          "color": "#173177"
        },
        "keyword3": {
          "value": "2014年9月22日",
          "color": "#173177"
        },
        "remark": {
          "value": "欢迎再次购买!",
          "color": "#173177"
        }
      }
    }
    
    参数是否必填说明
    template_id模板ID
    url模板跳转链接
    miniprogram跳小程序所需数据,不需跳小程序可不用传该数据
    appid所需跳转到的小程序appid(该小程序appid必须与发模板消息的公众号是绑定关联关系,暂不支持小游戏)
    pagepath所需跳转到小程序的具体页面路径,支持带参数,(示例index?foo=bar),暂不支持小游戏
    data模板数据
    color模板内容字体颜色,不填默认为黑色
    以上,为向微信小程序推送微信公众号的模板消息步骤。

    注:关于微信公众号不能推送的,或者推送报错的,推送的miniprogram下的appid对应的小程序必须是已审核并发布的才可以推送

    展开全文
  • 之前写了几篇关于微信小程序的开发实践,总的来说没啥难度,感兴趣的请移步:使用Mpvue配合Weui开发面试题题库微信小程序,并且发布到正式环境,这一次我们来尝试开发一下微信公众号,那么公众号小程序到底有什么...
  • 小程序公众号推送模板消息

    千次阅读 2020-08-27 15:15:26
    项目做成了小程序,原有公众号推送消息失效。 原因: 小程序的appid、secret与公众号的不一致; 小程序的opneid和微信公众号的openid不一致; 解决办法: 直接使用小程序openid( 此处是用户对小程序的openid,...
  • 微信小程序消息公众号推送

    千次阅读 多人点赞 2019-05-14 13:55:15
    上个礼拜研究了一下使用小程序公众号推送。 写一个攻略记录一下(代码都贴出来了,有一些从我代码中是从数据库中拿值的,大家酌情更改)。 准备工作如下: 一阶段 1、注册微信公众号。 2、注册微信小程序(可以从...
  • thinkphp 5.0 对接微信公众号,向指定用户发送模板消息
  • wx小程序,前端引导用户关注公众号推送消息 第一步: 在小程序登录后,请求后台得到返回是否关注公众号字段(如果有关注后台是有unionID的),将该字段存入storage中,在首页处拿来判断显隐‘ 引导关注公众号 ’的...
  • 微信公众号推送模板跳转小程序

    千次阅读 2020-04-03 15:12:17
    前几天因业务需求,需要点击模板消息跳转小程序,所以在此发篇博客记录一下。 代码如下: public void textTemplate(String deptExt) throws Exception { // 将信息封装到实体类中 TemplateMessage temp = new ...
  • Java 小程序推送模板消息公众号 具体逻辑 1.需用户先关注公众号 2.小程序端登录时前端静默授权获取code 3.后端根据code获取公众号appid 代码实现 1.获取公众号openId /** * 前端在小程序中通过静默授权获取code...
  • 最近做了一个类似于日程提醒的小程序,需要把用户语音识别出的日程或提醒按照设置的提醒日期通过微信公众号推送给对应的用户进行提醒这样子.这是需求背景. 这个项目我已经做完了,但是中间遇到很多坑,所以想出篇帖子,...
  • 微信小程序中模板消息推送功能实现代码,含前后端程序(PHP后端)
  • 微信小程序关联公众号(服务号)推送通知消息

    万次阅读 多人点赞 2018-12-25 11:08:30
    最近开发的一个小程序项目需要通过服务号来推送通知。但是在最开始开发小程序的时候并没有考虑到这个功能。 我在做小程序与服务号用户关联的过程中也是踩了无数坑,所以我会在这篇文章中给出自己摸索出的解决方案。...
  • 为了解决在管理员端可以主动发起某个指令,可以给用户推送小程序消息需求,共找出两个解决方案: 两个方案均已实现点击调转到对应小程序页面,同时可以主动多次进行发送(暂时公众号模板消息有条数限制)。 本文件...
  • 调用微信上传永久多媒体素材接口,获取mediaId ... * 上传图片 至公众号媒体素材 * accessToken 接口调用凭证 **/ public static String uploadImage(){ String accessToken = Redis.getInstance().get
  • JAVA微信小程序/公众号推送微信官方文档解读模板申请添加消息推送接口消息推送设计 微信官方文档解读 首先说一下小程序小程序现在都是订阅消息了,小程序模板消息接口已经被废弃。其中订阅消息分为两种。 第一种:...
  • 报这个错误是url错误,用这个即可 String url1 = "https://api.weixin.qq.com/cgi-bin/message/wxopen/template/uniform_send?access_token="+token;
  • 公众号推送信息如下 用户端查看的效果 素材推送 素材推送可以有文章,视频等内容,都是自己创作的内容。创作完成后,可以通过公众号后台的群发功能推送给用户。服务号每月可以群发四次,订阅号每天可以...
  • 关于推送前所需要获取的数据请移步:https://blog.csdn.net/weixin_44467567/article/details/112304488 第一步: 登录公众号后台创建模板消息 创建完成后点击详情 第二步 :代码实现 接口传参格式 { "touser":...
  • 本文实例讲述了微信小程序实现发送模板消息功能。分享给大家供大家参考,具体如下: 一、获取access_token access_token是接口调用的凭证,目前有效期为两个小时,需要定时刷新,重复获取将导致上次获取的access_...
  • 为了解决在管理员端可以主动发起某个指令,可以给用户推送小程序消息需求,共找出两个解决方案: 两个方案均已实现点击调转到对应小程序页面,同时可以主动多次进行发送(暂时公众号模板消息有条数限制)。 一、...
  • 最近在做微信小程序,为了让用户能更加方便的获取到小程序内部的通知,便想着用模板消息来解决此类问题。首先介绍一下两种方法 第一种是传统的按照微信开发文档来实现模板消息的获取,首先要明确的是你要有一个第三...
  • 小程序openid推送公众号模板消息

    千次阅读 2020-08-12 21:05:19
    可以通过小程序获取的openid 推送公众号模板消息消息 或者是公众号openid 推送公众号模板消息 推送前提: 1.需要用户关注微信公众号,不关注推送时会报错 2.需要公众号小程序有绑定的管理关系 参考小程序...
  • 如题,公众号推送小程序消息,打开参数option获取的是未定义的,哪位大神指导下是推送和接收有什么特别的地方
  • 消息推送----微信小程序,公众号

    万次阅读 2018-08-29 18:36:07
    微信小程序推送消息只有在以下情况: 1.微信支付回调; 2.提交form表单的时候; 微信小程序获取openid步骤(官网api文档都有): 官网api文档地址:https://developers.weixin.qq.com/miniprogram/dev/api...
  • 微信小程序推送模板消息功能,基于springboot ,包含前端和后端全流程
  • 难点:如何将微信公众号下openid和小程序下的openid进行关联
  • 点击推送消息后跳转到小程序中的某个页面,或者跳转到某一个网页上,例如有这样一个需求,在商城平台购买产品后,需要通过公众号给用户推送订单详细并且点击消息可以看到对应的订单详情。以下我将在微信公众号消息...

空空如也

空空如也

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

公众号推送小程序消息