微信公众号生成带参数二维码跳转关注与未关注以及事件推送
发布日期:2021-05-06 19:33:02 浏览次数:17 分类:技术文章

本文共 6781 字,大约阅读时间需要 22 分钟。

首先说下业务场景

需要从某个页面生成二维码,用户扫描二维码,如果已关注公众号,跳到公众号页面,推送小程序链接
如果还未关注公众号,跳转到关注页面,关注公众号后推送小程序链接。
当然从公众号跳转到小程序,多多少少是需要带一点业务相关参数的。
本篇主要将二维码生成,以及事件推送

一、二维码生成

根据官方文档介绍,目前公众号二维码主要有永久和临时两种,但是永久二维码是有数量限制的,临时二维码携带参数又有限制。

所以我们一般都使用临时二维码
官方介绍
生成二维码的动作主要有两步,第一步根据参数拿到二维码ticket,第二步根据ticket换取二维码

首先看获取二维码的参数

二维码参数
拼接结构如下:{“action_name”: “QR_LIMIT_SCENE”, “action_info”: {“scene”: {“scene_id”: 123}}}
注意scene是在action_info 里面的
请求URL为 :https://api.weixin.qq.com/cgi-bin/qrcode/create?access_token=TOKEN 类型为POST
返回数据是这样的
{“ticket”:“gQH47joAAAAAAAAAASxodHRwOi8vd2VpeGluLnFxLmNvbS9xL2taZ2Z3TVRtNzJXV1Brb3ZhYmJJAAIEZ23sUwMEmm
3sUw==”,“expire_seconds”:60,“url”:“http://weixin.qq.com/q/kZgfwMTm72WWPkovabbI”}
下面上具体代码

/**     * 创建临时带参二维码     *     * @param accessToken   接口访问凭证     * @param expireSeconds 二维码有效时间,单位为秒,最大不超过1800     * @param sceneId       场景ID     * @return WeixinQRCode     */    public WeixinQRCode createTemporaryQRCode(String accessToken, int expireSeconds, String sceneStr) {           QRCodeParMapping byMappingValue = qrCodeParamMappingUtil.getQrcodeParMappingByMappingValue(sceneStr);        Integer mappingID = null;        if (byMappingValue == null) {               byMappingValue = new QRCodeParMapping();            byMappingValue.setMappingValue(sceneStr);            qrCodeParamMappingUtil.save(byMappingValue);        }        mappingID = byMappingValue.getMappingID();        sceneStr = mappingID.toString();        System.out.println("二维码携带参数为" + sceneStr);        WeixinQRCode weixinQRCode = null;        // 拼接请求地址        String requestUrl = "https://api.weixin.qq.com/cgi-bin/qrcode/create?access_token=ACCESS_TOKEN";        requestUrl = requestUrl.replace("ACCESS_TOKEN", accessToken);        // 需要提交的json数据        String jsonMsg = "{\"expire_seconds\": %d, \"action_name\": \"QR_SCENE\", \"action_info\": {\"scene\": {\"scene_id\": %s}}}";        // 创建临时带参二维码        JSONObject jsonObject = WechatUtil.httpsRequest(requestUrl, "POST",                String.format(jsonMsg, expireSeconds, sceneStr));        if (null != jsonObject) {               try {                   weixinQRCode = new WeixinQRCode();                weixinQRCode.setTicket(jsonObject.getString("ticket"));                weixinQRCode.setExpireSeconds(jsonObject.getInt("expire_seconds"));                logger.info("创建临时带参二维码成功 ticket:{} expire_seconds:{}", weixinQRCode.getTicket(),                        weixinQRCode.getExpireSeconds());            } catch (Exception e) {                   weixinQRCode = null;                int errorCode = jsonObject.getInt("errcode");                String errorMsg = jsonObject.getString("errmsg");                logger.error("创建临时带参二维码失败 errcode:{} errmsg:{}", errorCode, errorMsg);            }        }        return weixinQRCode;    }	/**     * 发起https请求并获取结果     *     * @param requestUrl    请求地址     * @param requestMethod 请求方式(GET、POST)     * @param outputStr     提交的数据     * @return JSONObject(通过JSONObject.get ( key)的方式获取json对象的属性值)     */    public static JSONObject httpsRequest(String requestUrl, String requestMethod, String outputStr) {           JSONObject jsonObject = null;        StringBuffer buffer = new StringBuffer();        try {               // 创建SSLContext对象,并使用我们指定的信任管理器初始化            TrustManager[] tm = {   new MyX509TrustManager()};            SSLContext sslContext = SSLContext.getInstance("SSL", "SunJSSE");            sslContext.init(null, tm, new java.security.SecureRandom());            // 从上述SSLContext对象中得到SSLSocketFactory对象            SSLSocketFactory ssf = sslContext.getSocketFactory();            URL url = new URL(requestUrl);            HttpsURLConnection httpUrlConn = (HttpsURLConnection) url.openConnection();            httpUrlConn.setSSLSocketFactory(ssf);            httpUrlConn.setDoOutput(true);            httpUrlConn.setDoInput(true);            httpUrlConn.setUseCaches(false);            // 设置请求方式(GET/POST)            httpUrlConn.setRequestMethod(requestMethod);            if ("GET".equalsIgnoreCase(requestMethod))                httpUrlConn.connect();            // 当有数据需要提交时            if (null != outputStr) {                   OutputStream outputStream = httpUrlConn.getOutputStream();                // 注意编码格式,防止中文乱码                outputStream.write(outputStr.getBytes("UTF-8"));                outputStream.close();            }            // 将返回的输入流转换成字符串            InputStream inputStream = httpUrlConn.getInputStream();            InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "utf-8");            BufferedReader bufferedReader = new BufferedReader(inputStreamReader);            String str = null;            while ((str = bufferedReader.readLine()) != null) {                   buffer.append(str);            }            bufferedReader.close();            inputStreamReader.close();            // 释放资源            inputStream.close();            inputStream = null;            httpUrlConn.disconnect();            jsonObject = JSONObject.fromObject(buffer.toString());        } catch (ConnectException ce) {               log.error("Weixin server connection timed out.");        } catch (Exception e) {               log.error("https request error:{}", e);        }        return jsonObject;    }/** * 临时二维码信息 *  * @author liufeng * @date 2013-11-10 */public class WeixinQRCode {   	// 获取的二维码ticket	private String ticket;	// 二维码的有效时间,单位为秒,最大不超过1800	private int expireSeconds;	public String getTicket() {   		return ticket;	}	public void setTicket(String ticket) {   		this.ticket = ticket;	}	public int getExpireSeconds() {   		return expireSeconds;	}	public void setExpireSeconds(int expireSeconds) {   		this.expireSeconds = expireSeconds;	}}一共两个方法  一个类第一个方法是生成二维码的步骤,三个参数:1、accessToken 请自备2、过期时间 3、二维码携带参数第二个方法是访问微信的GET请求第三个二维码实体类这里要额外说一个事情,第一个查询映射的方法,是干什么的首先上面参数有说过,二维码可携带参数有scene_id 和scene_str  但是临时二维码 只能用ID(关乎于后面的事件推送) 并且是32位非零整型,长度有限制,所以个人做了个参数映射,生成二维码码的参数在数据库关联一个ID,每次ID自增,每次传参要查询是否有对应的ID,没有就生成一个新的这部分逻辑很简单先不上代码了,如不需要,可自行注释代码,有需要可能后面会补。

这样我们就拿到了二维码的ticket

获取二维码就很简单了
通过访问链接就可以直接拿到二维码
官方是这么写的:
HTTP GET请求(请使用https协议)https://mp.weixin.qq.com/cgi-bin/showqrcode?ticket=TICKET
提醒:TICKET记得进行UrlEncode
ticket正确的情况下,状态码200,是一张图片可以下载。错误的话可能是404

这里额外再说一句,那个携带参数,即使是它不支持或者超出限制了,二维码仍然会正常返回,但是参数不会正常携带到后面的事件里面

二、事件接收以及消息推送

首先说事件接收,这个事件接收是一个很广的概念,可以接收很多类型的事件,官方是这么写的

事件
事件推送的URL需要在公众号后台自行配置,是一个URL哦~不同的事件按照分类进行区别开发
二维码的推送参数如下:
事件参数
这是我代码中打印的 已关注用户推送的
在这里插入图片描述
根据这个我们能拿到二维码携带过来的参数 就是Eventkey。
未关注用户推送的:
在这里插入图片描述
注意未关注用户的参数前面带一个qrscene_ 获取时自行截取

事件到了 我们需要做处理

这里返回的不是模版消息,是客服消息
看官方文档
在这里插入图片描述
消息类型是这样,我的需求是要跳转到小程序 并没有链接类型
所以就使用文本类型,里面自己嵌入链接,官方给出了方法

发送文本消息时,支持插入跳小程序的文字链文本内容点击跳小程序说明: 1.data-miniprogram-appid 项,填写小程序appid,则表示该链接跳小程序; 2.data-miniprogram-path项,填写小程序路径,路径与app.json中保持一致,可带参数; 3.对于不支持data-miniprogram-appid 项的客户端版本,如果有herf项,则仍然保持跳href中的网页链接; 4.data-miniprogram-appid对应的小程序必须与公众号有绑定关系。

下一篇详细介绍怎么回消息以及代码~

上一篇:Git commit代码后撤销方法
下一篇:springboot actuator简单使用教程

发表评论

最新留言

第一次来,支持一个
[***.219.124.196]2025年03月14日 18时54分12秒