上一篇讲了普通关注的各种情景,接下来准备详细讲解带参数的二维码的应用实例。在下一篇详解之前,这里先介绍一下如何下载二维码、生成二维码表,为后续的应用做好准备。
为了满足用户渠道推广分析和用户帐号绑定等场景的需要,公众平台提供了生成带参数二维码的接口。使用该接口可以获得多个带不同场景值的二维码,用户扫描后,公众号可以接收到事件推送。使用接口过程中有任何问题,可以前往微信开放社区 #公众号 专区发帖交流。
一、带参数二维码类型
目前有2种类型的二维码:
1、永久二维码,是无过期时间的,但数量较少(目前为最多10万个)。永久二维码主要用于适用于帐号绑定、用户来源统计等场景。
2、临时二维码,是有过期时间的,最长可以设置为在二维码生成后的30天(即2592000秒)后过期,但能够生成较多数量。临时二维码主要用于帐号绑定等不要求二维码永久保存的业务场景。
二、获取二维码方法
用户扫描带场景值二维码时,可能推送以下两种事件:
如果用户还未关注公众号,则用户可以关注公众号,关注后微信会将带场景值关注事件推送给开发者。
如果用户已经关注公众号,在用户扫描后会自动进入会话,微信也会将带场景值扫描事件推送给开发者。
获取带参数的二维码的过程包括两步,首先创建二维码ticket,然后凭借ticket到指定URL换取二维码。
创建二维码ticket
每次创建二维码ticket需要提供一个开发者自行设定的参数(scene_id),分别介绍临时二维码和永久二维码的创建二维码ticket过程。
临时二维码请求说明
http请求方式: POST URL: https://api.weixin.qq.com/cgi-bin/qrcode/create?access_token=TOKEN POST数据格式:json POST数据例子:{"expire_seconds": 604800, "action_name": "QR_SCENE", "action_info": {"scene": {"scene_id": 123}}} 或者也可以使用以下POST数据创建字符串形式的二维码参数:{"expire_seconds": 604800, "action_name": "QR_STR_SCENE", "action_info": {"scene": {"scene_str": "test"}}}
永久二维码请求说明
http请求方式: POST URL: https://api.weixin.qq.com/cgi-bin/qrcode/create?access_token=TOKEN POST数据格式:json POST数据例子:{"action_name": "QR_LIMIT_SCENE", "action_info": {"scene": {"scene_id": 123}}} 或者也可以使用以下POST数据创建字符串形式的二维码参数: {"action_name": "QR_LIMIT_STR_SCENE", "action_info": {"scene": {"scene_str": "test"}}}
三、代码实现
1、首先在网站根目录下创建QrCodeTg目录,用于存放获取的带参数二维码图片。
2、数据库中创建带参数二维码清单,创建语句如下
--带参数二维码配置表
CREATE TABLE weixin_qrcode_ticket
(
scene_id int, --带参数二维码id,用于查找二维码图片
create_time datetime, --从微信服务器获取二维码时间
qrcode_image_url nvarchar(100), --从微信服务器获取的二维码保存位置,生成自己的url
distribute_time datetime, --二维码分配给推广人、合伙人的时间
open_id nvarchar(40), --推广人、合伙人的openid
scan_image_url nvarchar(100), --扫码返回图文的logo图片链接
scan_title nvarchar(100), --扫码返回图文的文字标题
scan_title_sub nvarchar(100), --扫码返回图文的子标题
scan_redirect_url nvarchar(100), --扫码后如果直接跳转链接,导向新链接的网址
red_packet_flag nvarchar(4), --是否给扫码的微信用户发红包
red_packet_min float, --给扫码的微信用户发红包的随机值最小值
red_packet_max float, --给扫码的微信用户发红包的随机值最大值
r_red_packet_flag nvarchar(4), -是否给推广人发红包
r_red_packet_min float, --给推广人发红包的随机值最小值
r_red_packet_max float, --给推广人发红包的随机值最小值
logo_image_name nvarchar(100), --二维码对应商铺的LOGO
shop_name nvarchar(100), --二维码对应商铺的名称
shop_id nvarchar(12), --二维码对应商铺的id
user_id nvarchar(20), --推广人的编码,一般用手机号
user_name nvarchar(200), --推广人的姓名
scan_type nvarchar(20), --推广活动名称
scan_text nvarchar(200) --推广活动简介
)
3、使用微信服务器提供的api接口,批量下载二维码图片到QrCodeTg目录,并把记录添加到weixin_qrcode_ticket表中。
前端页面:QrCode.aspx
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="QrCode.aspx.cs" Inherits="Jjlm.QrCode" %>
<!DOCTYPE html>
<html>
<head id="Head1" runat="server">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<link href="Css/SqltIndex.css" rel="stylesheet" type="text/css" />
<title>获取指定范围二维码</title>
<style>
</style>
</head>
<body style="text-align:center;width:100%;margin:0 auto;background-color: #ffffff;">
<center>
<form id="form1" runat="server">
<div>
</div>
<asp:Label runat="server" id="lbResult"/></br></br>
<asp:Label runat="server" id="lbopenid" Visible="false"/></br>
</form>
</center>
</body>
</html>
后端页面:QrCode.aspx.cs
using System;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Data;
using System.Data.SqlClient;
using System.Text;
using System.Text.RegularExpressions;
using LitJson;
using System.Net;
using System.IO;
using QinMing.Config;
using QinMing.WeixinContainer;
using QinMing.Tools;
namespace Jjlm
{
public partial class QrCode : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
if(QinMing.Tools.QinMingTools.IsHasSQLInject(Request.QueryString["snum"]))
{
Response.Write("请勿非法尝试!");
Response.End();
}
if(QinMing.Tools.QinMingTools.IsHasSQLInject(Request.QueryString["enum"]))
{
Response.Write("请勿非法尝试!");
Response.End();
}
SqlConnection conn = new SqlConnection(QinMingConfig.DatabaseConnStr);
conn.Open();
SqlCommand cmd = new SqlCommand();
cmd.Connection = conn;
SqlConnection conn1 = new SqlConnection(QinMingConfig.DatabaseConnStr);
conn1.Open();
SqlCommand cmd1 = new SqlCommand();
cmd1.Connection = conn1;
SqlDataReader dr1;
string start_num = Request.QueryString["snum"];
string end_num = Request.QueryString["enum"];
for(int i = Convert.ToInt32(start_num); i <= Convert.ToInt32(end_num); i = i + 1)
{
cmd1.CommandText = "select * from weixin_qrcode_ticket where scene_id=" + i.ToString() + " ";
dr1 = cmd1.ExecuteReader();
if (dr1.Read())
{
//库内已存在该scene_id的带参数二维码,不再重复生成
}
else
{
string tmpurl = GetewmPic(i.ToString());
cmd.CommandText = "insert into weixin_qrcode_ticket (scene_id,create_time,qrcode_image_url) values("
+ i.ToString() + ",getdate(),'" + tmpurl + "')";
cmd.ExecuteScalar();
}
dr1.Close();
}
cmd1.CommandText = "select max(scene_id) max_scene_id from weixin_qrcode_ticket ";
dr1 = cmd1.ExecuteReader();
if (dr1.Read())
{
lbResult.Text = "目前带参数二维码已生成总数为:" + dr1["max_scene_id"].ToString();
}
dr1.Close();
if (conn.State == ConnectionState.Open)
{
conn.Close();
conn.Dispose();
}
if (conn1.State == ConnectionState.Open)
{
conn1.Close();
conn1.Dispose();
}
}
}
public string GetewmPic(string scene_id)
{
QinMingWeixinContainer gt=new QinMingWeixinContainer();
string access_token = gt.GetAccessToken();
string tocket = "";
string pic="";
string poster = "{\"action_name\": \"QR_LIMIT_SCENE\",\"action_info\": {\"scene\": { \"scene_id\": " + scene_id + " } } }";//二维码永久请求格式
string tockes = GetPage("https://api.weixin.qq.com/cgi-bin/qrcode/create?access_token=" + access_token, poster);
//return tockes;
if(tockes.IndexOf("ticket") > -1)
{
JsonData bejson = JsonMapper.ToObject(tockes);
tocket = (String)bejson["ticket"];
tocket = Uri.EscapeDataString(tocket); //TICKET必需UrlEncode
}
//return tocket;
string Picurl = "https://mp.weixin.qq.com/cgi-bin/showqrcode?ticket=" + tocket;
HttpWebRequest req = (HttpWebRequest)WebRequest.Create(Picurl);
System.Drawing.Image img = System.Drawing.Image.FromStream(req.GetResponse().GetResponseStream());
string newfilename = "qrcode_tg_" + scene_id + ".jpg";//二维码图片路径
string address = HttpContext.Current.Server.MapPath("/QrCodeTg/" + newfilename);
img.Save(address);
pic = "QrCodeTg/" + newfilename;
return pic;
}
public static string GetPage(string posturl, string postData)
{
Stream outstream = null;
Stream instream = null;
StreamReader sr = null;
HttpWebResponse response = null;
HttpWebRequest request = null;
Encoding encoding = Encoding.UTF8;
byte[] data = encoding.GetBytes(postData);
// 准备请求...
try
{
// 设置参数
request = WebRequest.Create(posturl) as HttpWebRequest;
CookieContainer cookieContainer = new CookieContainer();
request.CookieContainer = cookieContainer;
request.AllowAutoRedirect = true;
request.Method = "POST";
request.ContentType = "application/x-www-form-urlencoded";
request.ContentLength = data.Length;
outstream = request.GetRequestStream();
outstream.Write(data, 0, data.Length);
outstream.Close();
//发送请求并获取相应回应数据
response = request.GetResponse() as HttpWebResponse;
//直到request.GetResponse()程序才开始向目标网页发送Post请求
instream = response.GetResponseStream();
sr = new StreamReader(instream, encoding);
//返回结果网页(html)代码
string content = sr.ReadToEnd();
string err = string.Empty;
return content;
}
catch (Exception ex)
{
string err = ex.Message;
return string.Empty;
}
}
}
}
四、结果演示
在浏览器地址栏输入http://www.yourweb.com/weixin/QrCode.aspx?snum=1&enum=1000
QrCodeTg目录将会下载scene_id编号为1-1000的二维码图片。