GithubHelp home page GithubHelp logo

wechat's Introduction

WechatBuild Status

轻量的微信公众号组件(A Lightweight Wechat Component)

  • 包引入

     <dependency>
         <groupId>me.hao0</groupId>
         <artifactId>wechat</artifactId>
         <version>1.9.3</version>
     </dependency>
  • 依赖包,注意引入项目时是否需要exclude:

     <dependency>
         <groupId>me.hao0</groupId>
         <artifactId>common</artifactId>
         <version>1.1.3</version>
     </dependency>
     <!-- 1.3.0之后引入 -->
     <dependency>
         <groupId>com.google.guava</groupId>
         <artifactId>guava</artifactId>
         <version>19.0</version>
     </dependency>
  • 业务系统与微信公众号交互图阐述:

  • API基本用法:

     Wechat wechat = 
     	WechatBuilder.newBuilder("appId", "appSecret")
     					.conf1()  // 其他可选配置
     					...
     					.build();
     // 同步调用
     wechat.module().api();
     
     // 异步调用
     wechat.module().api(Callback<T>);
  • Wechat已实现以下组件:

    • 基础: base()
    • 用户: user()
    • 菜单: menu()
    • 多客服: cs()
    • 消息: msg()
    • 二维码: qr()
    • 素材: material()
    • JS调用相关: js()
    • 数据统计: data()
  • API使用文档见这里

  • 组件扩展: 如果想自己扩展组件,可以继承Component,调用register:

     public class MyComponent extends Component {
         // ...
     }
     MyComponent myComp = new MyComponent();
    wechat.register(myComp);
  • AccessToken管理:

    由于微信服务器限制AccessToken请求次数,并且频繁请求AccessToken并不是一个明智之举,需要将获取的AccessToken保存下来,待过期时,再去请求新的AccessToken,所以以上API均提供了无accessToken版本,如:

     List<String> ip();
     List<String> ip(String accessToken);
  • 实现AccessTokenLoader:

     public interface AccessTokenLoader {
    
         /**
          * 获取accessToken
          * @return accessToken,若""或NULL会重新从微信获取accessToken,并触发refresh方法
          */
         String get();
     
         /**
          * 刷新accessToken,实现时需要保存一段时间,以免频繁从微信服务器获取
          * @param token 从微信获取的新AccessToken
          */
         void refresh(AccessToken token);
     }
  • 默认的AccessTokenLoader实现(生产环境不推荐使用):

     public class DefaultAccessTokenLoader implements AccessTokenLoader {
     
         private volatile AccessToken validToken;
     
         @Override
         public String get() {
             return (validToken == null
                     || Strings.isNullOrEmpty(validToken.getAccessToken())
                     || System.currentTimeMillis() > validToken.getExpiredAt()) ? null : validToken.getAccessToken();
         }
     
         @Override
         public void refresh(AccessToken token) {
             validToken = token;
         }
     }
  • Ticket管理: 同AccessToken类似,需自己实现接口TicketLoader:

     public interface TicketLoader {
    
         /**
          * 获取Ticket
          * @param type ticket类型
          *             @see me.hao0.wechat.model.js.TicketType
          * @return 有效的ticket,若返回""或null,则重新从微信请求Ticket,并触发refresh方法
          */
         String get(TicketType type);
     
         /**
          * 刷新Ticket
          * @param ticket 从微信获取的新Ticket
          */
         void refresh(Ticket ticket);
     }
  • 默认的TicketLoader实现(生产环境不推荐使用):

     public class DefaultTicketLoader implements TicketLoader {
    
         private final Map<TicketType, Ticket> tickets = new ConcurrentHashMap<>();
     
         @Override
         public String get(TicketType type) {
             Ticket t = tickets.get(type);
             return (t == null
                     || Strings.isNullOrEmpty(t.getTicket())
                     || System.currentTimeMillis() > t.getExpireAt()) ? null : t.getTicket();
         }
     
         @Override
         public void refresh(Ticket ticket) {
             tickets.put(ticket.getType(), ticket);
         }
     }
  • 具体例子,可见测试用例

  • 历史版本

    • 1.0.0:

      • 基础功能实现。
    • 1.1.0:

      • 实现代码简化,个别类访问权限修改;
      • 实现MATERIAL组件。
    • 1.2.0:

      • 废弃~~Wechat.newWechat~~构建方法,替换为WechatBuilder方式。
      • *Loader设置过期时刻。
      • 实现JSSDK组件。
    • 1.3.0:

      • 引入guava
      • API支持异步调用。
    • 1.4.0:

      • 组件懒加载。
      • 改变组件访问方式,由变量方法
    • 1.5.0:

      • 上传客服头像。
      • 消息转发客服接口移至消息模块。
      • 实现DATA组件。
    • 1.6.0:

      • 将通用工具类移入common组件。
    • 1.6.1:

      • 文档完善,类访问权限控制;
      • 更新最新common包。
    • 1.6.2:

      • 参数严格校验。
    • 1.6.3:

      • 简化校验。
    • 1.6.4:

    • 1.6.5

      • 升级common,去掉kfAccount校验。
    • 1.6.6

      • 修复respNews参数校验。
    • 1.6.7

      • 消息群发兼容msgId为Int时。
    • 1.6.8

      • 修复消息被动回复问题。
    • 1.6.9

      • 修复微信菜单事件类型判断。
    • 1.6.10

      • 修复User.unionId为String类型。
    • 1.7.0

      • 增加获取用户列表的接口Users.getUsers()
    • 1.8.0

      • 增加通过场景字符串获取永久二维码的接口QrCodes.getPermQrcodeBySceneStr()
    • 1.9.0

      • 增加获取未关注公众号用户的信息接口;
      • 升级common,guava。
    • 1.9.1

      • 修复用户授权accessToken获取;
      • 废弃Bases.openId,替换为Bases.authAccessToken。
    • 1.9.2

      • 增加模版消息事件类型RecvTemplateSendJobFinishEvent
      • 兼容在接收到微信新增的事件消息时,不作抛错处理,而是返回RecvUnknownEvent
    • 1.9.3

      • 升级common包到1.1.3,修复XmlReaders线程安全问题。
  • 微信相关文档

