• 第一步:登录微信公众号,绑定网页开发者   在登录后的界面中,我们向下拉在左侧会看到有一个“开发者工具”点击。 这时在开发者工具中,会看到有好几个工具,其中有一个“web开发者工具”,我们点击进入。 ...

    第一步:登录微信公众号,绑定网页开发者

        

    在登录后的界面中,我们向下拉在左侧会看到有一个“开发者工具”点击。

    这时在开发者工具中,会看到有好几个工具,其中有一个“web开发者工具”,我们点击进入。

     

     

    在这里,我们就会看到有一个“绑定开发者微信号”按钮,我们点击。

    进入后,我们输入需要绑定的微信号,点击“邀请绑定”按钮即可,然后在手机上确认一下即可。

    展开全文
  • 解绑 ...手机微信——公众平台安全助手——绑定查询——微信号绑定账号——公众号——选择运营者栏目下的公众号——解绑 找回 有时候公众号长期不用,忘了登陆账号和密码,这时我们需要找回: ...

    解绑

    微信规定每个微信号最多只能绑定5个公众号(包括管理员和运营者)

    有些时候我们需要绑定新的公众号,但是发现已经达到绑定上限了,而我们自己也忘了自己绑定过哪些公众号。
    这时我们需要解绑一些不常用的公众号:
    手机微信——公众平台安全助手——绑定查询——微信号绑定账号——公众号——选择运营者栏目下的公众号——解绑

    找回

    有时候公众号长期不用,忘了登陆账号和密码,这时我们需要找回:
    手机微信——公众平台安全助手——绑定查询——微信号绑定账号——公众号——公众号名字下面会显示微信账号,这样就找到了登录账号,下面输入正确的密码就可以登录进公众号

    展开全文
  • 资源中心包 ...amp;t=resource/res_list&verify=1&id=open1419319164&token=&lang=zh_CN   微信开发者工具下载地址 https://developers.weixi...
    展开全文
  • 微信用户和公众号产生交互的过程中,用户的某些操作会使得微信服务器通过事件推送的形式通知到开发者开发者中心处设置的服务器地址,从而开发者可以获取到该信息。其中,某些事件推送在发生后,是允许开发者回复...

    1、概述

    在微信用户和公众号产生交互的过程中,用户的某些操作会使得微信服务器通过事件推送的形式通知到开发者在开发者中心处设置的服务器地址,从而开发者可以获取到该信息。其中,某些事件推送在发生后,是允许开发者回复用户的,某些则不允许

    我们在上一篇微信公众号开发C#系列-6、消息管理-普通消息接受处理中讲到,微信的消息可以大体分为两种类型,一种是包括:文本,语音,图片等的普通消息,另一种就是本篇要将的事件类型。包括:关注/取消关注事件,扫描带参数二维码事件,上报地理位置事件,自定义菜单相关事件等,本篇一一进行讲解。介于偏于内容过多易产生阅读疲劳,对于自定义菜单相关事件的处理我们放在下一篇中讲解。

    这里的消息指的是传统的微信公众平台消息交互,微信用户向公众号发送消息后,公众号回复消息给微信用户。包括以下类型:

    1. 关注/取消关注事件:subscribe/unsubscribe
    2. 扫描带参数二维码事件:scan
    3. 上报地理位置事件:location
    4. 自定义菜单事件
    5. 点击菜单拉取消息时的事件推送
    6. 点击菜单跳转链接时的事件推送

    本篇主要介绍前三种。

    2、实现方式

    使用Senparc.Weixin框架来快速处理各种接收事件推送,实现非常简单,自定义一个继承MessageHandler的类,重写这些类型的方法即可。注意:DefaultResponseMessage必须重写,用于返回没有处理过的消息类型(也可以用于默认消息,如帮助信息等);其中所有原OnXX的抽象方法已经都改为虚方法,可以不必每个都重写。若不重写,默认返回DefaultResponseMessage方法中的结果。

    自定义消息处理类:

    public partial class CustomMessageHandler : MessageHandler<MessageContext<IRequestMessageBase, IResponseMessageBase>>
    {
        public CustomMessageHandler(Stream inputStream, int maxRecordCount = 0)
            : base(inputStream, null, maxRecordCount)
        {
            WeixinContext.ExpireMinutes = 3;
        }
        public override void OnExecuting()
        {
            //测试MessageContext.StorageData
            if (CurrentMessageContext.StorageData == null)
            {
                CurrentMessageContext.StorageData = 0;
            }
            base.OnExecuting();
        }
        public override void OnExecuted()
        {
            base.OnExecuted();
            CurrentMessageContext.StorageData = ((int)CurrentMessageContext.StorageData) + 1;
        }
    }
    

    定义好事件处理类后,分别重写上面提到几种接收事件推送的事件即可。
    我们可以通过重写MessageHandler里的这几种类型方法来处理我们的业务,当然也可以只重写需要的部分类型,不需要的类型可以不重写,只需要定义一个统一的DefaultResponseMessage

    public override IResponseMessageBase DefaultResponseMessage(IRequestMessageBase requestMessage)
    {
        //所有没有被处理的消息会默认返回这里的结果
        var responseMessage = this.CreateResponseMessage<ResponseMessageText>();
        responseMessage.Content = "这条消息来自DefaultResponseMessage。";
        return responseMessage;
    }
    

    3、消息的去重的重要性

    上一篇我们就已经提到过微信服务器在5秒内收不到响应会断掉连接,并且重新发起请求,总共重试三次。如此以来,我们模拟有这样一个场景:当用户关注微信账号时,获取当前用户信息,然后将信息写到数据库中,类似网站的注册。假设这个关注事件中,我们需要处理比较复杂的业务逻辑。如送积分,写用户日志,分配用户组等等一系列的逻辑需要执行,或者网络环境比较复杂,无法保证5秒内响应当前用户的操作,那如果当操作尚未完成,微信服务器又给我们的服务器推送了一条相同的关注事件,我们将再次执行我们的那些逻辑,这样就有可能导致数据库中出现重复的数据(有的童鞋就会说了,我在插入数据之前先判断当前是否已经存在了,如果存在了就不执行插入的操作。我想说的是,我当初也是这样想的,但真实的运行环境和我们的调试环境还是有差距的,直到发现数据库中有不少重复的用户信息时,我才发现消息去重的重要性。)。

    消息的去重普通消息和事件消息是有区别的。普通消息使用msgid,而事件消息使用FromUserName + CreateTime。

    4、关注/取消关注事件

    用户在关注与取消关注公众号时,微信会把这个事件推送到开发者填写的URL。方便开发者给用户下发欢迎消息或者做帐号的解绑。

    假如服务器无法保证在五秒内处理并回复,可以直接回复空串,微信服务器不会对此作任何处理,并且不会发起重试。

    关注或取消事件推送XML数据包示例:

    <xml>
      <ToUserName><![CDATA[toUser]]></ToUserName>
      <FromUserName><![CDATA[FromUser]]></FromUserName>
      <CreateTime>123456789</CreateTime>
      <MsgType><![CDATA[event]]></MsgType>
      <Event><![CDATA[subscribe]]></Event>
    </xml>
    

    参数说明:

    参数				描述
    ToUserName		开发者微信号
    FromUserName	发送方帐号(一个OpenID)
    CreateTime		消息创建时间 (整型)
    MsgType			消息类型,event
    Event			事件类型,subscribe(订阅)、unsubscribe(取消订阅)
    

    4.1 关注事件

    关注事件我们只需要重写OnEvent_SubscribeRequest事件代码即可,如下我们返回了一个文本消息,实现代码参考:

    /// <summary>
    /// 订阅(关注)事件
    /// </summary>
    /// <returns></returns>
    public override IResponseMessageBase OnEvent_SubscribeRequest(RequestMessageEvent_Subscribe requestMessage)
    {
    	var responseMessage = CreateResponseMessage<ResponseMessageNews>();
        foreach (var model in messageList)
        {
            responseMessage.Articles.Add(new Article()
            {
                Title = "国思公众号",
                Description = "欢迎关注国思软件公众号,更多内容稳步官网,多谢!",
                PicUrl = "http://www.rdiframework.net/WeiXin.png",
                Url = "http://www.rdiframework.net/"
            });
        }
        return responseMessage;
    }
    

    关注事件执行后效果

    在上面的关注事件中,用户关注公众号就会自动执行上面的事件代码,我们就可以在事件代码中做相关的业务处理,如绑定用户分组、增加用户到本地等等。同时推送一条欢迎消息返回到用户手机上。

    4.2 取消关注事件

    取消关注事件与关注事件类似,主要是事件变成了unsubscribe(取消关注)。取消关注事件-unsubscribe的主要意义在于及时删除网站应用中已经记录的OpenID绑定,消除冗余数据,并且关注用户流失的情况。

    取消关注事件我们只需要重写OnEvent_UnsubscribeRequest事件代码即可,如下我们返回了一个文本消息,实现代码参考:

    /// <summary>
    /// 退订/取消关注
    /// 实际上用户无法收到非订阅账号的消息,所以这里可以随便写。
    /// unsubscribe事件的意义在于及时删除网站应用中已经记录的OpenID绑定,消除冗余数据。并且关注用户流失的情况。
    /// </summary>
    /// <returns></returns>
    public override IResponseMessageBase OnEvent_UnsubscribeRequest(RequestMessageEvent_Unsubscribe requestMessage)
    {
        int returnValue = RDIFrameworkService.Instance.WeixinBasicService.UserUnsubscribeByOpenId(Id,requestMessage.FromUserName);//退
        var responseMessage = base.CreateResponseMessage<ResponseMessageText>();
        responseMessage.Content = "有空再来";
        return responseMessage;
    }
    

    上面的代码在用户取消公众号的关注时就会自动执行,可以看到我们有一行代码针对用户取消关注时执行的业务逻辑,同时返回了一个文本消息。实际用户已经取消关注,返回的消息也返回不到用户手机上的。

    5、扫描带参数二维码事件

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

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

    5.1 接口展示与实现方式

    对于第一种上面已经讲了,这里就只说明下第二种。

    推送XML数据包示例:

    <xml>
      <ToUserName><![CDATA[toUser]]></ToUserName>
      <FromUserName><![CDATA[FromUser]]></FromUserName>
      <CreateTime>123456789</CreateTime>
      <MsgType><![CDATA[event]]></MsgType>
      <Event><![CDATA[SCAN]]></Event>
      <EventKey><![CDATA[SCENE_VALUE]]></EventKey>
      <Ticket><![CDATA[TICKET]]></Ticket>
    </xml>
    

    参数说明:

    参数				描述
    ToUserName		开发者微信号
    FromUserName	发送方帐号(一个OpenID)
    CreateTime		消息创建时间 (整型)
    MsgType			消息类型,event
    Event			事件类型,SCAN
    EventKey		事件KEY值,是一个32位无符号整数,即创建二维码时的二维码scene_id
    Ticket			二维码的ticket,可用来换取二维码图片
    

    对于生成带参数的二维码我们会在后面的文章中专门介绍,这儿我们了解一个这个概念。为了满足用户渠道推广分析和用户帐号绑定等场景的需要,公众平台提供了生成带参数二维码的接口。使用该接口可以获得多个带不同场景值的二维码,用户扫描后,公众号可以接收到事件推送。具体官方技术文档可参考:生成带参数的二维码

    目前有2种类型的二维码:

    1、临时二维码,是有过期时间的,最长可以设置为在二维码生成后的30天(即2592000秒)后过期,但能够生成较多数量。临时二维码主要用于帐号绑定等不要求二维码永久保存的业务场景

    2、永久二维码,是无过期时间的,但数量较少(目前为最多10万个)。永久二维码主要用于适用于帐号绑定、用户来源统计等场景。

    扫描带参数二维码事件只需要重写OnEvent_ScanRequest事件代码即可,如下我们返回了一个文本消息,实现代码参考:

    public override IResponseMessageBase OnEvent_ScanRequest(RequestMessageEvent_Scan requestMessage)
    {
        //通过扫描关注
        var responseMessage = CreateResponseMessage<ResponseMessageText>();
    
        responseMessage.Content = responseMessage.Content ?? string.Format("欢迎关注国思软件,通过扫描二维码进入,场景值:{0}", requestMessage.EventKey);
    
        return responseMessage;
    }
    

    在上面的代码中用户扫描了带场景值的二维码进入公众号后我们返回了一个提示的文本消息。这是非常有用的功能,常用途推广,可以根据不同的二维码场景值分别做不同的业务处理,如可以统计关注的每一个粉丝从哪里来的,做到渠道推广分析,但是关注的都是同一个公众号。

    5.2 生成带参数的二维码用途

    微信公众号生成带参数的二维码有何用途?

    1. 可以区分粉丝来源,只需要生成不同的带参数的二维码,把这些二维码分别投放到各个渠道,粉丝通过这些渠道二维码进来就可以区分粉丝来源,微号帮后台渠道粉丝列表中有粉丝数及明细;
    2. 粉丝通过扫描渠道二维码关注公众号,会打标签分组,比如粉丝扫商店A、B的二维码进来的, 在微信公众号后来的用户管理中可查看到商店A/B二维码名下的粉丝明细及分组情况;
    3. 可以生成多个不同的渠道二维码配置不同的营销活动,设置不同的关注回复信息,让粉丝第一时间了解活动动机,是否有兴趣参与等等;
    4. 可以利用渠道二维码生成功能,可以实现微信收款前关注公众号,间接分析粉丝后续消费情况;
    5. 考核推广员完成任务的进度,如以推广名字生成多不个同的二维码,分配给不同的推广员,每个推广员吸引了多少粉丝关注公众号,微号帮后台都可以一一明细;
    6. 带参数的二维码也叫渠道二维码或者场景二维码,生存的数量有限,且是永久二维码。当数量用完后可以删除一些不用的二维码释放出来,二次利用。
      通过扫描带场景值的二维码进入

    6、上报地理位置事件

    用户同意上报地理位置后,每次进入公众号会话时,都会在进入时上报地理位置,或在进入会话后每5秒上报一次地理位置,公众号可以在公众平台网站中修改以上设置。上报地理位置时,微信会将上报地理位置事件推送到开发者填写的URL。要获取用户地址位置,需要在微信公众平台开发者中心开启上报地理位置功能,开启之后会在用户首次进入公众号时,弹出是否允许上报地理位置选项,如果选择允许则在用户每次进入公众号会话的时候微信会以XML形式将用户的地理位置上报到你开发者中心填写的URL上。

    **注意:**用户地理位置是被动获取的,需用户同意后才会上报,微信公众平台开发不能主动获取用户地理位置。

    推送XML数据包示例:

    <xml>
      <ToUserName><![CDATA[toUser]]></ToUserName>
      <FromUserName><![CDATA[fromUser]]></FromUserName>
      <CreateTime>123456789</CreateTime>
      <MsgType><![CDATA[event]]></MsgType>
      <Event><![CDATA[LOCATION]]></Event>
      <Latitude>23.137466</Latitude>
      <Longitude>113.352425</Longitude>
      <Precision>119.385040</Precision>
    </xml>
    

    参数说明:

    参数				描述
    ToUserName		开发者微信号
    FromUserName	发送方帐号(一个OpenID)
    CreateTime		消息创建时间 (整型)
    MsgType			消息类型,event
    Event			事件类型,LOCATION
    Latitude		地理位置纬度
    Longitude		地理位置经度
    Precision		地理位置精度
    

    上报地理位置事件只需要重写OnEvent_LocationRequest事件代码即可,如下我们返回了一个文本消息,实现代码参考:

    public override IResponseMessageBase OnEvent_LocationRequest(RequestMessageEvent_Location requestMessage)
    {
        //这里是微信客户端(通过微信服务器)自动发送过来的位置信息
        var responseMessage = CreateResponseMessage<ResponseMessageText>();
        responseMessage.Content = "这里写什么都无所谓,比如:上帝爱你!";
        return responseMessage;//这里也可以返回null(需要注意写日志时候null的问题)
    }
    

    上报地理位置用处非常多,可以用维度和经度获取城市代号,调用天气Api,也可以用来监测企业员工的位置进行微信考勤。在微信运营的时候,用户地理位置还是我们进行营销策划、广告活动投放、用户精准营销的重要依据。

    参考文章

    微信公众平台技术文档-官方

    Senparc.Weixin SDK + 官网示例源代码

    RDIFramework.NET — 基于.NET的快速信息化系统开发框架 — 系列目录

    RDIFramework.NET ━ .NET快速信息化系统开发框架 ━ 工作流程组件介绍

    RDIFramework.NET框架SOA解决方案(集Windows服务、WinForm形式与IIS形式发布)-分布式应用

    RDIFramework.NET代码生成器全新V3.5版本发布-重大升级


    一路走来数个年头,感谢RDIFramework.NET框架的支持者与使用者,大家可以通过下面的地址了解详情。

    RDIFramework.NET官方网站:http://www.rdiframework.net/

    RDIFramework.NET官方博客:http://blog.rdiframework.net/

    同时需要说明的,以后的所有技术文章以官方网站为准,欢迎大家收藏!

    RDIFramework.NET框架由专业团队长期打造、一直在更新、一直在升级,请放心使用!

    欢迎关注RDIFramework.net框架官方公众微信(微信号:guosisoft),及时了解最新动态。

    扫描二维码立即关注

    微信号:guosisoft

    展开全文
  • 微信公众号开发技术要点 微信公众号开发技术要点 微信公众号及其接口功能介绍 基本概念 公众号开发者模式 代码验证及图示 Open ID与Union ID 基本概念 使用说明 Access_token 基本介绍 注意事项 获取流程 ...

    微信公众号开发技术要点

    前言

    本文将介绍微信公众号开发中涉及的一些技术概念,以便读者可以快速掌握公众号开发过程中的基本操作和流程。文档不涉及具体开发技术和流程的介绍,该文档作用相当于官方文档中关键点的详细注解。

    在公众号开发流程中,涉及到三种系统:

    1. 微信方面的系统,负责监听用户的操作并将相关消息和事件推送到响应系统,下称微信系统;
    2. 接收微信系统所推送的事件和消息的系统,下称响应系统;
    3. 业务逻辑系统,实现业务逻辑处理,下称业务系统。

    响应系统和业务系统需要自己开发;其中业务系统中的页面即为下文中提到的第三方页面;

    微信公众号及其接口功能介绍

    基本概念

    公众号是为微信用户提供资讯和服务的平台;公众平台开发接口则是通过后台业务系统向用户提供服务的基础;

    不同的公众号类型有不同数量的接口权限,服务号要多于订阅号;

    公众号开发者模式

    开启公众号开发模式后,微信系统将以事件推送的形式告知响应系统用户在公众号里的相关行为,包括:关注/取关事件、二维码扫描事件、自定义菜单事件、跳转链接事件时的事件、点击菜单拉取消息时的事件,从而开发者可以获取到该消息并做出响应;

    1. 开启公众号开发者模式
    2. 填写服务器配置
    3. 验证服务器地址的有效性

    这些步骤都是在微信官方公众号后台里开发->基本配置里完成的

    代码验证及图示

    配置图示:

    这里写图片描述

    服务器代码:

    public class WeChatServer extends HttpServlet {
        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            this.doPost(req,resp);
        }
    
        @Override
        protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException {
            PrintWriter writer=resp.getWriter();
            System.out.println(req.getParameter("echostr"));
            writer.println(req.getParameter("echostr"));
        }
    }
    //微信系统对响应系统地址的有效性验证是通过返回值(echostr)完成的,这里没有添加对微信系统身份的检查,直接输出
    

    完整代码见WeChatWebSystem

    Open ID与Union ID

    基本概念

    为识别用户,微信为每一个用户提供了针对特定公众号平台的Open ID;同一个用户在不同公众号里的有不同的Open ID;同一个公众号里不同用户有不同的Open ID;获取用户的Open ID是无需用户同意的,但是获取用户的基本信息(所在地址、昵称等)是需要用户同意的;

    为了实现在多个公众平台、移动应用之间做到用户统一管理,提供了Union ID机制。同一用户在同一开放平台账号下的所有公众号和应用里Union ID是相同的;

    使用说明

    1. Open ID的获取和使用

      获取

      1. Open ID会在微信系统向响应系统推送普通消息以及事件推送时附带于消息体内;
      2. 从公众号进入第三方页面时,业务系统需要获得该用户的Open ID;

      使用:

      1. 发送被动消息时(包括对事件的响应和消息的响应),使用Open ID来标记发送对象;
      2. 发送主动消息时(模板消息),使用Open ID来标记发送对象;
    2. Union ID的获取和使用

      从公众号进入第三方页面时,业务系统可以选择获取Union ID来实现业务逻辑,其具体流程为:

      准备阶段:

      1. 获得微信网页授权:微信公众号后台->开发->接口权限;
      2. 设置授权回调域名:一旦设置成功,该域名下的所有页面均可以进行OAuth2.0鉴权;
      3. 以snsapi_userInfo为scope发起授权以获得该用户的基本信息;

      获取阶段:

      1. 引导用户进入授权页面,用户同意后,获得code;

        https://open.weixin.qq.com/connect/oauth2/authorize?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=SCOPE&state=STATE#wechat_redirect
        
        其中APPID/REDIRECT_URI/SCOPE/STATE为变量,参数顺序不可改变;跳转回调的redirect_uri,应当使用https链接来确保授权code的安全性。以上链接需要自微信客户端里打开,如果用户同意授权,则页面跳转到:redirect_uri/?code=CODE&state=STATE
        
        参数	是否必须	说明
        appid	是	公众号的唯一标识
        redirect_uri	是	授权后重定向的回调链接地址, 请使用 urlEncode 对链接进行处理
        response_type	是	返回类型,请填写code
        scope	是	应用授权作用域,snsapi_base (不弹出授权页面,直接跳转,只能获取用户openid),snsapi_userinfo (弹出授权页面,可通过openid拿到昵称、性别、所在地。并且, 即使在未关注的情况下,只要用户授权,也能获取其信息 )
        state	否	重定向后会带上state参数,开发者可以填写a-zA-Z0-9的参数值,最多128字节
        #wechat_redirect	是	无论直接打开还是做页面302重定向时候,必须带此参数
        
      2. 使用code换取网页授权access_token(用于获取用户基本信息的token,不是微信基础服务里的access_token,在这一步里,获取access_token的同时也会获得用户的open ID);

        获取code后,请求以下链接获取access_token:  https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code
        
        其中APPID/SECRET/CODE为变量
        
        正确返回的JSON数据如下:
        { "access_token":"ACCESS_TOKEN",
        "expires_in":7200,
        "refresh_token":"REFRESH_TOKEN",
        "openid":"OPENID",
        "scope":"SCOPE" }
        
      3. 如有必要,开发者刷新该access_token,避免过期;

        获取第二步的refresh_token后,请求以下链接获取access_token:
        https://api.weixin.qq.com/sns/oauth2/refresh_token?appid=APPID&grant_type=refresh_token&refresh_token=REFRESH_TOKEN
        
        access_token拥有较短的有效期,refresh_token则有30天的有效期;
        
        返回结果同上
        { "access_token":"ACCESS_TOKEN",
        "expires_in":7200,
        "refresh_token":"REFRESH_TOKEN",
        "openid":"OPENID",
        "scope":"SCOPE" }
        
      4. 通过access_token和openID获得用户基本信息;

         https://api.weixin.qq.com/sns/userinfo?access_token=ACCESS_TOKEN&openid=OPENID&lang=zh_CN
         
         access_token为网页授权时使用的access_token,不是调用微信接口时使用的access_token;
         返回数据:
         {    "openid":" OPENID",
        " nickname": NICKNAME,
        "sex":"1",
        "province":"PROVINCE"
        "city":"CITY",
        "country":"COUNTRY",
        "headimgurl":    "http://thirdwx.qlogo.cn/mmopen/g3MonUZtNHkdmzicIlibx6iaFqAc56vxLSUfpb6n5WKSYVY0ChQKkiaJSgQ1dZuTOgvLLrhJbERQQ4eMsv84eavHiaiceqxibJxCfHe/46",
        "privilege":[ "PRIVILEGE1" "PRIVILEGE2"     ],
        "unionid": "o6_bmasdasdsad6_2sgVt7hMZOPfL"
        }
        
        

      从响应系统内获得Union ID是通过其他接口实现的:

       请求方式: GET
       请求地址:https://api.weixin.qq.com/cgi-bin/user/info?access_token=ACCESS_TOKEN&openid=OPENID&lang=zh_CN
       参数说明:access_token即为接口访问令牌,openid即为消息的发送者
    
    1. 注意事项

      使用snaapi_base为scope的网页授权对用户是静默的,用户感觉直接进入了公众号网页;

      对于已关注公众号的用户,如果用户从公众号会话或者自定义菜单进入网页授权页,即使scope为snaapi_userInfo,也是静默的;

    Access_token

    基本介绍

    access_token是公众号内全局唯一接口调用凭据;其有效期为2小时,需要定时刷新,重新获取将导致上次access_token失效;

    注意事项

    1. 建议公众号使用统一的中控服务器来获取和刷新access_token;
    2. access_token的有效期通过expire_in标志;在刷新过程中中控服务器可以继续对外输出旧的access_token,刷新完毕5分钟内新旧access_token都有效;
    3. 中控服务器应当提供被动刷新access_token的机制;
    4. 公众号和小程序均可以使用AppID和AppSecret调用本接口来获取access_token;

    获取流程

    https请求方式: GET
    https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET
    
    正确返回结果
    {"access_token":"ACCESS_TOKEN","expires_in":7200}
    出粗返回结果
    {"errcode":40013,"errmsg":"invalid appid"}
    

    代码验证及图示

    下图为访问失败时的截图,因为本地开发中使用的IP地址不在公众号后台的IP访问白名单所致,正式部署后将不存在该问题:

    这里写图片描述

    下图为服务器端浏览器接口调试页面

    这里写图片描述

    自定义菜单

    开启服务模式后,将无法在微信公众号后台内实现对菜单的自定义,但是微信公众号后台内可以自定义的菜单点击类型十分有限(2/10),可以通过使用微信提供的菜单管理接口来对菜单进行管理。

    基本介绍

    1. 微信公众号内允许3个一级菜单,每个一级菜单允许5个二级子菜单;一级菜单最多4个汉字,二级菜单最多7个汉字;
    2. 菜单项共有10种类型:
      1. click:当用户点击该类子菜单时,微信系统将向响应系统推送类型为event的消息并附带该菜单项的key值,开发者可以据此对该事件做出响应;
      2. view:当用户点击该类子菜单时,微信客户端将打开开发者在该菜单项中设置的网页URL,在该URL内开发者可以配合网页授权接口获得用户的基本信息以开展业务服务;
      3. scancode_push:当用户点击此类型子菜单时,微信客户端将调起扫一扫工具,并将结果展示给用户,如果识别结果为URL,将进入该URL,同时响应系统将接收到该消息;
      4. scancode_waitmsg:当用户点击该类子菜单时,微信客户端将调起扫一扫工具,完成扫码操作后,将扫码的结果传给开发者,同时收起扫一扫工具,然后弹出“消息接收中”提示框,随后可能会收到开发者下发的消息。
      5. pic_sysphoto:当用户点击该类子菜单时,微信客户端将调起系统相机,完成拍照操作后,将拍摄的图片发送给响应系统,同时收起系统相机,等待开发者下发消息;
      6. pic_photo_or_album:基本功能同上,但是会给用户两种选择:拍照或者系统相册上传;
      7. pic_weixin:基本功能同上,但是会使用微信相册;
      8. location_select:弹出地理位置选择器,完成操作后,将选择地理信息发送给响应系统,收起地理位置选择器后,等待开发者下发消息;
      9. media_id:当用户点击该类子菜单项后,微信系统将对应永久素材id的素材下发给用户;
      10. view_limited:当用户点击该类型子菜单时,微信客户端将打开开发者在按钮中填写的永久素材id对应的图文消息URL;

    创建菜单

    接口说明:

     接口地址:https://api.weixin.qq.com/cgi-bin/menu/create?access_token=ACCESS_TOKEN
     访问方式:POST
     参数说明:
     ACCESS_TOKEN即为获取的access_token;
     POST的数据为JSON字符串,其中button定义了菜单,为一个JSON数组;数组中每一个元素都是一个一级菜单,其中sub_button属性为该一级菜单的二级菜单,同样也是JSON数组;每一个菜单项包含type(上面提到的10种)、name、key等信息。
     {
         "button":[
         {    
              "type":"click",
              "name":"今日歌曲",
              "key":"V1001_TODAY_MUSIC"
          },
          {
               "name":"菜单",
               "sub_button":[
               {    
                   "type":"view",
                   "name":"搜索",
                   "url":"http://www.soso.com/"
                },
                {//跳转小程序
                     "type":"miniprogram",
                     "name":"wxa",
                     "url":"http://mp.weixin.qq.com",
                     "appid":"wx286b93c14bbf93aa",
                     "pagepath":"pages/lunar/index"
                 },
                {
                   "type":"click",
                   "name":"赞一下我们",
                   "key":"V1001_GOOD"
                }]
           }]
     }
     正确返回消息:
     {"errcode":0,"errmsg":"ok"}
     出错时返回消息:
     {"errcode":40018,"errmsg":"invalid button name size"}
     
    

    这里需要注意的是,POST的内容类型(content-type)需要设置为application/json;

    查询菜单

    创建自定义菜单后,可使用该接口查询自定义菜单的结构。如果使用了个性化菜单,那么该接口将返回默认菜单和全部个性化菜单的信息;

    请求方式:GET
    https://api.weixin.qq.com/cgi-bin/menu/get?access_token=ACCESS_TOKEN
    
    返回数据(无个性化菜单时):
    {
        "menu": {
            "button": [
                {
                    "type": "click", 
                    "name": "今日歌曲", 
                    "key": "V1001_TODAY_MUSIC", 
                    "sub_button": [ ]
                }, 
                {
                    "type": "click", 
                    "name": "歌手简介", 
                    "key": "V1001_TODAY_SINGER", 
                    "sub_button": [ ]
                }, 
                {
                    "name": "菜单", 
                    "sub_button": [
                        {
                            "type": "view", 
                            "name": "搜索", 
                            "url": "http://www.soso.com/", 
                            "sub_button": [ ]
                        }, 
                        {
                            "type": "view", 
                            "name": "视频", 
                            "url": "http://v.qq.com/", 
                            "sub_button": [ ]
                        }, 
                        {
                            "type": "click", 
                            "name": "赞一下我们", 
                            "key": "V1001_GOOD", 
                            "sub_button": [ ]
                        }
                    ]
                }
            ]
        }
    }
    
    返回结果(有个性化菜单时):
    {
        "menu": {
            "button": [
                {
                    "type": "click", 
                    "name": "今日歌曲", 
                    "key": "V1001_TODAY_MUSIC", 
                    "sub_button": [ ]
                }
            ], 
            "menuid": 208396938
        }, 
        "conditionalmenu": [
            {
                "button": [
                    {
                        "type": "click", 
                        "name": "今日歌曲", 
                        "key": "V1001_TODAY_MUSIC", 
                        "sub_button": [ ]
                    }, 
                    {
                        "name": "菜单", 
                        "sub_button": [
                            {
                                "type": "view", 
                                "name": "搜索", 
                                "url": "http://www.soso.com/", 
                                "sub_button": [ ]
                            }, 
                            {
                                "type": "view", 
                                "name": "视频", 
                                "url": "http://v.qq.com/", 
                                "sub_button": [ ]
                            }, 
                            {
                                "type": "click", 
                                "name": "赞一下我们", 
                                "key": "V1001_GOOD", 
                                "sub_button": [ ]
                            }
                        ]
                    }
                ], 
                "matchrule": {
                    "group_id": 2, 
                    "sex": 1, 
                    "country": "中国", 
                    "province": "广东", 
                    "city": "广州", 
                    "client_platform_type": 2
                }, 
                "menuid": 208396993
            }
        ]
    }
    

    删除菜单

    接口说明:

    http请求方式:GET
    https://api.weixin.qq.com/cgi-bin/menu/delete?access_token=ACCESS_TOKEN
    正确返回消息:
    {"errcode":0,"errmsg":"ok"}
    错误返回消息同上
    

    这里需要注意的是,该方式将删除整个菜单。

    个性化菜单

    为了帮助公众号实现灵活的业务运营,微信公众平台新增了个性化菜单接口,开发者可以通过该接口,让公众号的不同用户群体看到不一样的自定义菜单。该接口开放给已认证订阅号和已认证服务号。

    开发者可以使用如下方式标志用户:

    1. 用户标签(开发者的业务需求可以借助用户标签来完成)
    2. 性别
    3. 手机操作系统地区(用户在微信客户端设置的地区)
    4. 语言(用户在微信客户端设置的语言)

    使用个性化菜单需要有以下几点注意:

    1. 个性化菜单要求用户的微信客户端版本在iPhone6.2.2,Android 6.2.4以上,暂时不支持其他版本微信;
    2. 菜单的刷新策略是,在用户进入公众号会话页或公众号profile页时,如果发现上一次拉取菜单的请求在5分钟以前,就会拉取一下菜单,如果菜单有更新,就会刷新客户端的菜单。测试时可以尝试取消关注公众账号后再次关注,则可以看到创建后的效果;
    3. 普通公众号的个性化菜单的新增接口每日限制次数为2000次,删除接口也是2000次,测试个性化菜单匹配结果接口为20000次;
    4. 出于安全考虑,一个公众号的所有个性化菜单,最多只能设置为跳转到3个域名下的链接;
    5. 创建个性化菜单之前必须先创建默认菜单(默认菜单是指使用普通自定义菜单创建接口创建的菜单)。如果删除默认菜单,个性化菜单也会全部删除;
    6. 个性化菜单接口支持用户标签,请开发者注意,当用户身上的标签超过1个时,以最后打上的标签为匹配;

    创建个性化菜单:

    请求方式:POST(请使用https协议)
    https://api.weixin.qq.com/cgi-bin/menu/addconditional?access_token=ACCESS_TOKEN
    POST数据为JSON对象;
    {
         "button":[
         {    
            "type":"click",
            "name":"今日歌曲",
             "key":"V1001_TODAY_MUSIC" },
        {     "name":"菜单",
            "sub_button":[
            {            
                "type":"view",
                "name":"搜索",
                "url":"http://www.soso.com/"},
                {
                             "type":"miniprogram",
                             "name":"wxa",
                             "url":"http://mp.weixin.qq.com",
                             "appid":"wx286b93c14bbf93aa",
                             "pagepath":"pages/lunar/index"
                },
                 {
            "type":"click",
            "name":"赞一下我们",
            "key":"V1001_GOOD"
               }]
     }],
    "matchrule":{
      "tag_id":"2",
      "sex":"1",
      "country":"中国",
      "province":"广东",
      "city":"广州",
      "client_platform_type":"2",
      "language":"zh_CN"
      }
    }
    正确返回消息:
    {"menuid":"208379533"}——menuid即为该菜单的标记;可用于以后删除使用;
    

    删除个性化菜单:

    请求方式:POST(请使用https协议)
    https://api.weixin.qq.com/cgi-bin/menu/delconditional?access_token=ACCESS_TOKEN
    参数说明:
    POST数据为JSON字符串
    {"menuid":"208379533"}
    正确返回:
    {"errcode":0,"errmsg":"ok"}
    错误返回:
    通用
    

    自定义菜单事件推送

    注意,第3个到第8个的所有事件,仅支持微信iPhone5.4.1以上版本,和Android5.4以上版本的微信用户,旧版本微信用户点击后将没有回应,开发者也不能正常接收到事件推送。

    click类型的消息推送:
    <xml>
    <ToUserName><![CDATA[toUser]]></ToUserName>
    <FromUserName><![CDATA[FromUser]]></FromUserName>
    <CreateTime>123456789</CreateTime>
    <MsgType><![CDATA[event]]></MsgType>
    <Event><![CDATA[CLICK]]></Event>
    <EventKey><![CDATA[EVENTKEY]]></EventKey>
    </xml>
    
    view类型的消息推送:
    <xml>
    <ToUserName><![CDATA[toUser]]></ToUserName>
    <FromUserName><![CDATA[FromUser]]></FromUserName>
    <CreateTime>123456789</CreateTime>
    <MsgType><![CDATA[event]]></MsgType>
    <Event><![CDATA[VIEW]]></Event>
    <EventKey><![CDATA[www.qq.com]]></EventKey>
    <MenuId>MENUID</MenuId>//指菜单ID,如果是个性化菜单,则可以通过这个字段,知道是哪个规则的菜单被点击了。
    </xml>
    
    scancode_push类型的消息推送:
    <xml><ToUserName><![CDATA[gh_e136c6e50636]]></ToUserName>
    <FromUserName><![CDATA[oMgHVjngRipVsoxg6TuX3vz6glDg]]></FromUserName>
    <CreateTime>1408090502</CreateTime>
    <MsgType><![CDATA[event]]></MsgType>
    <Event><![CDATA[scancode_push]]></Event>
    <EventKey><![CDATA[6]]></EventKey>
    <ScanCodeInfo><ScanType><![CDATA[qrcode]]></ScanType>
    <ScanResult><![CDATA[1]]></ScanResult>
    </ScanCodeInfo>
    </xml>
    
    scancode_waitmsg类型的消息推送:
    <xml><ToUserName><![CDATA[gh_e136c6e50636]]></ToUserName>
    <FromUserName><![CDATA[oMgHVjngRipVsoxg6TuX3vz6glDg]]></FromUserName>
    <CreateTime>1408090606</CreateTime>
    <MsgType><![CDATA[event]]></MsgType>
    <Event><![CDATA[scancode_waitmsg]]></Event>
    <EventKey><![CDATA[6]]></EventKey>
    <ScanCodeInfo><ScanType><![CDATA[qrcode]]></ScanType>
    <ScanResult><![CDATA[2]]></ScanResult>
    </ScanCodeInfo>
    </xml>
    
    pic_sysphoto类型的消息推送:
    <xml><ToUserName><![CDATA[gh_e136c6e50636]]></ToUserName>
    <FromUserName><![CDATA[oMgHVjngRipVsoxg6TuX3vz6glDg]]></FromUserName>
    <CreateTime>1408090651</CreateTime>
    <MsgType><![CDATA[event]]></MsgType>
    <Event><![CDATA[pic_sysphoto]]></Event>
    <EventKey><![CDATA[6]]></EventKey>
    <SendPicsInfo><Count>1</Count>
    <PicList><item><PicMd5Sum><![CDATA[1b5f7c23b5bf75682a53e7b6d163e185]]></PicMd5Sum>
    </item>
    </PicList>
    </SendPicsInfo>
    </xml>
    
    pic_photo_or_album类型的消息推送:
    <xml><ToUserName><![CDATA[gh_e136c6e50636]]></ToUserName>
    <FromUserName><![CDATA[oMgHVjngRipVsoxg6TuX3vz6glDg]]></FromUserName>
    <CreateTime>1408090816</CreateTime>
    <MsgType><![CDATA[event]]></MsgType>
    <Event><![CDATA[pic_photo_or_album]]></Event>
    <EventKey><![CDATA[6]]></EventKey>
    <SendPicsInfo><Count>1</Count>
    <PicList><item><PicMd5Sum><![CDATA[5a75aaca956d97be686719218f275c6b]]></PicMd5Sum>
    </item>
    </PicList>
    </SendPicsInfo>
    </xml>
    
    pic_weixin类型的消息推送:
    <xml><ToUserName><![CDATA[gh_e136c6e50636]]></ToUserName>
    <FromUserName><![CDATA[oMgHVjngRipVsoxg6TuX3vz6glDg]]></FromUserName>
    <CreateTime>1408090816</CreateTime>
    <MsgType><![CDATA[event]]></MsgType>
    <Event><![CDATA[pic_weixin]]></Event>
    <EventKey><![CDATA[6]]></EventKey>
    <SendPicsInfo><Count>1</Count>
    <PicList><item><PicMd5Sum><![CDATA[5a75aaca956d97be686719218f275c6b]]></PicMd5Sum>
    </item>
    </PicList>
    </SendPicsInfo>
    </xml>
    
    location_select类型的消息推送:
    <xml><ToUserName><![CDATA[gh_e136c6e50636]]></ToUserName>
    <FromUserName><![CDATA[oMgHVjngRipVsoxg6TuX3vz6glDg]]></FromUserName>
    <CreateTime>1408091189</CreateTime>
    <MsgType><![CDATA[event]]></MsgType>
    <Event><![CDATA[location_select]]></Event>
    <EventKey><![CDATA[6]]></EventKey>
    <SendLocationInfo><Location_X><![CDATA[23]]></Location_X>
    <Location_Y><![CDATA[113]]></Location_Y>
    <Scale><![CDATA[15]]></Scale>
    <Label><![CDATA[ 广州市海珠区客村艺苑路 106号]]></Label>
    <Poiname><![CDATA[]]></Poiname>
    </SendLocationInfo>
    </xml>
    
    
    

    用户管理

    标签管理

    开发者可以使用用户标签管理的相关接口,实现对公众号标签的管理;标签可以用于对用户的分类管理;

    每个公众号可以创建100个标签;创建方式如下:

    请求方式:POST(使用https协议);
    请求地址:https://api.weixin.qq.com/cgi-bin/tags/create?access_token=ACCESS_TOKEN
    POST数据格式:
    {   "tag":{ "name" : "广东"//标签名长度不能超过30字节}}
    返回结果:
    {   "tag":{ "id":134,id "name":"广东"   } }//包含tag-id
    

    获取公众号已创建的标签:

    请求方式:GET(使用https协议) 
    请求地址:https://api.weixin.qq.com/cgi-bin/tags/get?access_token=ACCESS_TOKEN
    返回说明:
    {   "tags":[{       "id":1,       "name":"每天一罐可乐星人",       "count":0 //此标签下粉丝数 },{   "id":2,   "name":"星标组",   "count":0 },{   "id":127,   "name":"广东",   "count":5 }   ] }
    

    编辑标签:

    请求方式:POST(请使用https协议)
    请求地址:https://api.weixin.qq.com/cgi-bin/tags/update?access_token=ACCESS_TOKEN
    POST数据:
    {   "tag" : {     "id" : 134,     "name" : "广东人"   } }
    返回说明:
    正确返回:{   "errcode":0,   "errmsg":"ok" }
    错误返回:详见错误返回码
    

    删除标签:

    请注意,当某个标签下的粉丝超过10w时,后台不可直接删除标签。此时,开发者可以对该标签下的openid列表,先进行取消标签的操作,直到粉丝数不超过10w后,才可直接删除该标签。

    请求方式:POST(使用https协议) 
    请求地址:https://api.weixin.qq.com/cgi-bin/tags/delete?access_token=ACCESS_TOKEN
    POST数据:
    {   "tag":{        "id" : 134   } }
    返回说明:
    正确返回:{   "errcode":0,   "errmsg":"ok" }
    错误返回:详见错误返回码
    

    获取标签下的粉丝列表:

    请求方式:POST(请使用https协议) 
    请求地址:https://api.weixin.qq.com/cgi-bin/user/tag/get?access_token=ACCESS_TOKEN
    POST数据格式:JSON
    {   "tagid" : 134,   "next_openid":""//第一个拉取的OPENID,不填默认从头开始拉取 }
    返回说明:
    { 
    	"count":2,//这次获取的粉丝数量   
    	"data":{//粉丝列表
    		"openid":[  
    			"ocYxcuAEy30bX0NXmGn4ypqx3tI0",    
    			"ocYxcuBt0mRugKZ7tGAHPnUaOW7Y"
    		]  
    	},  
    	"next_openid":"ocYxcuBt0mRugKZ7tGAHPnUaOW7Y"//拉取列表最后一个用户的openid 
    }
    

    用户标签管理

    标签功能支持为公众号用户进行打标签、取消标签等操作;该功能可以实现个性化菜单定制

    批量为用户打标签

    请求方式:POST(请使用https协议)
    请求地址:https://api.weixin.qq.com/cgi-bin/tags/members/batchtagging?access_token=ACCESS_TOKEN
    POST数据:
    {   
    	"openid_list" : [//粉丝列表    
    		"ocYxcuAEy30bX0NXmGn4ypqx3tI0",    
    		"ocYxcuBt0mRugKZ7tGAHPnUaOW7Y"],   
    	"tagid" : 134 
    }
    返回说明:
    {   
    	"errcode":0,   
    	"errmsg":"ok"
    }
    

    批量为用户取消标签

    请求方式:POST(请使用https协议) 
    请求地址:https://api.weixin.qq.com/cgi-bin/tags/members/batchuntagging?access_token=ACCESS_TOKEN
    POST数据格式:JSON
    {
    	"openid_list" : [//粉丝列表     
    		"ocYxcuAEy30bX0NXmGn4ypqx3tI0",     
    		"ocYxcuBt0mRugKZ7tGAHPnUaOW7Y"],   
    	"tagid" : 134
    }
    返回说明:{"errcode":0, "errmsg":"ok"}
    

    获取用户的标签列表

    请求方式:POST(请使用https协议)
    请求地址:https://api.weixin.qq.com/cgi-bin/tags/getidlist?access_token=ACCESS_TOKEN
    POST数据格式:JSON
    {   "openid" : "ocYxcuBt0mRugKZ7tGAHPnUaOW7Y" }
    返回说明:{   "tagid_list":[//被置上的标签列表 134, 2   ] }
    

    设置用户备注名

    请求方式: POST(请使用https协议)
    请求地址:https://api.weixin.qq.com/cgi-bin/user/info/updateremark?access_token=ACCESS_TOKEN
    POST数据格式:JSON
    POST数据例子:
    {
        "openid":"oDF3iY9ffA-hqb2vVvbr7qxf6A0Q",
        "remark":"pangzi"//标签名
    }
    返回说明:{"errcode":0,"errmsg":"ok"}
    

    获取用户基本信息

    注意,这里获的用户基本信息是在关注者和公众号产生消息交互后,公众号可获得该用户的Open ID,之后在响应系统中,通过Open ID获的Union ID以及基本信息

    请求方式: GET
    请求地址:https://api.weixin.qq.com/cgi-bin/user/info?access_token=ACCESS_TOKEN&openid=OPENID&lang=zh_CN
    返回说明:正常情况下,微信会返回下述JSON数据包给公众号
    {
        "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": " o6_bmasdasdsad6_2sgVt7hMZOPfL"
        "remark": "",
        "groupid": 0,
        "tagid_list":[128,2],
        "subscribe_scene": "ADD_SCENE_QR_CODE",
        "qr_scene": 98765,
        "qr_scene_str": ""
    }
    

    批量获得用户基本信息

    请求方式: POST
    请求地址:https://api.weixin.qq.com/cgi-bin/user/info/batchget?access_token=ACCESS_TOKEN
    POST:JSON
    {
        "user_list": [
            {
                "openid": "otvxTs4dckWG7imySrJd6jSi0CWE", 
                "lang": "zh_CN"
            }, 
            {
                "openid": "otvxTs_JZ6SEiP0imdhpi50fuSZg", 
                "lang": "zh_CN"
            }
        ]
    }
    返回说明:
    {
       "user_info_list": [
           {
               "subscribe": 1, 
               "openid": "otvxTs4dckWG7imySrJd6jSi0CWE", 
               "nickname": "iWithery", 
               "sex": 1, 
               "language": "zh_CN", 
               "city": "揭阳", 
               "province": "广东", 
               "country": "中国", 
    
               "headimgurl": "http://thirdwx.qlogo.cn/mmopen/xbIQx1GRqdvyqkMMhEaGOX802l1CyqMJNgUzKP8MeAeHFicRDSnZH7FY4XB7p8XHXIf6uJA2SCunTPicGKezDC4saKISzRj3nz/0",
    
              "subscribe_time": 1434093047, 
               "unionid": "oR5GjjgEhCMJFyzaVZdrxZ2zRRF4", 
               "remark": "", 
    
               "groupid": 0,
               "tagid_list":[128,2],
               "subscribe_scene": "ADD_SCENE_QR_CODE",
               "qr_scene": 98765,
               "qr_scene_str": ""
    
          }, 
           {
               "subscribe": 0, 
               "openid": "otvxTs_JZ6SEiP0imdhpi50fuSZg"
           }
       ]
    }
    

    获取用户列表

    公众号可通过本接口来获取帐号的关注者列表,关注者列表由一串OpenID(加密后的微信号,每个用户对每个公众号的OpenID是唯一的)组成。一次拉取调用最多拉取10000个关注者的OpenID,可以通过多次拉取的方式来满足需求。

    请求方式: GET(请使用https协议)
    请求地址:https://api.weixin.qq.com/cgi-bin/user/get?access_token=ACCESS_TOKEN&next_openid=NEXT_OPENID
    返回说明:
    {
    	"total":2,
    	"count":2,
    	"data":{
    		"openid":["OPENID1","OPENID2"]
    	},
    	"next_openid":"NEXT_OPENID"
    }
    

    当公众号关注者数量超过10000时,可通过填写next_openid的值,从而多次拉取列表的方式来满足需求。

    具体而言,就是在调用接口时,将上一次调用得到的返回中的next_openid值,作为下一次调用中的next_openid值。

    消息管理

    接收普通消息

    当普通用户向公众号发送消息时,微信系统将POST消息的XML数据包到开发者填写的URL上;

    注意事项:

    1. 微信服务器在5s内收不到响应并不会断掉连接,并且重新发起请求,总共重试3次;如果服务器无法保证在5s内做出响应,应当回复空串。
    2. 如果开发者需要在5s内对用户发送的消息做出回应,即使用发送消息->被回复消息接口向用户被动回复消息,那么需要选择对消息的加密方式,详情见 消息加密;

    各种消息体结构(XML格式组织,可使用输入流的方式读取):

    注意,首次出现的XML标签将给出注释,第二次出现则不再注释,该规则同样适用于后面的接收事件消息

    1. 文本消息

      <xml>
      	<ToUserName>< ![CDATA[toUser] ]></ToUserName>	//开发者微信号
      	<FromUserName>< ![CDATA[fromUser] ]></FromUserName>		//用户的openid
      	<CreateTime>1348831860</CreateTime>
      	<MsgType>< ![CDATA[text] ]></MsgType>	//文本为text
      	<Content>< ![CDATA[this is a test] ]></Content>
      	<MsgId>1234567890123456</MsgId>		//64位整型
      </xml>
      
    2. 图片消息

      <xml>
      	<ToUserName>< ![CDATA[toUser] ]></ToUserName>
      	<FromUserName>< ![CDATA[fromUser] ]></FromUserName>
      	<CreateTime>1348831860</CreateTime>
      	<MsgType>< ![CDATA[image] ]></MsgType>	//图片为image
      	<PicUrl>< ![CDATA[this is a url] ]></PicUrl>
      	<MediaId>< ![CDATA[media_id] ]></MediaId>	//可使用图片消息媒体id,可以调用多媒体文件下载接口拉取数据。
      	<MsgId>1234567890123456</MsgId>
      </xml>
      
    3. 语音消息

      <xml>
      	<ToUserName>< ![CDATA[toUser] ]></ToUserName>
      	<FromUserName>< ![CDATA[fromUser] ]></FromUserName>
      	<CreateTime>1357290913</CreateTime>
      	<MsgType>< ![CDATA[voice] ]></MsgType>	//语音为voice
      	<MediaId>< ![CDATA[media_id] ]></MediaId>
      	<Format>< ![CDATA[Format] ]></Format>	//语音格式,如amr,speex等
      	<MsgId>1234567890123456</MsgId>
      	<Recognition>< ![CDATA[腾讯微信团队] ]></Recognition>
      </xml>
      

      这里需要注意的是,如果开启了语音识别,用户每次发送语音给公众号时,微信会在推送的语音消息XML数据包中,增加一个Recongnition字段标志识别结果;

    4. 视频消息

      <xml>
      	<ToUserName>< ![CDATA[toUser] ]></ToUserName>
      	<FromUserName>< ![CDATA[fromUser] ]></FromUserName>
      	<CreateTime>1357290913</CreateTime>
      	<MsgType>< ![CDATA[video] ]></MsgType>	//视频为video
      	<MediaId>< ![CDATA[media_id] ]></MediaId>	//可使用图片消息媒体id,可以调用多媒体文件下载接口拉取数据。
      	<ThumbMediaId>< ![CDATA[thumb_media_id] ]></ThumbMediaId>	//视频消息缩略图的媒体id,可以调用多媒体文件下载接口拉取数据。
      	<MsgId>1234567890123456</MsgId></xml>
      
    5. 小视频消息

      <xml>
      	<ToUserName>< ![CDATA[toUser] ]></ToUserName>
      	<FromUserName>< ![CDATA[fromUser] ]></FromUserName>
      	<CreateTime>1357290913</CreateTime>
      	<MsgType>< ![CDATA[shortvideo] ]></MsgType>		//小视频为shortvideo
      	<MediaId>< ![CDATA[media_id] ]></MediaId>
      	<ThumbMediaId>< ![CDATA[thumb_media_id] ]></ThumbMediaId>
      	<MsgId>1234567890123456</MsgId>
      </xml>
      
    6. 地理位置消息

      <xml>
      	<ToUserName>< ![CDATA[toUser] ]></ToUserName>
      	<FromUserName>< ![CDATA[fromUser] ]></FromUserName>
      	<CreateTime>1351776360</CreateTime>
      	<MsgType>< ![CDATA[location] ]></MsgType>	//地理位置为	location
      	<Location_X>23.134521</Location_X>	// 地理纬度
      	<Location_Y>113.358803</Location_Y>	// 地理经度
      	<Scale>20</Scale>	//地图缩放大小
      	<Label>< ![CDATA[位置信息] ]></Label>	//地理位置信息
      	<MsgId>1234567890123456</MsgId>
      </xml>
      
      
    7. 链接消息

      <xml>
      	<ToUserName>< ![CDATA[toUser] ]></ToUserName>
      	<FromUserName>< ![CDATA[fromUser] ]></FromUserName>
      	<CreateTime>1351776360</CreateTime>
      	<MsgType>< ![CDATA[link] ]></MsgType>	//链接消息为 link
      	<Title>< ![CDATA[公众平台官网链接] ]></Title>	//标题
      	<Description>< ![CDATA[公众平台官网链接] ]></Description>	//描述
      	<Url>< ![CDATA[url] ]></Url>	//消息链接
      	<MsgId>1234567890123456</MsgId>
      </xml>
      
      

    接收事件消息

    在微信用户和公众号产生交互的过程中,用户的某些操作会使得微信系统通过事件推送的形式通知响应系统,从而开发者可以获取到该信息。其中,某些事件推送在发生后,是允许开发者回复用户的,某些则不允许,详细内容如下:

    1. 关注/取消关注事件
    2. 扫描带参数二维码事件
    3. 上报地理位置事件
    4. 自定义菜单事件
    5. 点击菜单拉取消息的事件
    6. 点击菜单跳转链接时的事件

    各种事件介绍:

    1. 关注/取消关注事件

      用户在关注与取消关注公众号时,微信系统会把这个事件推送到响应系统,方便开发者给用户下发欢迎消息或者做帐号的解绑。为保护用户数据隐私,开发者收到用户取消关注事件时需要删除该用户的所有信息。

      推送XML数据包示例:

      <xml>
      	<ToUserName>< ![CDATA[toUser] ]></ToUserName>	//开发者微信号
      	<FromUserName>< ![CDATA[FromUser] ]></FromUserName>		//用户的OennID
      	<CreateTime>123456789</CreateTime>	//创建时间,int整型
      	<MsgType>< ![CDATA[event] ]></MsgType>
      	<Event>	//消息类型为event< ![CDATA[subscribe] ]></Event>	//事件类型,subscribe(订阅)、unsubscribe(取消订阅)
      </xml>
      
      
    2. 扫描带参数二维码事件:

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

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

      推送XML数据包示例:

      用户未关注时,进行关注后的事件推送
      <xml>
      	<ToUserName>< ![CDATA[toUser] ]></ToUserName>
      	<FromUserName>< ![CDATA[FromUser] ]></FromUserName>
      	<CreateTime>123456789</CreateTime>
      	<MsgType>< ![CDATA[event] ]></MsgType>		//消息类型为event
      	<Event>< ![CDATA[subscribe] ]></Event>	//事件类型,subscribe
      	<EventKey>< ![CDATA[qrscene_123123] ]></EventKey>	//事件KEY值,qrscene_为前缀,后面为二维码的参数值
      	<Ticket>< ![CDATA[TICKET] ]></Ticket>	//二维码的ticket,可用来换取二维码图片
      </xml>
      
      用户已关注时的事件推送
      <xml>
      	<ToUserName>< ![CDATA[toUser] ]></ToUserName> 
      	<FromUserName>< ![CDATA[FromUser] ]></FromUserName> 
      	<CreateTime>123456789</CreateTime> 
      	<MsgType>< ![CDATA[event] ]></MsgType>
          <Event>< ![CDATA[SCAN] ]></Event>
          <EventKey>< ![CDATA[SCENE_VALUE] ]></EventKey>	//创建二维码是的scene_id
          <Ticket>< ![CDATA[TICKET] ]></Ticket>	//二维码的ticket,可用来换取图片
      </xml>
      
      
    3. 上报地理位置事件

      用户同意上报地理位置后,每次进入公众号会话时,都会进入上报地理位置,或在进入会话后每5秒报一次地理位置。上报地理位置时,微信系统将上报地理位置事件推送到响应系统;

      推送XML数据包示例:

      <xml>
      	<ToUserName>< ![CDATA[toUser] ]></ToUserName>
      	<FromUserName>< ![CDATA[fromUser] ]></FromUserName>
      	<CreateTime>123456789</CreateTime>
      	<MsgType>< ![CDATA[event] ]></MsgType>
      	<Event>< ![CDATA[LOCATION] ]></Event>
      	<Latitude>23.137466</Latitude>	//维度
      	<Longitude>113.352425</Longitude>	//经度
      	<Precision>119.385040</Precision>	//地理位置精度
      </xml>
      
      
    4. 自定义菜单事件

      用户点击自定义菜单后,微信系统会把点击事件推送给响应系统,点击菜单弹出子菜单,不会产生上报。

      推送XML数据包示例:

      点击菜单拉取消息时的事件推送
      <xml>
      	<ToUserName>< ![CDATA[toUser] ]></ToUserName>
      	<FromUserName>< ![CDATA[FromUser] ]></FromUserName>
      	<CreateTime>123456789</CreateTime>
      	<MsgType>< ![CDATA[event] ]></MsgType>
      	<Event>< ![CDATA[CLICK] ]></Event>	//事件类型为CLICK
      	<EventKey>< ![CDATA[EVENTKEY] ]></EventKey>	//事件KEY值,与自定义菜单接口中KEY值对应
      </xml>
      
      点击菜单跳转链接时的事件推送
      <xml>
      	<ToUserName>< ![CDATA[toUser] ]></ToUserName>
      	<FromUserName>< ![CDATA[FromUser] ]></FromUserName>
      	<CreateTime>123456789</CreateTime>
      	<MsgType>< ![CDATA[event] ]></MsgType>	
      	<Event>< ![CDATA[VIEW] ]></Event>	//事件类型为 VIEW
      	<EventKey>< ![CDATA[www.qq.com] ]></EventKey>	//事件的KEY值,设置的跳转URL
      </xml>
      
      

    被动回复用户消息

    当用户发送消息给公众号时,或某些特定的用户操作引发的事件推送时,微信系统会将一个POST请求发送到响应系统,开发者可以在响应包(Get)中返回特定XML结构,来对该消息进行响应,这种方式称为被动回复用户消息。

    现支持回复文本、图片、图文、语音、视频、音乐。

    发送被动响应消息其实并不是一种接口,而是对微信系统发过来消息的一次回复,只是这次回复将发送到用户。

    被动回复消息的数据格式:

    注意:

    1. 回复图片(不支持gif动图)等多媒体消息时需要预先通过素材管理接口上传临时素材到微信服务器,可以使用素材管理中的临时素材,也可以使用永久素材。

    2. 一旦遇到以下情况,微信都会在公众号会话中,向用户下发系统提示“该公众号暂时无法提供服务,请稍后再试”:

      1. 开发者在5秒内未回复任何内容;
      2. 开发者回复了异常数据,比如JSON数据等;
    3. 回复文本消息

      XML格式数据:

      <xml>
      	<ToUserName>< ![CDATA[toUser] ]></ToUserName>	//用户Open id
      	<FromUserName>< ![CDATA[fromUser] ]></FromUserName>	//开发者 微信号;这两者都可以从响应系统收到的消息里获得
          <CreateTime>12345678</CreateTime>
          <MsgType>< ![CDATA[text] ]></MsgType>	//消息类型为:text
          <Content>< ![CDATA[你好] ]></Content>
      </xml>
      
      
    4. 回复图片消息

      XML格式数据:

      <xml>
      	<ToUserName>< ![CDATA[toUser] ]></ToUserName>
      	<FromUserName>< ![CDATA[fromUser] ]></FromUserName>
      	<CreateTime>12345678</CreateTime>
      	<MsgType>< ![CDATA[image] ]></MsgType>	//消息类型为:image
      	<Image>
      		<MediaId>< ![CDATA[media_id] ]></MediaId>//通过素材管理中的接口上传多媒体文件,得到的id。
      	</Image>
      </xml>
      
      
    5. 回复语音消息

      XML格式数据:

      <xml>
      	<ToUserName>< ![CDATA[toUser] ]></ToUserName>
      	<FromUserName>< ![CDATA[fromUser] ]></FromUserName>
      	<CreateTime>12345678</CreateTime>
      	<MsgType>< ![CDATA[voice] ]></MsgType>	//消息类型为:voice
      	<Voice>
      		<MediaId>< ![CDATA[media_id] ]></MediaId>
      	</Voice>
      </xml>
      
      
    6. 回复视频消息

      XML格式数据:

      <xml>
      	<ToUserName>< ![CDATA[toUser] ]></ToUserName>
      	<FromUserName>< ![CDATA[fromUser] ]></FromUserName>
      	<CreateTime>12345678</CreateTime>
      	<MsgType>< ![CDATA[video] ]></MsgType>	//消息类型为:video
      	<Video>
      		<MediaId>< ![CDATA[media_id] ]></MediaId>
      		<Title>< ![CDATA[title] ]></Title>	//视频的标题
      		<Description>< ![CDATA[description] ]></Description>	//视频的描述
      	</Video>
      </xml>
      
      
    7. 回复音乐消息

      XML格式数据:

      <xml>
      	<ToUserName>< ![CDATA[toUser] ]></ToUserName>
      	<FromUserName>< ![CDATA[fromUser] ]></FromUserName>
      	<CreateTime>12345678</CreateTime>
      	<MsgType>< ![CDATA[music] ]></MsgType>
      	<Music>
      		<Title>< ![CDATA[TITLE] ]></Title>
      		<Description>< ![CDATA[DESCRIPTION] ]></Description>
      		<MusicUrl>< ![CDATA[MUSIC_Url] ]></MusicUrl>
      		<HQMusicUrl>< ![CDATA[HQ_MUSIC_Url] ]></HQMusicUrl>
      		<ThumbMediaId>< ![CDATA[media_id] ]></ThumbMediaId>
      	</Music>
      </xml>
      
      
    8. 回复图文消息

      XML格式数据:

      <xml>
      	<ToUserName>< ![CDATA[toUser] ]></ToUserName>
      	<FromUserName>< ![CDATA[fromUser] ]></FromUserName>
      	<CreateTime>12345678</CreateTime>
      	<MsgType>< ![CDATA[news] ]></MsgType>
      	<ArticleCount>2</ArticleCount>
      	<Articles>
      		<item>
      			<Title>< ![CDATA[title1] ]></Title>
      			<Description>< ![CDATA[description1] ]></Description>
      			<PicUrl>< ![CDATA[picurl] ]></PicUrl>
      			<Url>< ![CDATA[url] ]></Url>
      		</item>
      		<item>
      			<Title>< ![CDATA[title] ]></Title>
      			<Description>< ![CDATA[description] ]></Description>
      			<PicUrl>< ![CDATA[picurl] ]></PicUrl>
      			<Url>< ![CDATA[url] ]></Url>
      		</item>
      	</Articles>
      </xml>
      
      

    主动发送消息

    主动发送消息是通过模板消息实现的,模板消息仅用于公众号向用户发送重要的服务通知,只能用于符合其要求的服务场景中,如信用卡刷卡通知,商品购买成功通知等。

    为了发送模板消息,需要首先设置公众号所属的行业,之后公众号则只能使用该行业内的模板来发送模板消息;设置行业可以通过微信公众平台后台来完成,每月可修改一次;也可以通过接口调用的方式来修改所属行业;

    定义模板消息时需要注意的地方:

    1. 模板消息调用时主要需要模板ID和模板中各参数的赋值内容;
    2. 模板中参数内容必须以".DATA"结尾,否则视为保留字;
    3. 模板保留符号"{{ }}";
    4. 详情见:获得已添加到微信公众号里的所有模板列表;

    设置所属行业:

    请求方式: POST
    请求地址:https://api.weixin.qq.com/cgi-bin/template/api_set_industry?access_token=ACCESS_TOKEN
    POST数据格式:
    {"industry_id1":"1","industry_id2":"4"}
     
    
    

    获得模板ID:

    该过程可在公众号后台完成,同时提供接口:

    请求方式: POST
    请求地址:https://api.weixin.qq.com/cgi-bin/template/api_add_template?access_token=ACCESS_TOKEN
    POST数据格式:
    {"template_id_short":"TM00015"}
    正确返回消息说明:JSON
    {"errcode":0,"errmsg":"ok","template_id":"Doclyl5uP7Aciu-qZ7mJNPtWkbkYnWBWVja26EGbNyk"}
    错误返回消息说明:
    错误码通用。
    
    

    获取已添加到微信公众号里的所有模板列表:

    请求方式:GET
    请求地址:https//api.weixin.qq.com/cgi-bin/template/get_all_private_template?access_token=ACCESS_TOKEN
    返回结果说明:
    {    
     "template_list": [{
          "template_id": "iPk5sOIt5X_flOVKn5GrTFpncEYTojx6ddbt8WYoV5s",
          "title": "领取奖金提醒",
          "primary_industry": "IT科技",
          "deputy_industry": "互联网|电子商务",
          "content": "{ {result.DATA} }\n\n领奖金额:{ {withdrawMoney.DATA} }\n领奖  时间:{ {withdrawTime.DATA} }\n银行信息:{ {cardInfo.DATA} }\n到账时间:  { {arrivedTime.DATA} }\n{ {remark.DATA} }",
          "example": "您已提交领奖申请\n\n领奖金额:xxxx元\n领奖时间:2013-10-10 12:22:22\n银行信息:xx银行(尾号xxxx)\n到账时间:预计xxxxxxx\n\n预计将于xxxx到达您的银行卡"
       }]
    }
    
    

    删除模板:

    该过程可在公众号后台完成,同时提供接口:

    请求方式:POST
    请求地址:https://api.weixin.qq.com/cgi-bin/template/del_private_template?access_token=ACCESS_TOKEN
    POST数据格式:
    {"template_id" : "Dyvp3-Ff0cnail_CDSzk1fIc6-9lOkxsQE7exTJbwUE"}
    正确返回消息说明:JSON
    错误返回消息说明:
    {"errcode" : 0,"errmsg" : "ok"}
    错误码通用。
    
    

    发送模板消息:

    请求方式: POST
    请求地址:https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=ACCESS_TOKEN
    POST数据格式:
    {
    	"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"
            }
        }
    }
    正确返回消息格式:
    {"errcode":0,"errmsg":"ok","msgid":200228332}
    
    

    事件推送:

    在模版消息发送任务完成后,微信系统会将是否送达成功作为通知,发送到响应系统。

    送达成功时,推送的XML如下:
    <xml>
    	<ToUserName>< ![CDATA[gh_7f083739789a] ]></ToUserName>
    	<FromUserName>< ![CDATA[oia2TjuEGTNoeX76QEjQNrcURxG8] ]></FromUserName>
    	<CreateTime>1395658920</CreateTime>
    	<MsgType>< ![CDATA[event] ]></MsgType>
    	<Event>< ![CDATA[TEMPLATESENDJOBFINISH] ]></Event>
    	<MsgID>200163836</MsgID>
    	<Status>< ![CDATA[success] ]></Status>
    </xml>
    
    没有送达时,推送的XML如下:
    <xml>
    	<ToUserName>< ![CDATA[gh_7f083739789a] ]></ToUserName>
    	<FromUserName>< ![CDATA[oia2TjuEGTNoeX76QEjQNrcURxG8] ]></FromUserName>
    	<CreateTime>1395658984</CreateTime>
    	<MsgType>< ![CDATA[event] ]></MsgType>
    	<Event>< ![CDATA[TEMPLATESENDJOBFINISH] ]></Event>
    	<MsgID>200163840</MsgID>
    	<Status>< ![CDATA[failed:user block] ]></Status>	//failed: system failed——其他原因;failed:user block——用户拒绝接收该公众号的消息
    </xml>
    
    

    消息加密

    公众号消息加解密是为了进一步加强公众号安全保障,提供的新机制。公众账号主动调用API的情况不受影响。只有被动回复用户的消息时,才需要进行消息加解密。消息加解密方式:

    1. 明文模式:维持现有模式,没有适配加解密新特性,消息体明文收发,默认设置为明文模式;
    2. 兼容模式:公众平台发送消息内容将同时包括明文和密文,消息包长度增加到原来的3倍左右;公众号回复明文或密文均可,不影响现有消息收发;开发者可在此模式下进行调试;
    3. 安全模式(推荐):公众平台发送消息体的内容只含有密文,公众账号回复的消息体也为密文,建议开发者在调试成功后使用此模式收发消息

    启用加解密功能(即选择兼容模式或安全模式)后,微信系统在向响应系统推送消息时,URL将新增加两个参数(加密类型和消息体签名),并以此来体现新功能。加密算法采用AES。具体方案见该模块代码实现。

    获取微信系统服务器地址

    出于安全等考虑,如需要获知微信服务器的IP地址列表,可以通过该接口获得微信服务器IP地址列表或者IP网段信息。

    请求方式: GET
    请求地址:https://api.weixin.qq.com/cgi-bin/getcallbackip?access_token=ACCESS_TOKEN
    返回消息:JSON格式
    {"ip_list":["127.0.0.1","127.0.0.2","101.226.103.0/25"]}
    
    

    客服消息及管理

    当用户和公众号产生特定动作的交互时(具体动作列表请见下方说明),微信系统将会把消息数据推送给响应系统,响应系统可以在一段时间内(目前修改为48小时)调用客服接口,通过POST一个JSON数据包来发送消息给普通用户。此接口主要用于客服等有人工消息处理环节的功能,方便开发者为用户提供更加优质的服务。

    目前允许的动作列表如下(公众平台会根据运营情况更新该列表,不同动作触发后,允许的客服接口下发消息条数不同,下发条数达到上限后,会遇到错误返回码,具体请见返回码说明页):

    1. 用户发送信息
    2. 点击自定义菜单(仅有点击推事件、扫码推事件、扫码推事件且弹出“消息接收中”提示框这3种菜单类型将会触发客服接口)
    3. 关注公众号
    4. 扫描二维码
    5. 支付成功
    6. 用户维权

    客服账号管理:

    请注意,必须先在公众平台官网为公众号设置微信号后才能使用该能力。

    1. 添加客服账号

      请求方式: POST
      请求地址:https://api.weixin.qq.com/customservice/kfaccount/add?access_token=ACCESS_TOKEN
      POST数据示例如下:
      {
           "kf_account" : "test1@test",
           "nickname" : "客服1",
           "password" : "pswmd5",
      }
      返回说明(正确时的JSON返回结果):
      {"errcode" : 0,"errmsg" : "ok"}
      返回错误码是通用的
      
      
    2. 删除客服账号

      请求方式: GET
      请求地址:https://api.weixin.qq.com/customservice/kfaccount/del?access_token=ACCESS_TOKEN
      POST数据示例如下:
      {
           "kf_account" : "test1@test",
           "nickname" : "客服1",
           "password" : "pswmd5",
      }
      返回说明(正确时的JSON返回结果):
      {"errcode" : 0,"errmsg" : "ok"}
      返回错误码是通用的
      
      
    3. 修改客服账号

      请求方式: POST
      请求地址:https://api.weixin.qq.com/customservice/kfaccount/update?access_token=ACCESS_TOKEN
      POST数据示例如下:
      {
           "kf_account" : "test1@test",
           "nickname" : "客服1",
           "password" : "pswmd5",
      }
      返回说明(正确时的JSON返回结果):
      {"errcode" : 0,"errmsg" : "ok"}
      返回错误码是通用的
      
      

    设置客服账号头像

    开发者可调用该接口来上传图片作为客服人员的头像,头像图片文件必须是jpg格式,推荐使用640*640大小的图片以达到最佳效果。该接口调用请求如下:

    请求方式: POST/FORM
    请求地址:http://api.weixin.qq.com/customservice/kfaccount/uploadheadimg?access_token=ACCESS_TOKEN&kf_account=KFACCOUNT
    这里需要注意的是,官方文档中提到的是使用curl工具POST一个多媒体文件;这里我想只要通过代码将文件提交到上述地址就OK,因为curl是一个命令行工具,网上有在php中使用curl的,但是对Java的支持很惨淡,这一部分详见代码验证及图示。
    
    

    获取所有客服账号

    请求方式: GET
    请求地址:https://api.weixin.qq.com/cgi-bin/customservice/getkflist?access_token=ACCESS_TOKEN
    返回数据:
    {
        "kf_list": [
            {
                "kf_account": "test1@test", 
                "kf_nick": "ntest1", 
                "kf_id": "1001"	//这里需要注意的是,kf_id是第一次在这里出现,创建的时候并没有返回该字段;
                "kf_headimgurl": " http://mmbiz.qpic.cn/mmbiz/4whpV1VZl2iccsvYbHvnphkyGtnvjfUS8Ym0GSaLic0FD3vN0V8PILcibEGb2fPfEOmw/0"
            }, 
            {
                "kf_account": "test2@test", 
                "kf_nick": "ntest2", 
                "kf_id": "1002"
                "kf_headimgurl": " http://mmbiz.qpic.cn/mmbiz/4whpV1VZl2iccsvYbHvnphkyGtnvjfUS8Ym0GSaLic0FD3vN0V8PILcibEGb2fPfEOmw /0"
            }
        ]
    }
    
    

    客服接口-发送消息

    请求方式: POST
    请求地址:https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token=ACCESS_TOKEN
    各消息类型所需的JSON数据包如下:
    文本消息:
    {
        "touser":"OPENID",
        "msgtype":"text",
        "text":
        {
             "content":"Hello World"
        }
    }
    发送文本消息时,文本内容中可以携带跳转小程序的文字链:<a href="http://www.qq.com" data-miniprogram-appid="appid" data-miniprogram-path="pages/index/index">点击跳小程序</a>
    参数说明:
    1.data-miniprogram-appid 项,填写小程序appid,则表示该链接跳小程序;
    2.data-miniprogram-path项,填写小程序路径,路径与app.json中保持一致,可带参数;
    3.对于不支持data-miniprogram-appid 项的客户端版本,如果有herf项,则仍然保持跳href中的网页链接;
    
    注意,data-miniprogram-appid对应的小程序必须与公众号有绑定关系。
    
    发送图片消息:
    {
        "touser":"OPENID",
        "msgtype":"image",
        "image":
        {
          "media_id":"MEDIA_ID"
        }
    }
    
    发送语音消息:
    {
        "touser":"OPENID",
        "msgtype":"voice",
        "voice":
        {
          "media_id":"MEDIA_ID"
        }
    }
    
    发送视频消息:
    {
        "touser":"OPENID",
        "msgtype":"video",
        "video":
        {
          "media_id":"MEDIA_ID",
          "thumb_media_id":"MEDIA_ID",
          "title":"TITLE",
          "description":"DESCRIPTION"
        }
    }
    
    发送音乐消息:
    {
        "touser":"OPENID",
        "msgtype":"music",
        "music":
        {
          "title":"MUSIC_TITLE",
          "description":"MUSIC_DESCRIPTION",
          "musicurl":"MUSIC_URL",
          "hqmusicurl":"HQ_MUSIC_URL",
          "thumb_media_id":"THUMB_MEDIA_ID" 
        }
    }
    
    发送图文消息(点击跳转到外链) 图文消息条数限制在8条以内,注意,如果图文数超过8,则将会无响应。
    {
        "touser":"OPENID",
        "msgtype":"news",
        "news":{
            "articles": [
             {
                 "title":"Happy Day",
                 "description":"Is Really A Happy Day",
                 "url":"URL",
                 "picurl":"PIC_URL"
             },
             {
                 "title":"Happy Day",
                 "description":"Is Really A Happy Day",
                 "url":"URL",
                 "picurl":"PIC_URL"
             }
             ]
        }
    }
    
    发送图文消息:
    {
        "touser":"OPENID",
        "msgtype":"mpnews",
        "mpnews":
        {
             "media_id":"MEDIA_ID"
        }
    }
    
    发送卡券:
    {
      "touser":"OPENID", 
      "msgtype":"wxcard",
      "wxcard":{              
           "card_id":"123dsdajkasd231jhksad"        
       },
    }
    发送小程序卡片:
    {
        "touser":"OPENID",
        "msgtype":"miniprogrampage",
        "miniprogrampage":
        {
            "title":"title",
            "appid":"appid",
            "pagepath":"pagepath",
            "thumb_media_id":"thumb_media_id"
        }
    }
    
    

    微信网页开发

    网页授权获取用户基本信息

    用户在微信客户端中访问第三方网页,公众号可以通过微信网页授权机制,来获取用户基本信息,进而实现业务逻辑。

    这里需要注意的是同用户管理中的获取用户基本信息的区别:用户管理是在响应系统的完成的;而用户授权是在业务系统中完成的;两者工作的环境也是不同的,所以请求接口是不同的:第三方授权是在公众号内通过微信客户端进入网页时发生,而用户管理是公众号内部的管理行为;

    使用流程:

    1. 在微信公众号请求用户网页授权之前,开发者需要先到公众平台官网中的“开发 - 接口权限 - 网页服务 - 网页帐号 - 网页授权获取用户基本信息”的配置选项中,修改授权回调域名。
    2. 授权回调域名配置规范为全域名。配置后,该域名下的所有网页都可以进行OAuth2.0鉴权。

    两种请求模式:

    1. 以snsapi_base为scope发起的网页授权,用来获取进入页面的用户的openid的,并且是静默授权并自动跳转到回调页的。用户感知的就是直接进入了回调页(往往是业务系统的入口);

    2. 以snsapi_userinfo为scope发起的网页授权,用来获取用户的基本信息的。这种授权需要用户手动同意,并且由于用户同意过,所以无须关注,就可在授权后获取该用户的基本信息。

      注意:用户管理类接口中的“获取用户基本信息接口”,是在用户和公众号产生消息交互或关注后事件推送后,才能根据用户OpenID来获取用户基本信息。该接口以及包括其他微信接口,都是需要该用户(即openid)关注了公众号后,才能调用成功的。

    在OAuth2.0用户授权机制下,存在一个反应用户是否同意授权的标记,该标记在OAuth2.0的环境下称为:access_token。这和响应系统用于请求微信接口时使用的access_token是不一样的,但是它们的性质是相同的;

    特殊环境下的静默授权:

    1. 上面已经提到,对于以snsapi_base为scope的网页授权,就静默授权的,用户无感知;
    2. 对于已关注公众号的用户,如果用户从公众号的会话或者自定义菜单进入本公众号的网页授权页,即使是scope为snsapi_userinfo,也是静默授权,用户无感知。

    具体而言,网页授权流程分为四步:

    1. 引导用户进入授权页面同意授权,获取code

       请求地址:https://open.weixin.qq.com/connect/oauth2/authorize?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=SCOPE&state=STATE#wechat_redirect
       参数说明:APPID/REDIRECT_URI/SCOPE/StATE等为变量,其余为常量;参数顺序不可变;
      
      

      如果用户同意授权,页面将跳转至 REDIRECT_URI/?code=CODE&state=STATE。 code说明 : code作为换取access_token的票据,每次用户授权带上的code将不一样,code只能使用一次,5分钟未被使用自动过期。

    2. 通过code换取网页授权access_token(与基础支持中的access_token不同)

      请求地址:https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code
      参数说明:APPID/SECRET/CODE等为变量,其余为常量;参数顺序可变;
      返回数据:JSON
      { 
      	"access_token":"ACCESS_TOKEN",//	网页授权接口调用凭证,注意:此access_token与基础支持的access_token不同
      	"expires_in":7200,
      	"refresh_token":"REFRESH_TOKEN",//用户刷新access_token
      	"openid":"OPENID",
      	"scope":"SCOPE"
      }
      
      

      注意:由于公众号的secret和获取到的access_token安全级别都非常高,必须只保存在服务器,不允许传给客户端。后续刷新access_token、通过access_token获取用户信息等步骤,也必须从服务器发起。即当前请求是可以通过客户端进行的。

      另外,此时已经获得open id,即如果不需要使用union id 的话,网页授权到此结束;

    3. 如果需要,开发者可以刷新网页授权access_token,避免过期

      请求地址:https://api.weixin.qq.com/sns/oauth2/refresh_token?appid=APPID&grant_type=refresh_token&refresh_token=REFRESH_TOKEN
      参数说明:APPID/REFRESH_TOKEN为变量,REFRESH_TOKEN即为第二步获得数据
      
      
    4. 通过网页授权access_token和openid获取用户基本信息(支持UnionID机制)

      请求方式:GET
      请求地址:https://api.weixin.qq.com/sns/userinfo?access_token=ACCESS_TOKEN&openid=OPENID&lang=zh_CN
      参数说明:ACCESS_TOKEN即为第二步获得网页授权数据;OPENID一样;
      返回数据说明:JSON
      {
      	"openid":" OPENID",
      	" nickname": NICKNAME,
      	"sex":"1",
      	"province":"PROVINCE"
      	"city":"CITY",
      	"country":"COUNTRY",
      	"headimgurl": "http://thirdwx.qlogo.cn/mmopen/g3MonUZtNHkdmzicIlibx6iaFqAc56vxLSUfpb6n5WKSYVY0ChQKkiaJSgQ1dZuTOgvLLrhJbERQQ4eMsv84eavHiaiceqxibJxCfHe/46",
      	"privilege":[ "PRIVILEGE1" "PRIVILEGE2"     ],
      	"unionid": "o6_bmasdasdsad6_2sgVt7hMZOPfL"
      }
      
      

      整体来看,App Secret作为秘密数据,其获取也应该通过业务系统的验证以检查正在请求App Secret的网页是不是友军;

    微信JS-SDK的功能

    JS-SDK为第三方网页在微信客户端内使用本地资源提供JS封装的接口;这里不涉及具体API的使用,仅介绍JS-SDK的引入、调用接口权限的验证配置。

    引入JS文件:

    同普通JS文件。

    权限验证:

    所有需要使用JS-SDK的页面必须先注入配置信息,否则将无法调用,同一个url仅需调用一次,对于变化url的SPA的web app可在每次url变化时进行调用,目前Android微信客户端不支持pushState的H5新特性,所以使用pushState来实现web app的页面会导致签名失败,此问题会在Android6.2中修复。

    wx.config({
        debug: true, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
        appId: '', // 必填,公众号的唯一标识
        timestamp: , // 必填,生成签名的时间戳
        nonceStr: '', // 必填,生成签名的随机串
        signature: '',// 必填,签名,签名算法见后专门模块
        jsApiList: [] // 必填,需要使用的JS接口列表
    });
    
    wx.ready(function(){
        // config信息验证后会执行ready方法,所有接口调用都必须在config接口获得结果之后,config是一个客户端的异步操作,所以如果需要在页面加载时就调用相关接口,则须把相关接口放在ready函数中调用来确保正确执行。对于用户触发时才调用的接口,则可以直接调用,不需要放在ready函数中。
    });
    
    wx.error(function(res){
        // config信息验证失败会执行error函数,如签名过期导致验证失败,具体错误信息可以打开config的debug模式查看,也可以在返回的res参数中查看,对于SPA可以在这里更新签名。
    });
    
    

    所有接口通过wx对象(也可使用jWeixin对象)来调用,参数是一个对象,除了每个接口本身需要传的参数之外,还有以下通用参数:

    1. success:执行成功时的回调函数;
    2. fail:调用接口失败时执行的回调函数;
    3. complete:接口调用完成时执行的回调函数,无论成功或失败都会执行。
    4. cancel:用户点击取消时的回调函数,仅部分有用户取消操作的api才会用到。
    5. trigger: 监听Menu中的按钮点击时触发的方法,该方法仅支持Menu中的相关接口。

    以上几个函数都带有一个参数,类型为对象,其中除了每个接口本身返回的数据之外,还有一个通用属性errMsg,其值格式如下:

    1. 调用成功时:“xxx:ok” ,其中xxx为调用的接口名
    2. 用户取消时:“xxx:cancel”,其中xxx为调用的接口名
    3. 调用失败时:其值为具体错误信息

    签名算法

    生成签名之前必须先了解一下jsapi_ticket,jsapi_ticket是公众号用于调用微信JS接口的临时票据。正常情况下,jsapi_ticket的有效期为7200秒,通过access_token来获取。 开发者必须在自己的服务全局缓存jsapi_ticket 。

    生成签名的流程:

    1. 获得access_token:具体见上文目录;

    2. 用第一步拿到的access_token获得jsapi_ticket

      请求方法:GET
      请求地址:https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=ACCESS_TOKEN&type=jsapi
      返回数据说明:JSON
      {
      	"errcode":0,
      	"errmsg":"ok",
      	"ticket":"bxLdikRXVbTPdHSM05e5u5sUoXNKd8-41ZO3MhKoyN5OfkWITDGgnr2fwJ0m9E8NYzWKVZvdVtaUgWvsdshFKA",
      	"expires_in":7200
      }
      
      
    3. 签名生成规则如下:参与签名的字段包括noncestr(随机字符串), 有效的jsapi_ticket, timestamp(时间戳), url(当前网页的URL,不包含#及其后面部分) 。对所有待签名参数按照字段名的ASCII 码从小到大排序(字典序)后,使用URL键值对的格式(即key1=value1&key2=value2…)拼接成字符串string1。这里需要注意的是所有参数名均为小写字符。对string1作sha1加密,字段名和字段值都采用原始值,不进行URL 转义。 sha1加密后的结果即为signature;

    展开全文
  • 微信开发者文档

    2019-01-12 10:54:37
    用户在关注与取消关注公众号时,微信会把这个事件推送到开发者填写的URL。方便开发者给用户下发欢迎消息或者做帐号的解绑微信服务器在五秒内收不到响应会断掉连接,并且重新发起请求,总...
  • flask开发微信公众号

    2019-02-14 12:00:05
    公众平台发送的xml
  • 微信用户和公众号产生交互的过程中,用户的某些操作会使得微信服务器通过事件推送的形式通知到开发者开发者中心处设置的服务器地址,从而开发者可以获取到该信息。其中,某些事件推送在发生后,是允许开发者回复...
  • 微信开发时候在做消息接口交互的时候需要使用带微信加密ID(OpenId),下面讲讲述2中类型方式获取微信OpenID,接收事件推送方式和网页授权获取用户基本信息方式获取。
  • 微信用户和公众号产生交互的过程中,用户的某些操作会使得微信服务器通过事件推送的形式-&gt;通知到开发者开发者中心处设置的服务器地址,从而[开发者]可以获取到该信息。其中,某些事件推送在发生后,是...
  • 用户在关注与取消关注公众号时,微信会把这个事件推送到开发者填写的URL。方便开发者给用户下发欢迎消息或者做帐号的解绑。为保护用户数据隐私,开发者收到用户取消关注事件时需要删除该用户的所有信息。 微信服务....
  • 微信公众号
  • 转载自: ...   微信蓝牙BLE接入调试指引...2 微信测试公众号 2.1 申请测试公众号 可以在http://mp.weixin.qq.com/debug/cgi-bin/sandbox?t=sandbox/login申请到一个用于测试的公众号,这个帐号可以用于调试具用...
  • (一)微信公众号开发之VS远程调试 (二)微信公众号开发之基础梳理 (三)微信公众号开发之自动消息回复和自定义菜单 前言 上一篇我们大致讲解了下微信公众号开发的基本原理和流程概述。本章主要是对文本消息...
  • 1.发现 之前已经讨论过如何过滤微信推送的事件消息和...用户在关注与取消关注公众号时,微信会把这个事件推送到开发者填写的URL。方便开发者给用户下发欢迎消息或者做帐号的解绑微信服务器在五秒内收不到响应...
  • 关注/取消关注事件用户在关注与取消关注公众号时,微信会把这个事件推送到开发者填写的URL。方便开发者给用户下发欢迎消息或者做帐号的解绑微信服务器在五秒内收不到响应会断掉连接,并且重新发起请求,总共重试三...
  • 本文主要实现的功能包括 关注/取消关注事件 扫描带参数二维码事件 ...验证消息的确来自微信服务器,开发者提交信息后,微信服务器将发送GET请求到填写的服务器地址URL上 接收普通事件推送和接...
  • 开发者模式的开启 进入到公众号管理平台——开发——基本配置,对服务器配置进行服务的开启 服务器的地址url为:http://127.0.0.1:8080/myproject/WeChatServer 令牌(token)的设置与程序配置文件中的token设置...
  • 微信公众号实现跟关注用户进行消息的交互功能,我们可以简单的理解: (1)首先,用户向微信服务器发送消息; (2)微信服务器接收到用户的消息处理之后,通过开发者配置的URL和Token 来找到第三方服务器,并以XML...
1 2 3 4 5 ... 11
收藏数 207
精华内容 82