微信API工具包 [ Aha-Weixin ]

简化微信开发难度,上手简单,支持Spring Boot

Project maintained by Dean This project is released under the terms of the Apache License 2.0.

支持两种方式调用微信提供的API功能,自动维护微信的API调用凭证,开发者无需关心这部分的规则,拆包即用,支持两种方式同时使用。

  <dependency>
    <groupId>io.github.rcarlosdasilva</groupId>
    <artifactId>weixin</artifactId>
    <version>0.5-SNAPSHOT</version>
  </dependency>

支持Spring Boot,并提供了starter:

  <dependency>
    <groupId>io.github.rcarlosdasilva</groupId>
    <artifactId>weixin-spring-boot-starter</artifactId>
    <version>0.2-SNAPSHOT</version>
  </dependency>

1 依赖

常用工具类:Guava
Json解析:Gson
XML解析:XStream
Http:okhttp
缓存:jredis
日志:slf4j

2 配置

2.1 配置项(具体可查看Setting类中的注释)

2.2 通用方式

weixin工具包有默认的配置,如需改变,需要实例一个Setting对象,配置内容可参照 2.1

  Setting setting = new Setting();
  // setting.setUseRedisCache(true);
  // setting.setUseSpringRedis(true);
  WeixinRegistry.withSetting(setting);

  //如果使用第三方平台
  WeixinRegistry.openPlatform(appId, appSecret, aesToken, aesKey);

2.3 或使用Spring Boot Starter

如果使用Starter,则可借用Spring Boot的自动配置,以YAML做配置为例:

weixin:
  throw-exception: true
  cache-type: reids
  use-spring-redis-config: true
  # 如果使用第三方平台
  open-platform:
    app-id: 三方平台appid
    app-secret: 三方平台secret
    aes-token: 加密aes token
    aes-key: 加密aes key

3 加载公众号信息

3.1 公众号信息内容

使用weixin工具包之前,需要将公众号的相关信息加载一下,工具包才能自动维护API调用凭证等数据。Account类用来存储这些信息,主要包含:

使用Account.create(appId, appSecret)创建一个使用公众号平台管理的公众号信息(withOpenPlatform会自动设置为false)。使用Account.create(appId)创建一个使用第三方平台管理的公众号信息

3.2 通用方式

  Account accountWithNormalWeixin = Account.create(appId, appSecret);
  // 配置其他内容 accountWithNormalWeixin.setMpId(mpid) 等
  Account accountAuthorizedForOpenPlatform = Account.create(appId);

  // weixin工具包可以自动识别,每个公众号应该通过哪种公众号管理方式来获取API调用凭证等数据
  WeixinRegistry.register(accountWithNormalWeixin);
  WeixinRegistry.register(accountAuthorizedForOpenPlatform);
  // 有几个公众号就调用几遍WeixinRegistry.register方法

  // 假如只需要控制一个公众号,则
  // Account singleAccount = Account.create(appId, appSecret);
  // WeixinRegistry.registerUnique(singleAccount);

3.3 或使用Spring Boot Starter

实现Starter中的AccountLoader接口,并保证在Spring中注册Bean,在load方法中返回公众号信息,而不用关心如何加载,例如:

@Component
public class WeixinAccountLoader implements AccountLoader {

  @Override
  public List load() {
    List accounts = new ArrayList();

    // 创建公众号信息集合

    return accounts;
  }

}

weixin starter会尝试注入AccountLoader并自动注册load方法返回的公众号

4 监听器

weixin工具包会自动维护管理所有与微信API调用凭证相关的数据,不需要开发者介入就可以简单实现微信开发。但有时开发者会有储存微信API调用凭据(access_token)等数据的需要,这里提供了几个监听器接口,开发者可自行实现这些接口,每次凭据有更新后,监听器都会获取到最新的数据,进行相应的业务处理。

4.1 提供的接口

4.2 通用注册监听器

  // Setting配置参考2.2
  Setting setting = new Setting();
  // 实例化监听器的实现类
  OpenPlatformAccessTokenUpdatedListener listener = new ListenerImpl();
  setting.addListener(listener);

4.3 或使用Spring Boot Starter

只要保证将监听器的实现类在Spring中注册Bean,weixin starter会自动注入监听器

5 API调用

当前weixin工具包实现了自定义菜单、素材管理、消息管理、用户管理、客服消息等功能API

