微信公众号生成个性化推广二维码
文章目录
- 微信公众号生成个性化推广二维码
- 目标
- 环境要求
- 实现思路
- 获取二维码流程
- 概述
- 获取ticket
- 获取二维码下载地址
- 代码实现
- 核心代码
- 运行结果
微信公众号生成个性化推广二维码
目标
针对不同的推广场景,生成特定的公众号二维码,以便系统统计用户来源,提供个性化服务;
环境要求
- 后台语言:Java
- IDE:IDEA
- JDK:1.8
- 微信服务号
实现思路
通过微信公众号提供的生成带参数的二维码来实现用户来源的识别。
目前有两类带参数的二维码:
- 临时二维码,是有过期时间的,最长可以设置为在二维码生成后的30天(即2592000秒)后过期,但能够生成较多数量。临时二维码主要用于帐号绑定等不要求二维码永久保存的业务场景
- 永久二维码,是无过期时间的,但数量较少(目前为最多10万个)。永久二维码主要用于适用于帐号绑定、用户来源统计等场景。
当用户扫描带场景的二维码时,微信系统将向响应系统(什么是微信系统和响应系统?点击传送门)推送以下两种事件:
- 已关注用户将自动进入会话,微信系统将向响应系统推送带有场景值的扫描事件;
- 未关注用户则会先进入关注页面,如果用户选择关注公众号,那么微信系统将先推送关注事件给响应系统,然后再推送带有场景值的扫描事件;
获取二维码流程
概述
获取二维码一共分两步:
- 获取ticket:每次创建二维码ticket需要提供一个开发者自行设定的参数(scene_id),也就是场景值,该值即为响应系统接收扫描事件的场景值,该值可以为整型数字,可以为字符串;
- 通过ticket换取二维码:通过ticket换取二维码下载地址,该地址任何人都可访问;
获取ticket
因为有两种二维码,所以也有两种ticket
获取临时二维码ticket:
请求方式: POST
地址: https://api.weixin.qq.com/cgi-bin/qrcode/create?access_token=TOKEN
数据格式:json
数据示例:场景值为整型数字:{"expire_seconds": 604800, "action_name": "QR_SCENE", "action_info": {"scene": {"scene_id": 123}}}场景值为字符串:{"expire_seconds": 604800, "action_name": "QR_STR_SCENE", "action_info": {"scene": {"scene_str": "test"}}}
获取永久二维码ticket:
请求方式: POST
地址: https://api.weixin.qq.com/cgi-bin/qrcode/create?access_token=TOKEN
数据格式:json
数据示例:场景值为整型数字:{"action_name": "QR_LIMIT_SCENE", "action_info": {"scene": {"scene_id": 123}}}场景值为字符串:{"action_name": "QR_LIMIT_STR_SCENE", "action_info": {"scene": {"scene_str": "test"}}}
返回结果说明:
{"ticket":"gQH47joAAAAAAAAAASxodHRwOi8vd2VpeGluLnFxLmNvbS9xL2taZ2Z3TVRtNzJXV1Brb3ZhYmJJAAIEZ23sUwMEmm
3sUw==","expire_seconds":60,"url":"http://weixin.qq.com/q/kZgfwMTm72WWPkovabbI"}
首先贴上官方对参数的说明:
参数 | 说明 |
---|---|
expire_seconds | 该二维码有效时间,以秒为单位。 最大不超过2592000(即30天),此字段如果不填,则默认有效期为30秒。 |
action_name | 二维码类型,QR_SCENE为临时的整型参数值,QR_STR_SCENE为临时的字符串参数值,QR_LIMIT_SCENE为永久的整型参数值,QR_LIMIT_STR_SCENE为永久的字符串参数值 |
action_info | 二维码详细信息 |
scene_id | 场景值ID,临时二维码时为32位非0整型,永久二维码时最大值为100000(目前参数只支持1–100000) |
scene_str | 场景值ID(字符串形式的ID),字符串类型,长度限制为1到64 |
个人觉得不好理解的是action_name。
首先我们可以发现获取临时和永久ticket的地址是一样的!这说明我们需要传递一些信息告诉微信系统我们需要的是什么;然后我们可以发现的就是json的属性不一样,于是就产生了这样的疑问:是不是通过expire_seconds这个字段判断的呢?
接下里看参数说明,action_name的介绍为:“QR_SCENE为临时的整型参数值”。我没明白的是QR_SCENE到底是一个整型参数值,还是一个标记值。因为看到了参数值,所以就理解为“可变”的了,加上我们也的确有判断是否是永久的方法(expire_seconds存在与否),于是似乎理所当然。。。就出错了。
事实上,它是一个标记值,也就是微信系统应该是通过action_name来判断我们的目的是什么。不过问题也不大,程序跑起来就能明白这个问题到底是什么了,因为随意指定该属性的值会抛错:“invalid action name”;
获取二维码下载地址
获得ticket的同时,我们也获得了一个URL,这个URL即为二维码解析后的地址,此时我们就可以自己为该地址生成二维码图片了,比如美化一下什么的。不过我们也可以从微信系统那里获取下载地址。
GET请求(请使用https协议)https://mp.weixin.qq.com/cgi-bin/showqrcode?ticket=TICKET
提醒:TICKET记得进行UrlEncode
访问该地址即可获得对应场景、对应生命周期的二维码图片下载地址;
代码实现
核心代码
public class Main {public static void main(String[] args){//获取临时推广、场景值为字符串的二维码String temporaryQRCodeUrl= WeChatQRCodeManager.getTemporaryStrQRCodeDownloadUrl("teacher_wang");System.out.println(temporaryQRCodeUrl);//获取永久推广、场景值为字符串的二维码String permanentQRCodeUrl= WeChatQRCodeManager.getPermanentStrQRCodeDownloadUrl("teacher_liu");System.out.println(permanentQRCodeUrl);//获取临时推广、场景值为整型的二维码temporaryQRCodeUrl= WeChatQRCodeManager.getTemporaryIntQRCodeDownloadUrl(120);System.out.println(temporaryQRCodeUrl);//获取永久推广、场景值为整型的二维码permanentQRCodeUrl= WeChatQRCodeManager.getPermanentIntQRCodeDownloadUrl(119);System.out.println(permanentQRCodeUrl);}
}
public class WeChatQRCodeManager {/*** 获取临时特定场景推广二维码下载地址* @param sceneStr 临时特定场景的字符串标记* @return 二维码的下载地址* @see QRCodeInfo*/public static String getTemporaryStrQRCodeDownloadUrl(String sceneStr){QRCodeInfo info=new QRCodeInfo(false);info.setSceneStrId(sceneStr);return getQRCodeDownloadUrl(info);}/*** 获取永久特定场景推广二维码下载地址* @param sceneStr 永久特定场景的字符串标记* @return 二维码的下载地址* @see QRCodeInfo*/public static String getPermanentStrQRCodeDownloadUrl(String sceneStr){QRCodeInfo info=new QRCodeInfo(true);info.setSceneStrId(sceneStr);return getQRCodeDownloadUrl(info);}/*** 获取临时特定场景推广二维码下载地址* @param sceneInt 临时特定场景的整型标记* @return 二维码的下载地址* @see QRCodeInfo*/public static String getTemporaryIntQRCodeDownloadUrl(int sceneInt){QRCodeInfo info=new QRCodeInfo(false);info.setSceneIntId(sceneInt);return getQRCodeDownloadUrl(info);}/*** 获取永久特定场景推广二维码下载地址* @param sceneInt 永久特定场景的整型标记* @return 二维码的下载地址* @see QRCodeInfo*/public static String getPermanentIntQRCodeDownloadUrl(int sceneInt){QRCodeInfo info=new QRCodeInfo(true);info.setSceneIntId(sceneInt);return getQRCodeDownloadUrl(info);}/*** 获取二维码下载地址* @param info 二维码信息载体* @return 二维码下载地址* @see QRCodeInfo*/private static String getQRCodeDownloadUrl(QRCodeInfo info) {String responseString= HttpUtils.doPostJson(WeChatUrlManager.getQrCodeTicketUrl(),info.toJsonString());String ticket= JsonUtils.getTargetStringInfo("ticket",responseString);return WeChatUrlManager.getQrCodeUrl(ticket);}
}
/*** @author Shao Lixuan 2019/3/7 16:43*/
public class QRCodeInfo {private int expireSeconds;private String sceneStrId;private boolean isTemporary;private int sceneIntId;private boolean sceneIsStr;public QRCodeInfo(boolean temporary){isTemporary=temporary;sceneIsStr=true;}public boolean isTemporary() {return isTemporary;}public void setTemporary(boolean temporary) {isTemporary = temporary;}public int getExpireSeconds() {return expireSeconds;}public void setExpireSeconds(int expireSeconds) {this.expireSeconds = expireSeconds;}public String getSceneStrId() {return sceneStrId;}public void setSceneStrId(String sceneStrId) {this.sceneStrId = sceneStrId;sceneIsStr=true;}public int getSceneIntId() {return sceneIntId;}public void setSceneIntId(int sceneIntId) {this.sceneIntId = sceneIntId;sceneIsStr=false;}public String toJsonString(){String template;if(isTemporary){if(sceneIsStr) {template = "{\"expire_seconds\": %d, \"action_name\":\"QR_STR_SCENE\", \"action_info\": {\"scene\": {\"scene_str\": \"%s\"}}}";return String.format(template, expireSeconds, sceneStrId);}else{template = "{\"expire_seconds\": %d, \"action_name\":\"QR_SCENE\", \"action_info\": {\"scene\": {\"scene_str\": %d}}}";return String.format(template, expireSeconds, sceneIntId);}}else {if(sceneIsStr) {template = "{\"action_name\": \"QR_LIMIT_STR_SCENE\", \"action_info\": {\"scene\": {\"scene_str\": \"%s\"}}}";return String.format(template, sceneStrId);}else{template = "{\"action_name\": \"QR_LIMIT_SCENE\", \"action_info\": {\"scene\": {\"scene_str\": %d}}}";return String.format(template, sceneStrId);}}}
}
运行结果
https://mp.weixin.qq.com/cgi-bin/showqrcode?ticket=gQGh8TwAAAAAAAAAAS5odHRwOi8vd2VpeGluLnFxLmNvbS9xLzAyQllPSkFXRnVmRUMxMDAwMHcwN0QAAgRA5IBcAwQAAAAA
https://mp.weixin.qq.com/cgi-bin/showqrcode?ticket=gQGG8DwAAAAAAAAAAS5odHRwOi8vd2VpeGluLnFxLmNvbS9xLzAyMEtZaEJYRnVmRUMxS3NBMTFzY18AAgRg5IFcAwQ8AAAA
https://mp.weixin.qq.com/cgi-bin/sho wqrcode?ticket=gQHH8TwAAAAAAAAAAS5odHRwOi8vd2VpeGluLnFxLmNvbS9xLzAyaGFiTEFiRnVmRUMxMDAwMGcwM1EAAgTj04FcAwQAAAAA
https://mp.weixin.qq.com/cgi-bin/showqrcode?ticket=gQGK8DwAAAAAAAAAAS5odHRwOi8vd2VpeGluLnFxLmNvbS9xLzAyRVZNMUJTRnVmRUMxS3NBMXhzMW4AAgRg5IFcAwQ8AAAA
项目源码CSDN下载
微信公众号生成个性化推广二维码相关推荐
- 微信公众号扫描带参数二维码实现自动分组?
2019独角兽企业重金招聘Python工程师标准>>> 最近很多人都在问微信公众号扫描带参数二维码实现自动分组,通过微号帮平台操作实现,这个功能不止如此,微信二维码来源统计分析.微信 ...
- Java实现微信公众号直接发送参数二维码给用户
文章目录 前言 一.参数二维码的作用 二.功能实现 1. 生成带参数二维码 2. 上传二维码图片 3. 发送带参数二维码给用户 总结 前言 公众号开发近些年是一个比较热门的方向,今天为大家讲解的是用J ...
- 微信公众号扫描带参数二维码实现自动分组
学习交流: CSDN资源下载地址:https://download.csdn.net/download/naruto668/10624558 之前的几个老客户找到我最近要做一个微信公众号生成带参数海报 ...
- 微信公众号开发:渠道二维码生成/粉丝来源归属统计打标签
作为一个运营人?离不开一个话题:推广公号.每天打开公号后台第一眼:粉丝数 继续点开,统计--用户分析 用户增长:昨日/每天,每一样的数据(新增,取关,净增,累积) 用户属性:性别,年龄,地域等 那如果 ...
- 微信公众号开发,扫描二维码事件推送丢失参数问题
需求场景: 每个用户都有自己的推广二维码,分享自己推广二维码,别人扫码后跳转关注公众号,关注后绑定推荐关系. 用到技术点: 1.生成带参数二维码 2.接收事件推送,这里主要是关注和扫带参数二维码两个事 ...
- 微信渠道二维码怎么做?微信公众号怎么做渠道二维码?
因为公众平台没有生成渠道二维码功能,如果想要实现公众号的渠道二维码,可以用第三方平台微号帮提供的渠道二维码生成在线功能实现,渠道二维码主要用于统计各个渠道来源的粉丝,为公众号实现精准化推广,为公众号节 ...
- 渠道码是什么意思?微信公众号怎么设置渠道二维码?
渠道码是一种带参数的二维码,可以自动统计到渠道引流效果,可以对公众号的粉丝来源渠道进行统计. 渠道码的作用一般包括自定义回复.粉丝标签自定义管理.粉丝来源数据自动统计. 我们在公众号推广时可以使用渠道 ...
- 最新在线客服系统php代码微信软件公众号小程序app二维码聊天网站源码
最新在线客服系统php代码微信软件公众号小程序app二维码聊天网站源码 管理界面 独家长期更新日志(欢迎反馈BUG) 1.添加手机端前后台声音提示 2.添加后台客户管理显示在线离线 3.添加清空当前对 ...
- 微信公众号 订阅号 生成带参数二维码
1.公众号的任意一篇文章页链接 例如: http://mp.weixin.qq.com/s?__biz=MjM5NzAwNzMwMQ==&mid=2655787844&idx=3&am ...
- 利用微信公共号的带参数二维码做(扫码登录)
<script type="text/javascript">var t2 ='';$(function() {var rand = parseInt(Math.ran ...
最新文章
- 基于macos的Homebrew常用命令和使用教程(你得看❤️)
- numpy.arange详解
- 事务策略: 了解事务陷阱--转
- 分摊、分配、定期重过账
- Oracle ASM Cluster File Systems (ACFS)应用指南
- python--Time(时间)模块
- .NET中多线程调试的一个办法
- 模拟——生活大爆炸版石头剪刀布(洛谷 P1328)
- Linux中main和初启函数,main 中的 argv和argc 到底是个啥意思?
- QMutexLocker作用范围
- ORACLE 指令基础学习
- 爆销产品标题怎么写_7个让销量暴增的商品标题文案套路
- 动态域名解析NAT版结合绿盾加密解密软件使用方法
- 「教程」Windows程序未响应,怎么分析确认具体原因
- 微信小程序 时间轴(时间线)特效
- swoole php配置文件,EasySwoole分离配置文件
- 2022煤炭生产经营单位(安全生产管理人员)判断题及在线模拟考试
- android命令大全 pdf,android调试桥(adb)常用命令.pdf
- MySQL数据库 引擎
- 如何正确的对安卓手机进行数据恢复?