和小猪一起搞微信公众号开发—二维码创建使用流程(需要授权)

摘要:
第一步:成为一名开发人员,并确认您有权使用该界面。有关详细信息,请参见步骤1和步骤2:从微信服务器接收并保存信息。我们在Piglet的微信公众号开发中介绍了一个简单的文本:在微信上,当用户与公众号交互时,实际上是用户=“微信服务器=”公众号服务器=“微服务器=”用户的整个过程。

使用该接口可以获得多个带不同场景值的二维码,用户扫描后,公众号可以接收到事件推送。

目前有2种类型的二维码,分别是临时二维码和永久二维码,前者有过期时间,最大为1800秒,但能够生成较多数量,后者无过期时间,数量较少(目前参数只支持1--1000)。两种二维码分别适用于帐号绑定、用户来源统计等场景。

用户扫描带场景值二维码时,可能推送以下两种事件:

  1. 如果用户还未关注公众号,则用户可以关注公众号,关注后微信会将带场景值关注事件推送给开发者。
  2. 如果用户已经关注公众号,在用户扫描后会自动进入会话,微信也会将带场景值扫描事件推送给开发者。

获取带参数的二维码的过程包括两步,首先创建二维码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": 1800, "action_name": "QR_SCENE", "action_info": {"scene": {"scene_id": 123}}}

永久二维码请求说明

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}}}

参数说明

参数

说明

expire_seconds

该二维码有效时间,以秒为单位。 最大不超过1800。

action_name

二维码类型,QR_SCENE为临时,QR_LIMIT_SCENE为永久

action_info

二维码详细信息

scene_id

场景值ID,临时二维码时为32位整型,永久二维码时最大值为1000

 

返回说明

正确的Json返回结果:

{"ticket":"gQG28DoAAAAAAAAAASxodHRwOi8vd2VpeGluLnFxLmNvbS9xL0FuWC1DNmZuVEhvMVp4NDNMRnNRAAIEesLvUQMECAcAAA==","expire_seconds":1800}

参数

说明

ticket

获取的二维码ticket,凭借此ticket可以在有效时间内换取二维码。

expire_seconds

二维码的有效时间,以秒为单位。最大不超过1800。

 

错误的Json返回示例:

{"errcode":40013,"errmsg":"invalid appid"}

通过ticket换取二维码

获取二维码ticket后,开发者可用ticket换取二维码图片。请注意,本接口无须登录态即可调用。

请求说明

HTTP GET请求(请使用https协议)
https://mp.weixin.qq.com/cgi-bin/showqrcode?ticket=TICKET

返回说明

ticket正确情况下,http 返回码是200,是一张图片,可以直接展示或者下载。

HTTP头(示例)如下:
Accept-Ranges:bytes
Cache-control:max-age=604800
Connection:keep-alive
Content-Length:28026
Content-Type:image/jpg
Date:Wed, 16 Oct 2013 06:37:10 GMT
Expires:Wed, 23 Oct 2013 14:37:10 +0800
Server:nginx/1.4.1

错误情况下(如ticket非法)返回HTTP错误码404。

带参数二维码使用

当我们使用上述接口生成了二维码图片之后当用户对二维码扫描时(必须使用微信的扫一扫功能),微信服务器或者微信会做这么两件事:

  1. 如果用户还未关注公众号,则用户可以关注公众号,关注后微信会将带场景值关注事件推送给开发者。
  2. 如果用户已经关注公众号,则微信会将带场景值扫描事件推送给开发者。

下面小猪带大家一起来开发这么一个需求:当用户是使用普通的方式关注我们公众号时,则推送一个普通信息,当通过扫描带参数二维码时我们把欢迎次做适当的做一些更改后返回给用户。

第一步:成为开发者并确认拥有使用接口的权限

具体请查看:和小猪一起搞微信公众号开发—回复简单文本中的第一步和第二步

第二步:接收并保存微信服务器的信息推送

我们在和小猪一起搞微信公众号开发—回复简单文本中介绍过:在微信上面,当用户与公众号进行交互时,其实是 用户=》微信服务器=》公众号服务器=》微信服务器=》用户  的一整个过程。而如果用户关注公众号和取消关注公众号时同样会有上述的过程。