5.1 典型调用示例

待完善    具体功能与使用可参考io.github.rcarlosdasilva.weixin.api.internal包中API调用接口类中的注释

5.2 已实现API速查

示例: 第一行:Weixin.with(key).certificate().askAccessToken()

公众号平台API
微信文档目录 调用入口 调用方法
注意:使用generateJsapiSignature生成JS-SDK签名时,会自动获取js_ticket,无需开发者手动调用
开始前必读 > 接口调用频次限制说明 > 公众号的所有api调用次数进行清零 helper resetQuota
开始开发 > 获取access_token certificate askAccessToken
开始开发 > 获取微信服务器IP地址 common getWeixinIps
自定义菜单 > 自定义菜单创建接口 menu create
自定义菜单 > 自定义菜单查询接口 menu query
自定义菜单 > 自定义菜单删除接口 menu delete
自定义菜单 > 个性化菜单接口 > 创建个性化菜单 menu createWithConditional
自定义菜单 > 个性化菜单接口 > 删除个性化菜单 menu deleteWithConditional
自定义菜单 > 个性化菜单接口 > 测试个性化菜单匹配结果 menu testWithConditional
自定义菜单 > 获取自定义菜单配置接口 menu queryComplete
消息管理 > 发送消息-客服消息 > ? 请使用新版客服功能 - -
消息管理 > 发送消息-群发接口和原创校验 > 上传图文消息内的图片获取URL media addMassMediaImage
消息管理 > 发送消息-群发接口和原创校验 > 上传图文消息素材 media addMassMediaNews
消息管理 > 发送消息-群发接口和原创校验 > 视频特殊处理转换media_id media transformMassMediaVideo
消息管理 > 发送消息-群发接口和原创校验 > 根据标签进行群发 message sendWithMass4Tag
消息管理 > 发送消息-群发接口和原创校验 > (发送给所有人) message sendWithMassAll
消息管理 > 发送消息-群发接口和原创校验 > 根据OpenID列表群发 message sendWithMass4Users
消息管理 > 发送消息-群发接口和原创校验 > 删除群发 message deleteMass
消息管理 > 发送消息-群发接口和原创校验 > 预览接口 message sendWithMassPreview
消息管理 > 发送消息-群发接口和原创校验 > 查询群发消息发送状态 message queryMassStatus
消息管理 > 发送消息-模板消息接口 > 设置所属行业 template setIndustry
消息管理 > 发送消息-模板消息接口 > 获取设置的行业信息 template getIndustry
消息管理 > 发送消息-模板消息接口 > 获得模板ID template append
消息管理 > 发送消息-模板消息接口 > 获取模板列表 template query
消息管理 > 发送消息-模板消息接口 > 删除模板 template delete
消息管理 > 发送消息-模板消息接口 > 发送模板消息 message sendWithTemplate
消息管理 > 发送消息-一次性订阅消息 > ? 待开发 - -
消息管理 > 获取公众号的自动回复规则 message queryAutoReplyStatus
微信网页开发 > 微信网页授权 > 第一步 certificate webAuthorize
微信网页开发 > 微信网页授权 > 第二步:通过code换取网页授权access_token certificate askWebAuthorizeAccessToken
微信网页开发 > 微信网页授权 > 第三步:刷新access_token certificate refreshWebAuthorizeAccessToken
微信网页开发 > 微信网页授权 > 第四步:拉取用户信息(需scope为 snsapi_userinfo) user getUserInfoByWebAuthorize
微信网页开发 > 微信网页授权 > 检验授权凭证(access_token)是否有效 certificate verifyWebAuthorizeAccessToken
微信网页开发 > 微信JS-SDK > JS-SDK使用权限签名算法 > jsapi_ticket certificate askJsTicket
微信网页开发 > 微信JS-SDK > JS-SDK使用权限签名算法 > 签名算法 certificate generateJsapiSignature
素材管理 > 新增临时素材 media addTemporaryMedia
素材管理 > 获取临时素材 media getTemporaryMedia
素材管理 > 获取临时素材 > 高清语音素材获取接口 media getTemporaryMediaWithHqAudio
素材管理 > 新增永久素材 > 新增永久图文素材 media addTimelessMediaNews
素材管理 > 新增永久素材 > 上传图文消息内的图片获取URL media addMassMediaImage
素材管理 > 新增永久素材 > 新增其他类型永久素材 media addTimelessMedia
素材管理 > 新增永久素材 > 新增永久视频素材 media addTimelessMediaVideo
素材管理 > 获取永久素材 media getTimelessMedia
素材管理 > 删除永久素材 media deleteTimelessMedia
素材管理 > 修改永久图文素材 media updateTimelessMedia
素材管理 > 获取素材总数 media countTimelessMedia
素材管理 > 获取素材列表 media listTimelessMedia
图文消息留言管理 > 打开已群发文章评论 comment open
图文消息留言管理 > 关闭已群发文章评论 comment close
图文消息留言管理 > 查看指定文章的评论数据 comment list
图文消息留言管理 > 将评论标记精选 comment star
图文消息留言管理 > 将评论取消精选 comment unstar
图文消息留言管理 > 删除评论 comment delete
图文消息留言管理 > 回复评论 comment reply
图文消息留言管理 > 删除回复 comment deleteReply
用户管理 > 用户标签管理 > 创建标签 userTag create
用户管理 > 用户标签管理 > 获取公众号已创建的标签 userTag list
用户管理 > 用户标签管理 > 编辑标签 userTag update
用户管理 > 用户标签管理 > 删除标签 userTag delete
用户管理 > 用户标签管理 > 获取标签下粉丝列表 user listUsersOpenIdWithTag
用户管理 > 用户标签管理 > 批量为用户打标签 userTag tagging
用户管理 > 用户标签管理 > 批量为用户取消标签 userTag untagging
用户管理 > 用户标签管理 > 获取用户身上的标签列表 userTag listBasedUser
用户管理 > 设置用户备注名 user remarkName
用户管理 > 获取用户基本信息(UnionID机制) user getUserInfo
用户管理 > 获取用户基本信息(UnionID机制) > 批量获取用户基本信息 user getUsersInfo
用户管理 > 获取用户列表 user listAllUsersOpenId
用户管理 > 黑名单管理 > 获取公众号的黑名单列表 user listUsersInBlack
用户管理 > 黑名单管理 > 拉黑用户 user appendUsersToBlack
用户管理 > 黑名单管理 > 取消拉黑用户 user cancelUsersFromBlack
账号管理 > 生成带参数的二维码 > 临时二维码请求 common createQrWithTemporary
账号管理 > 生成带参数的二维码 > 永久二维码请求 common createQrWithUnlimited
账号管理 > 生成带参数的二维码 > 通过ticket换取二维码 common qrImage
账号管理 > 生成带参数的二维码 > ? 直接获取临时二维码 common qrImageWithTemporary
账号管理 > 生成带参数的二维码 > ? 直接获取永久二维码 common qrImageWithUnlimited
账号管理 > 长链接转短链接接口 common getShortUrl
数据统计 > 用户分析数据接口 > 获取用户增减数据 statistics getUserSummary
数据统计 > 用户分析数据接口 > 获取累计用户数据 statistics getUserCumulate
数据统计 > 图文分析数据接口 > 获取图文群发每日数据 statistics getNewsSummary
数据统计 > 图文分析数据接口 > 获取图文群发总数据 statistics getNewsTotal
数据统计 > 图文分析数据接口 > 获取图文统计数据 statistics getNewsRead
数据统计 > 图文分析数据接口 > 获取图文统计分时数据 statistics getNewsReadHour
数据统计 > 图文分析数据接口 > 获取图文分享转发数据 statistics getNewsShare
数据统计 > 图文分析数据接口 > 获取图文分享转发分时数据 statistics getNewsShareHour
数据统计 > 消息分析数据接口 > 获取消息发送概况数据 statistics getMessageSummary
数据统计 > 消息分析数据接口 > 获取消息发送分时数据 statistics getMessageSummaryHour
数据统计 > 消息分析数据接口 > 获取消息发送周数据 statistics getMessageSummaryWeek
数据统计 > 消息分析数据接口 > 获取消息发送月数据 statistics getMessageSummaryMonth
数据统计 > 消息分析数据接口 > 获取消息发送分布数据 statistics getMessageDistributed
数据统计 > 消息分析数据接口 > 获取消息发送分布周数据 statistics getMessageDistributedWeek
数据统计 > 消息分析数据接口 > 获取消息发送分布月数据 statistics getMessageDistributedMonth
数据统计 > 接口分析数据接口 > 获取接口分析数据 statistics getInterfaceSummary
数据统计 > 接口分析数据接口 > 获取接口分析分时数据 statistics getInterfaceSummaryHour
微信卡券 > ? 待开发 - -
微信门店 > ? 待开发 - -
微信小店 > ? 待开发 - -
微信设备功能 > ? 待开发 - -
新版客服功能 > 客服管理 > 获取客服基本信息 custom accountList
新版客服功能 > 客服管理 > 获取在线客服基本信息 custom accountListOnline
新版客服功能 > 客服管理 > 添加客服帐号 custom accountAppend
新版客服功能 > 客服管理 > 邀请绑定客服帐号 custom accountBinding
新版客服功能 > 客服管理 > 设置客服信息 custom accountUpdate
新版客服功能 > 客服管理 > 上传客服头像 custom accountUploadAvatar
新版客服功能 > 客服管理 > 删除客服帐号 custom accountDelete
新版客服功能 > 会话控制 > 创建会话 custom sessionCreate
新版客服功能 > 会话控制 > 关闭会话 custom sessionClose
新版客服功能 > 会话控制 > 获取客户会话状态 custom sessionStatus
新版客服功能 > 会话控制 > 获取客服会话列表 custom sessionList
新版客服功能 > 会话控制 > 获取未接入会话列表 custom sessionWaitings
新版客服功能 > 获取聊天记录 custom messageRecords
微信摇一摇周边 > ? 待开发 - -
微信连Wi-Fi > ? 待开发 - -
微信扫一扫 > ? 待开发 - -
微信发票 > ? 待开发 - -
? 其他 > 判断是否合法微信ip helper isLegalRequestIp
? 其他 > 验证公众号信息是否正确 helper isUsable
开放平台API
微信文档目录 调用入口 调用方法
注意:1. 使用openPlatformAuthorize生成授权地址时,会自动获取预授权码,正常情况下,无需手动调用askPreAuthCode获取。        2. getLicenseInformation与getLicensorInformation方法会根据Setting配置autoLoadAuthorizedWeixinData属性,自动调用(参考2.1)
授权流程技术 > 获取第三方平台component_access_token openAuth askAccessToken
授权流程技术 > 获取预授权码pre_auth_code openAuth askPreAuthCode
授权流程技术 > 使用授权码换取公众号或小程序的接口调用凭据和授权信息 openAuth getLicenseInformation
授权流程技术 > 获取(刷新)授权公众号或小程序的接口调用凭据(令牌) openAuth refreshLicensorAccessToken
授权流程技术 > 获取授权方的帐号基本信息 openAuth getLicensorInformation
授权流程技术 > 获取授权方的选项设置信息 openAuth getLicensorOption
授权流程技术 > 设置授权方的选项信息 openAuth setLicensorOption
授权流程技术 > 引入用户进入授权页 openAuth openPlatformAuthorize
开发前必读 > 权限说明 > 拉取当前所有已授权的帐号基本信息 ? 待开发 - -
代公众号实现业务 > 调用接口 > 第三方平台对其所有API调用次数清零 openAuth resetQuota
代公众号实现业务 > 发起网页授权 > 第一步 openCertificate webAuthorize
代公众号实现业务 > 发起网页授权 > 第二步:通过code换取access_token openCertificate askWebAuthorizeAccessToken
代公众号实现业务 > 发起网页授权 > 第三步:刷新access_token(如果需要) openCertificate refreshWebAuthorizeAccessToken
代公众号实现业务 > 发起网页授权 > 第四步:通过网页授权access_token获取用户基本信息(需授权作用域为snsapi_userinfo) user getUserInfoByWebAuthorize
代公众号实现业务 > 使用JS SDK certificate generateJsapiSignature
代公众号实现业务 > 卡券强授权 ? 待开发 - -
代公众号实现业务 > 微信广告接口 ? 待开发 - -
代公众号实现业务 > 微信开放平台帐号管理 ? 待开发 - -
全网发布 ? 待开发 - -