有事请烧钱

  • 支付宝:

  • 微信:

wechat's People

Contributors

ergoucj avatar ihaolin avatar weit avatar zhblue avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

wechat's Issues

微信企业号的支持

微信企业号有个别接口与公众号不同,比如企业号用code获取的是userid,然后要用接口才能换成openid。而且可能还有其他不同的接口。
本项目是否考虑加入这方面的支持

messages respNews function has an error

/**
* 被动回复微信服务器图文消息
* @param openId 用户openId
* @param articles 图片消息对象列表,长度小于10
* @return XML图文消息
*/
public String respNews(String openId, List

articles){
……
checkArgument(articles.size() > 10, "articles length must < 10");
==》
checkArgument(articles.size() < 10, "articles length must < 10");
……
}

User API unionid should be string

actually, in me.hao0.wechat.model.user.User class, the unionid was defined as an Integer, it should be string

@JsonProperty("unionid")
    private Integer unionId;

sendtemplate api https 无法发送 报43003错误

public Long sendTemplate(String accessToken, String openId, String templateId, String link, List fields) {
Preconditions.checkNotNullAndEmpty(accessToken, "accessToken");
Preconditions.checkNotNullAndEmpty(openId, "openId");
Preconditions.checkNotNullAndEmpty(templateId, "templateId");
String url = "http://api.weixin.qq.com/cgi-bin/message/template/send?access_token=" + accessToken;
Map<String, Object> params = this.buildTemplateParams(openId, templateId, link, fields);
Map<String, Object> resp = this.doPost(url, params);
Object msgId = resp.get("msgid");
return Long.valueOf(msgId instanceof Long?((Long)msgId).longValue():((Integer)msgId).longValue());
}
url 里的 http https 是否可配置

castexception location core.Messages

/**
* 群发消息:
* 1. 分组群发:【订阅号与服务号认证后均可用】
* 2. 按OpenId列表发: 订阅号不可用,服务号认证后可用
* @see me.hao0.wechat.model.message.send.SendMessageScope
* @param accessToken accessToken
* @param msg 消息
* @return 消息ID,或抛WechatException
* {errcode=0, errmsg=send job submission success, msg_id=402533248},这个值没带L
* (Long)resp.get("msg_id") ,是错的
*/
public Long send(String accessToken, SendMessage msg){
……
return (Long)resp.get("msg_id");
===>
return Long.parseLong(resp.get("msg_id").toString());
}

here is the test

public static void main(String[] args){
Map<String, Object> resp = new HashMap<String, Object>();
resp.put("integer",2);
resp.put("long",12L);
System.out.print((Integer)resp.get("integer"));
System.out.print((Long)resp.get("long"));
// System.out.print((Long)resp.get("integer")); //case error
}

EVENT中缺少TEMPLATESENDJOBFINISH 事件

使用模板消息接口时 回调地址可能会接收到 微信端的 TEMPLATESENDJOBFINISH 事件
在parse2RecvEvent没有找到对应类型 会报出unknown event msg的错误

组件内关于doPost的不良实现

现有个多线程调用发送模板消息的功能,通过服务器监控发现在此情形下抛出java.net.BindException: Address already in use: connect

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.