首先我们将微信推送过来的信息保存到数据库,以便以后对数据进行分析(省略了BLL层以及DAL层的代码,本系列文章重点介绍微信开发):

string xmlFromWeChat =new StreamReader(Request.InputStream).ReadToEnd();
Entity.WeChat.Event XMLContent = new Entity.WeChat.Event()
{
    XMLContent = xmlFromWeChat,
    CreateDate = System.DateTime.Now
};
eventHelper.Insert(XMLContent);

上述代码小猪定义了一个实体类:Entity.WeChat.Event:

/*==========================================================
*作者:SmallerPig
*时间:2013/12/9 14:10:01
*版权所有:无锡睿阅数字科技有限公司
============================================================*/
namespace Entity.WeChat
{
    public class Event
    {
        public Event()
        {

        }

        public int Id { get; set; }

        public string XMLContent { get; set; }

        public DateTime CreateDate { get; set; }

        public Event(DataAccess.WeChat_Event parent)
        {
            this.Id = parent.Id;
            this.XMLContent = parent.XMLContent;
            this.CreateDate = parent.CreateDate;
        }
    }
}

第三步:对事件类型进行读取判断处理:

完整的Action代码如下:

[HttpPost]
public ActionResult Login()
{
    string xmlFromWeChat =new StreamReader(Request.InputStream).ReadToEnd();
    Entity.WeChat.Event XMLContent = new Entity.WeChat.Event()
    {
        XMLContent = xmlFromWeChat,
        CreateDate = System.DateTime.Now
    };
    eventHelper.Insert(XMLContent);
    XmlDocument xmldocument = new XmlDocument();
    xmldocument.LoadXml(xmlFromWeChat);
    string msgtype = xmldocument.GetElementsByTagName("MsgType").Item(0).InnerText.ToUpper();
    msgType type = (msgType)Enum.Parse(typeof(msgType), msgtype);
    return Content(ProcessMSG(type, xmldocument));//这个函数来针对各种类型进行具体的处理
}

在上述代码中小猪为了方便对事件的判断定义了这么一个枚举来表示推送类型:

enum msgType : int
{
    TEXT = 0,//文本
    IMAGE = 1,//图片
    VOICE = 2,//声音
    VIDEO = 3,//视频
    LOCATION = 4,//地理位置
    LINK = 5,//链接
    EVENT = 6//事件
}

第四步:针对关注事件进行相关的逻辑处理并返回信息

private string replyEvent(msgType type, XmlDocument xmldocument)
{
    string fromUserName = xmldocument.GetElementsByTagName("FromUserName").Item(0).InnerText;
    string Event = xmldocument.GetElementsByTagName("Event").Item(0).InnerText;
    if (Event == "subscribe")
    {
        string toContent;
        toContent = "亲爱的用户您好! 
欢迎您的关注!呵呵,这里是小猪的欢迎词,该欢迎词只在您关注本账号时出现!";
        string testresult = new ReturnContent(FROM, fromUserName, toContent).ToString();//From值为固定的公众微信号
        return testresult;
    }
    else
        return null;
}

到目前为止:我们已经实现了当用户关注公众号时返回一个欢迎词,但是这里还未对用户的来源做判断,也就是说不管用户是通过什么方式关注的我们都使用固定的欢迎词。

第五步:针对扫描带参数二维码的关注事件进行判断

private string replyEvent(msgType type, XmlDocument xmldocument)
{
    string fromUserName = xmldocument.GetElementsByTagName("FromUserName").Item(0).InnerText;
    string Event = xmldocument.GetElementsByTagName("Event").Item(0).InnerText;
    if (Event == "subscribe")
    {
        string toContent;
        string key = xmldocument.GetElementsByTagName("EventKey").Item(0).InnerText;
        if (key.StartsWith("qrscene_"))
        {
            toContent = "亲爱的用户您好! 
欢迎您通过扫面带参数二维码进行关注,这里是小猪的欢迎词,该欢迎词只在您关注本账号时出现!";
        }
        else
        {
            toContent = "亲爱的用户您好! 
欢迎您的关注!呵呵,这里是小猪的欢迎词,该欢迎词只在您关注本账号时出现!";
        }
        string testresult = new ReturnContent(FROM, fromUserName, toContent).ToString();
        return testresult;
    }
    else
        return null;
}