6 微信通知回调处理

微信的服务器会在粉丝用户给公众号发送文本、图片、语音等消息,或自定义菜单点击、扫码等事件产生时,对开发者服务器特定接口,发起通知请求,具体通知规则与内容参考微信文档。
另外,使用开放平台的第三方平台时,公众号对三方平台进行授权的过程,微信的服务器也会对开发者服务器特定接口进行通知请求。
接收并解析微信服务器发来的通知,需要开发实现NotificationHandler接口,或继承DefaultNotificationHandler(建议继承DefaultNotificationHandler)

NotificationHandler中定义了不同的方法,来响应微信文档中定义的不同通知内容。例如:

6.1 指定通知处理类

实例化NotificationHandler的实现类,在系统启动时(保证在微信服务器发来通知前),执行:

  NotificationHandlerProxy.proxy(notificationHandler);

如果使用Spring Boot Starter,则只要保证将NotificationHandler的实现类在Spring中注册Bean即可,Starter会自动识别,例如:

@Component
public class BusinessNotificationHandler extends DefaultNotificationHandler {
  ...
}

6.2 如何响应

NotificationHandler接口中定义的每个方法中都有一个NotificationResponseBuilder(响应构造器)参数,开发者根据业务需求通过NotificationResponseBuilder构造响应内容。

