# wecom-sdk **Repository Path**: MakeDebug/wecom-sdk ## Basic Information - **Project Name**: wecom-sdk - **Description**: 企业微信API Java SDK - **Primary Language**: Java - **License**: Apache-2.0 - **Default Branch**: release - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 82 - **Created**: 2023-06-03 - **Last Updated**: 2023-06-03 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README
wecom-sdk

点击立即微信咨询 点击加入QQ交流群

如果你感觉这个项目不错,请点击右上角的Star以鼓励作者,谢谢。

## 简介 wecom-sdk是开源的企业微信开放API的Java实现,历经三年迭代,目前已经实现了企业微信相关接口近200个,配置简单、API友好、开发人员不需要很高的学习成本就能快速接入企业微信。 ## 特性 - 支持多企业微信同时配置作业 - 目前实现企业微信接口 180 多个,能满足大部分场景的需求 - 全参数封装,入参、出参高度语义化封装,再也不担心组织参数、解析参数的问题 - 实现统一回调,所有回调事件可集中异步处理,开发者只需要关心业务逻辑的处理 - 由 SDK 接管 AccessToken 生命周期,开发者无需关心 Token 的管理。 ## 采用技术栈 - Spring RestTemplate - okhttp - lombok - jackson2 - xstream ## 使用方法 目前自建应用大部分功能可以适配,其它模式未适配。 ## Maven中央仓库坐标 ```xml cn.felord wecom-sdk ${wecom.sdk.version} ``` ## 入门 Spring Boot 例子参见项目的`samples/spring-boot-sample`。 ### 例子 这里屏蔽了一些繁琐的步骤,开发者只需要做好配置即可调用。以下是调用企业群发API向客户群发送图文的例子: ```java //① 应用参数组装 建议持久化并使用缓存层 AgentDetails externalAgent=DefaultAgent.nativeAgent("企业ID", "应用密钥", NativeAgent.EXTERNAL); //② 定义缓存 全局定义一次即可 WeComTokenCacheable weComTokenCacheable=new Cache(); //③ 初始化API入口,建议注入Spring IoC WorkWeChatApi wecom=new WorkWeChatApi(weComTokenCacheable); //④ 检索具体的API ExternalContactManager externalContactManager=wecom.externalContactManager(externalAgent); //⑤ 组织参数 MsgTemplateRequest request=new MsgTemplateRequest(ChatType.GROUP); ContentText text=new ContentText("测试企业向客户群发送信息"); request.setText(text); Link link=new Link(); link.setTitle("百度一下"); link.setDesc("遇到问题,百度一下"); link.setUrl("https://www.baidu.com"); link.setPicurl("https://www.baidu.com/img/pc_79b50cf376490.png"); request.setAttachments(Collections.singletonList(new LinkMsgAttachment(link))); request.setSender("zhangsan"); //⑥ 向企业微信服务器发起请求并获取响应结果 MsgTemplateResponse msgTemplateResponse=externalContactManager.messageApi() .addMsgTemplate(request); Integer errcode=msgTemplateResponse.getErrcode(); String errmsg=msgTemplateResponse.getErrmsg(); String msgid=msgTemplateResponse.getMsgid(); List failList=msgTemplateResponse.getFailList(); ``` 步骤是不是非常简单,基本都是在组装参数。可能里面有几个概念大家会有疑惑,接下来我们对里面的一些重要概念进行一些说明。 ### 实现缓存接口 需要实现标记缓存接口`cn.felord.WeComCacheable`的接口,分别用来存储**access_token**,**企业jsapi_ticket**,**应用jsapi_ticket ** > 具体缓存策略根据企业微信文档自行实现。 ### 应用抽象 AgentDetails `cn.felord.AgentDetails` 是对应用的抽象描述,包含了企业ID`corpId`,应用ID`agentId`以及密钥`secret` ,绝大多数接口的调用会用到它,默认实现是`DefaultAgent`。如果是自建应用你可以这样初始化: ```java AgentDetails agent=new DefaultAgent("企业ID","应用密钥","应用ID"); ``` 如果是内置应用,比如外部联系人应用: ```java AgentDetails external=DefaultAgent.nativeAgent("企业ID","应用密钥",NativeAgent.EXTERNAL); ``` 通常这些应用参数会存入数据库,然后我们需要通过**企业ID**和**应用ID**实现应用配置检索服务(可以增加缓存来降低数据库的检索压力): ``` (corpId,agentId)->AgentDetails ``` ### 缓存中继 `WeComTokenCacheable`定义企业微信所需要的`AccessToken`、`corpticket`和`agentticket`中继缓存。这里我使用了Spring Cache实现,你可以自由选择,但是要自行保证中继服务器数据一致性。 ```java public static class RedisWeComCacheable implements WeComTokenCacheable { private static final String QYWX_TOKEN_CACHE = "token::qywx"; private static final String QYWX_CORP_TICKET_CACHE = "ticket::qywx::corp"; private static final String QYWX_AGENT_TICKET_CACHE = "ticket::qywx::agent"; @CachePut(value = {QYWX_TOKEN_CACHE}, key = "#corpId.concat('::').concat(#agentId)") @Override public String putAccessToken(@NotNull String corpId, @NotNull String agentId, @NotNull String accessToken) { return accessToken; } @Cacheable(value = {QYWX_TOKEN_CACHE}, key = "#corpId.concat('::').concat(#agentId)") @Override public String getAccessToken(@NotNull String corpId, @NotNull String agentId) { return null; } @CachePut(value = {QYWX_CORP_TICKET_CACHE}, key = "#corpId.concat('::').concat(#agentId)") @Override public String putCorpTicket(@NotNull String corpId, @NotNull String agentId, @NotNull String corpTicket) { return corpTicket; } @Cacheable(value = {QYWX_TOKEN_CACHE}, key = "#corpId.concat('::').concat(#agentId)") @Override public String getCorpTicket(@NotNull String corpId, @NotNull String agentId) { return null; } @CachePut(value = {QYWX_AGENT_TICKET_CACHE}, key = "#corpId.concat('::').concat(#agentId)") @Override public String putAgentTicket(@NotNull String corpId, @NotNull String agentId, @NotNull String agentTicket) { return agentTicket; } @Cacheable(value = {QYWX_TOKEN_CACHE}, key = "#corpId.concat('::').concat(#agentId)") @Override public String getAgentTicket(@NotNull String corpId, @NotNull String agentId) { return null; } } ``` ### API入口类 `WorkWeChatApi`是企业微信API的唯一入口,推荐注入**Spring IoC** ,然后就可以通过它的一系列方法来实现企业微信提供的功能了。例如通过手机号查询成员的企业微信userid: ```java AgentDetails agent=DefaultAgent.nativeAgent("企业ID","通讯录secret",NativeAgent.CONTACT); GenericResponse userIdByMobile=wecom.contactBookManager(agent) .userApi() .getUserIdByMobile("这里为手机号"); String userId=userIdByMobile.getData(); ``` ### 回调 回调的处理通过`CallbackCrypto`来负责,它屏蔽了验签、解密、异步处理等技术难点,你可以通过`CallbackCryptoBuilder` 构建`CallbackCrypto`,并把`CallbackCrypto`注入Spring IoC。 #### CallbackCryptoBuilder `CallbackCryptoBuilder`有几个关键点: - `XmlReader` XML解析的抽象,框架默认提供了XStream实现,不喜欢的可以重新实现注入。 - `Consumer` 消费事件函数,用来处理回调数据。 - `CallbackSettingsService` 企业微信回调配置检索,用来检索回调的配置参数。 - `ExecutorService` 回调处理线程池,回调数据的处理是异步的,这里默认提供了一个名字为`WECOM-CALLBACK-THREAD-POOL` 的线程池,你也可以自定义一个符合你实际配置的线程池。 参考示例: ```java @Bean public CallbackCrypto callbackCrypto(IEventRecordService eventRecordService, IWeCallbackSettingsService callbackSettingsService){ return new CallbackCryptoBuilder(eventRecordService::handleCallbackEvent) .build(callbackSettingsService::getByAgentIdAndCorpId); } ``` #### 回调示例 通用回调参考示例: ```java @RestController @RequestMapping("/wecom/callback") public class CallbackController { /** * The Callback crypto. */ @Autowired CallbackCrypto callbackCrypto; /** * 验证回调URL * * @param msgSignature the msg signature * @param timestamp the timestamp * @param nonce the nonce * @param echostr the echostr * @param corpId the corp id * @param agentId the agent id * @return the long */ @GetMapping("/{corpId}/{agentId}") public String verifyUrl(@RequestParam("msg_signature") String msgSignature, @RequestParam String timestamp, @RequestParam String nonce, @RequestParam String echostr, @PathVariable String corpId, @PathVariable String agentId) { return callbackCrypto.decryptMsg(agentId, corpId, msgSignature, timestamp, nonce, echostr); } /** * 消费回调数据 * * @param msgSignature the msg signature * @param timestamp the timestamp * @param nonce the nonce * @param xmlBody the xml body * @param corpId the corp id * @param agentId the agent id * @return the string */ @PostMapping("/{corpId}/{agentId}") public String consume(@RequestParam("msg_signature") String msgSignature, @RequestParam String timestamp, @RequestParam String nonce, @RequestBody String xmlBody, @PathVariable String corpId, @PathVariable String agentId) { return callbackCrypto .accept(agentId,corpId,msgSignature, timestamp, nonce, xmlBody); } } ``` > 目前暂时不支持第三方开发 ## API实现进度 - 获取企业微信API域名IP段 - [x] 获取企业微信API域名IP段 - 自建应用与第三方应用的对接 - [x] 自建应用与第三方应用的对接 - 通讯录管理 - [x] 成员管理 - [x] 部门管理 - [x] 标签管理 - [x] 异步导入接口 - [x] 通讯录回调通知 - [x] 互联企业 - 客户联系 - [x] 企业服务人员管理 - [x] 客户管理 - [x] 客户标签管理 - [x] 在职继承 - [x] 离职继承 - [x] 客户群管理 - [x] 联系我与客户入群方式 - [x] 客户朋友圈 - [x] 消息推送 - [x] 统计管理 - [x] 变更回调 - [x] 管理商品图册 - [x] 管理聊天敏感词 - [x] 上传附件资源 - [x] 微信客服 - [x] 客服账号管理 - [x] 接待人员管理 - [ ] 会话分配与消息收发 - [x] 身份验证 - [x] 应用管理 - [x] 消息推送 - [x] 素材管理 - [x] 上传临时素材 - [x] 上传图片 - [x] OA - [x] 文档 - [x] 日程 - [x] 微盘 - [x] 审批 - [x] 效率工具 - 企业支付 - 企业互联 - 会话内容存档 - 电子发票 - 家校沟通 - 家校应用 - 政民沟通