在这一步我们对事件的EventKey字段做了获取操作,如果该字段的值是以“qrscene_”开头,那么该事件来源于扫描带参数二维码(默认关注推荐该值为空)。

ps:在实际项目应用过程中我们可以针对这一步进行很多的操作,例如可以判断用户是从那里引进过来(根据给不同的二维码图片带上不同的参数,然后在这一步获取参数),方便做来源统计等等。

上述代码小猪额外编写了一个通用的消息返回类:

class ReturnContent
{
    public ReturnContent(string from, string to, string content)
    {
        this.From = from;
        this.To = to;
        this.Content = content;
    }

    public string From { get; set; }
    public string To { get; set; }
    public string Content { get; set; }

    public override string ToString()
    {
        string testresult = string.Format("<xml><ToUserName><![CDATA[{0}]]></ToUserName>"
            + "<FromUserName><![CDATA[{1}]]></FromUserName>"
            + "<CreateTime>12345678</CreateTime><MsgType><![CDATA[text]]></MsgType>"
            + "<Content><![CDATA[{2}]]></Content></xml>", To, From, Content);
        return testresult;
    }
}

第六步:完工

说明:

  1. 目前小猪使用的wp版的微信步支持扫描带参数二维码功能。
  2. 目前使用小猪的用手机好申请测试公众号的方式无法接收到已关注者扫描二维码的推送,据说微信认证后不存在该问题。

免责声明:文章转载自《和小猪一起搞微信公众号开发—二维码创建使用流程(需要授权)》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇EntityFrameworkCore之工作单元的封装搜索插件——autocomplete下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

JavaEE-02 JSP数据交互01

学习要点 request对象 response对象 转发与重定向 session对象 include指令 课程回顾 需求描述:编写JSP页面,计算2000—3000年中存在几个闰年。 实现分析:判断闰年的算法写在方法boolean leapYear(int year)中。 提示:闰年——能够被4整除而不能被100整除,或者能够被400整除。 JSP...

企业微信中的应用调起微信支付,支付不成功

问题描述:   最近在做一个支付接入。在企业微信中的工作台里面打开一个应用链接,选择商品,点击支付的时候,拉起商城的支付页,提示《请在微信你客户端打开链接》,点击去到微信,微信拉起密码输入框,输入密码以后,等待10多 秒以后。提示“系统繁忙,请稍后再试”。 解决方法:   (还没解决,先记录问题。)...

读取文件将 Excel 文件 转换成 CSV 文件 解决方案

本文纯属个人见解,是对前面学习的总结,如有描述不正确的地方还请高手指正~     考参:     http://www.codeproject.com/Articles/246772/Convert-xlsx-xls-to-csv     http://exceldatareader.codeplex.com/          做法:从excel中把数据...

JSON反序列化接口的问题

今天在使用JSON序列化类时出现问题,原来类中有一个接口,在反序列化时不知道接口的实体是什么 public class Device : IComparer { private string _deviceid; private string _devicename; private string _deviceaddr = "01"; private s...

基于Map多种方式实现简单的缓存处理

通过HashMap进行缓存 private static Map<String, Object>cacheMap; public staticObject getCache(String key, Object defaultValue) { Object obj =getCacheMap().get(key)...

Java格式化字符串,左对齐,左补0

今天在做java编程实现邮件发送的时候,遇到邮件发送的内容涉及表格形式的数据,不适合用附件,只能用对齐的形式来展现表格内容,一开始很苦恼,不知道该怎么对齐,最后写了下面这个函数,实现了格式化字符串,左对齐的功能,很简单的函数,却解决了问题。   下面这段代码,可以处理字符串的左对齐输出,可以自定义补充的字符(不仅限于‘ ’),可以自定义补充后字符串的长度。...