构造器可响应给微信如下几种类型的内容:

在每个方法中都会有一个Notification类型参数,使用notification.getAccount()方法就可以获取到当前通知消息相关的公众号信息(在开放平台下,进行授权过程的相关方法中除外)。

6.3 接收通知

开发者在获取到微信传来的参数后,使用NotificationHandlerProxy.instance().process()方法获取返回微信的内容。在这个方法中,会自动解密,根据NotificationHandler实现类中对应的方法中构建的响应内容进行加密,生成加密后的XML格式响应结果。

使用Spring MVC的例子(开放平台):

  @RequestMapping(value = "notification/open/{appId}", method = RequestMethod.POST)
  @ResponseBody
  public String notificationCallback(@PathVariable String appId,
      @RequestParam(value = "msg_signature", required = true) String signature,
      @RequestParam(value = "timestamp", required = true) long timestamp,
      @RequestParam(value = "nonce", required = true) String nonce, @RequestBody String content) {

    return NotificationHandlerProxy.instance().process(appId, content, signature, timestamp, nonce);
  }

使用Spring MVC的例子(公众号平台):

  @RequestMapping(value = "notification", method = RequestMethod.POST)
  @ResponseBody
  public String notificationCallback(@RequestParam(value = "signature", required = true) String signature,
      @RequestParam(value = "timestamp", required = true) long timestamp,
      @RequestParam(value = "nonce", required = true) String nonce, @RequestBody String content) {

    return NotificationHandlerProxy.instance().process(content, signature, timestamp, nonce);
  }

注意:开放平台中,签名获取的参数名为msg_signature,公众号平台中是signature

7 (开放平台)第三方平台公众号授权过程

开发者需要暴露两个接口,授权事件接收URL和公众号消息与事件接收URL。这里解释授权事件接收URL中的代码。

使用Spring MVC的例子(与普通消息和事件消息类似):

  @RequestMapping(value = "authorization", method = RequestMethod.POST)
  @ResponseBody
  public String authorizationCallback(@RequestParam(value = "msg_signature", required = true) String signature,
      @RequestParam(value = "timestamp", required = true) long timestamp,
      @RequestParam(value = "nonce", required = true) String nonce, @RequestBody String content) {

    return NotificationHandlerProxy.instance().process(content, signature, timestamp, nonce);
  }

授权过程中会调用NotificationHandler的doInfoOfComponentVerifyTicket、doInfoOfAuthorizeSucceeded、doInfoOfAuthorizeCanceled、doInfoOfAuthorizeUpdated四个方法

7.1 授权地址

开发者不用关心三方平台的component_access_token,也无须关心预授权码如何获取,在引导公众号管理员授权时,使用Weixin.withOpenPlatform().openAuth() .openPlatformAuthorize("成功后跳转地址")方法获取授权地址。

7.2 授权成功(更新)后的处理

管理员授权成功后,微信会做两次请求:1. 页面的跳转(GET),并在页面地址后加上授权码。 2. 微信服务器会发起对开发者服务器的授权事件接收URL请求(POST),请求内容中会传递授权码过来

两次请求都有授权码,这里建议,在页面的跳转请求中,获取到授权码后不进行任何授权相关的操作,这部分工作应放在服务器端完成。如开发者需要在跳转页面中,显示本次授权的公众号相关信息,可利用授权码对开发者服务器做轮询调取