@@ -67,7 +67,7 @@ public interface WxCpMenuService {
* @throws WxErrorException the wx error exception
* @see #delete() #delete()
*/
- void delete(Integer agentId) throws WxErrorException;
+ void delete(Long agentId) throws WxErrorException;
/**
*
@@ -96,5 +96,5 @@ public interface WxCpMenuService {
* @throws WxErrorException the wx error exception
* @see #get() #get()
*/
- WxMenu get(Integer agentId) throws WxErrorException;
+ WxMenu get(Long agentId) throws WxErrorException;
}
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpOAuth2Service.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpOAuth2Service.java
index 1824196720..695534ba73 100644
--- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpOAuth2Service.java
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpOAuth2Service.java
@@ -85,7 +85,7 @@ public interface WxCpOAuth2Service {
* @throws WxErrorException 异常
* @see #getUserInfo(String) #getUserInfo(String)
*/
- WxCpOauth2UserInfo getUserInfo(Integer agentId, String code) throws WxErrorException;
+ WxCpOauth2UserInfo getUserInfo(Long agentId, String code) throws WxErrorException;
/**
* 获取家校访问用户身份
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpService.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpService.java
index 269a69a475..9a715c1e91 100644
--- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpService.java
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpService.java
@@ -673,4 +673,11 @@ public interface WxCpService extends WxService {
* @return 人事助手服务 hr service
*/
WxCpHrService getHrService();
+
+ /**
+ * 获取待办服务
+ *
+ * @return 待办服务 todo service
+ */
+ WxCpTodoService getTodoService();
}
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpTodoService.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpTodoService.java
new file mode 100644
index 0000000000..82f17c2303
--- /dev/null
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpTodoService.java
@@ -0,0 +1,47 @@
+package me.chanjar.weixin.cp.api;
+
+import me.chanjar.weixin.common.error.WxErrorException;
+import me.chanjar.weixin.cp.bean.todo.WxCpTodo;
+
+import java.util.List;
+
+/**
+ * 企业微信待办接口.
+ *
+ * 官方文档:
+ * 获取待办详情,
+ * 更新待办状态
+ *
+ * @author Binary Wang created on 2026-08-11
+ */
+public interface WxCpTodoService {
+ /**
+ * 获取待办详情.
+ *
+ * 该接口用于获取指定的待办详情,请求参数仅包含必填的 todo_id,响应直接返回单个待办对象。
+ *
+ * 请求方式: POST(HTTPS)
+ * 请求地址: https://qyapi.weixin.qq.com/cgi-bin/todo/get?access_token=ACCESS_TOKEN
+ *
+ * @param todoId 待办ID
+ * @return 待办详情 wx cp todo
+ * @throws WxErrorException the wx error exception
+ */
+ WxCpTodo get(String todoId) throws WxErrorException;
+
+ /**
+ * 更新待办状态.
+ *
+ * 该接口用于修改指定的待办信息,支持修改待办整体状态(status 字段)、待办参与人及其状态(attendees[].userid / status 字段)。
+ * 仅允许修改当前应用创建的待办,不允许修改已删除的待办。
+ *
+ * 请求方式: POST(HTTPS)
+ * 请求地址: https://qyapi.weixin.qq.com/cgi-bin/todo/update?access_token=ACCESS_TOKEN
+ *
+ * @param todoId 待办ID
+ * @param status 待办整体状态,可不传:0 - 完成;1 - 进行中。为 null 时不修改整体状态
+ * @param attendees 待办参与人列表,最多支持20个参与人。为 null 或空时不修改参与人列表
+ * @throws WxErrorException the wx error exception
+ */
+ void update(String todoId, Integer status, List attendees) throws WxErrorException;
+}
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/BaseWxCpServiceImpl.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/BaseWxCpServiceImpl.java
index a3ec703ca4..eb8abd773f 100644
--- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/BaseWxCpServiceImpl.java
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/BaseWxCpServiceImpl.java
@@ -77,6 +77,7 @@ public abstract class BaseWxCpServiceImpl implements WxCpService, RequestH
private final WxCpCorpGroupService corpGroupService = new WxCpCorpGroupServiceImpl(this);
private final WxCpIntelligentRobotService intelligentRobotService = new WxCpIntelligentRobotServiceImpl(this);
private final WxCpHrService hrService = new WxCpHrServiceImpl(this);
+ private final WxCpTodoService todoService = new WxCpTodoServiceImpl(this);
/**
* 全局的是否正在刷新access token的锁.
@@ -429,23 +430,29 @@ protected T executeInternal(RequestExecutor executor, String uri, E
* 普通请求,不自动带accessToken
*/
private T executeNormal(RequestExecutor executor, String uri, E data) throws WxErrorException {
+ String uriForLog = redactQueryString(uri);
try {
T result = executor.execute(uri, data, WxType.CP);
- log.debug("\n【请求地址】: {}\n【请求参数】:{}\n【响应数据】:{}", uri, data, result);
+ log.debug("\n【请求地址】: {}\n【请求参数】:{}\n【响应数据】:{}", uriForLog, data, result);
return result;
} catch (WxErrorException e) {
WxError error = e.getError();
if (error.getErrorCode() != 0) {
- log.error("\n【请求地址】: {}\n【请求参数】:{}\n【错误信息】:{}", uri, data, error);
+ log.error("\n【请求地址】: {}\n【请求参数】:{}\n【错误信息】:{}", uriForLog, data, error);
throw new WxErrorException(error, e);
}
return null;
} catch (IOException e) {
- log.error("\n【请求地址】: {}\n【请求参数】:{}\n【异常信息】:{}", uri, data, e.getMessage());
+ log.error("\n【请求地址】: {}\n【请求参数】:{}\n【异常信息】:{}", uriForLog, data, e.getMessage());
throw new WxErrorException(e);
}
}
+ static String redactQueryString(String uri) {
+ int queryStart = uri.indexOf('?');
+ return queryStart < 0 ? uri : uri.substring(0, queryStart) + "?******";
+ }
+
@Override
public void setWxCpConfigStorage(WxCpConfigStorage wxConfigProvider) {
this.configStorage = wxConfigProvider;
@@ -753,4 +760,9 @@ public WxCpIntelligentRobotService getIntelligentRobotService() {
public WxCpHrService getHrService() {
return this.hrService;
}
+
+ @Override
+ public WxCpTodoService getTodoService() {
+ return this.todoService;
+ }
}
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpAgentServiceImpl.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpAgentServiceImpl.java
index cc08d33bb1..6f2ade2e49 100644
--- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpAgentServiceImpl.java
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpAgentServiceImpl.java
@@ -34,7 +34,7 @@ public class WxCpAgentServiceImpl implements WxCpAgentService {
private final WxCpService mainService;
@Override
- public WxCpAgent get(Integer agentId) throws WxErrorException {
+ public WxCpAgent get(Long agentId) throws WxErrorException {
if (agentId == null) {
throw new IllegalArgumentException("缺少agentid参数");
}
@@ -67,7 +67,7 @@ public List list() throws WxErrorException {
}
@Override
- public WxCpTpAdmin getAdminList(Integer agentId) throws WxErrorException {
+ public WxCpTpAdmin getAdminList(Long agentId) throws WxErrorException {
if (agentId == null) {
throw new IllegalArgumentException("缺少agentid参数");
}
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpCorpGroupServiceImpl.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpCorpGroupServiceImpl.java
index e3dc1cbe1c..73d11cc15d 100644
--- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpCorpGroupServiceImpl.java
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpCorpGroupServiceImpl.java
@@ -25,7 +25,7 @@ public class WxCpCorpGroupServiceImpl implements WxCpCorpGroupService {
private final WxCpService cpService;
@Override
- public List listAppShareInfo(Integer agentId, Integer businessType, String corpId,
+ public List listAppShareInfo(Long agentId, Integer businessType, String corpId,
Integer limit, String cursor) throws WxErrorException {
final String url = this.cpService.getWxCpConfigStorage().getApiUrl(LIST_SHARE_APP_INFO);
JsonObject jsonObject = new JsonObject();
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpIntelligentRobotServiceImpl.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpIntelligentRobotServiceImpl.java
index aba1ee85c4..a5ccdca5e1 100644
--- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpIntelligentRobotServiceImpl.java
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpIntelligentRobotServiceImpl.java
@@ -6,6 +6,7 @@
import me.chanjar.weixin.cp.api.WxCpIntelligentRobotService;
import me.chanjar.weixin.cp.api.WxCpService;
import me.chanjar.weixin.cp.bean.intelligentrobot.*;
+import me.chanjar.weixin.cp.util.crypto.WxCpIntelligentRobotCryptUtil;
import me.chanjar.weixin.cp.util.json.WxCpGsonBuilder;
import static me.chanjar.weixin.cp.constant.WxCpApiPathConsts.IntelligentRobot.*;
@@ -72,4 +73,19 @@ public WxCpIntelligentRobotMessage parseCallbackMessage(String callbackMessageJs
return WxCpIntelligentRobotMessage.fromJson(callbackMessageJson);
}
+ @Override
+ public WxCpIntelligentRobotMessage parseEncryptedCallbackMessage(String msgSignature, String timestamp, String nonce,
+ String encryptedJson, String token,
+ String encodingAesKey, String aiBotId) {
+ WxCpIntelligentRobotCryptUtil cryptUtil = new WxCpIntelligentRobotCryptUtil(token, encodingAesKey, aiBotId);
+ return parseCallbackMessage(cryptUtil.decrypt(msgSignature, timestamp, nonce, encryptedJson));
+ }
+
+ @Override
+ public String replyMessage(String responseUrl, String plainJson, String token, String encodingAesKey,
+ String aiBotId, String timestamp, String nonce) throws WxErrorException {
+ WxCpIntelligentRobotCryptUtil cryptUtil = new WxCpIntelligentRobotCryptUtil(token, encodingAesKey, aiBotId);
+ return this.cpService.postWithoutToken(responseUrl, cryptUtil.encrypt(plainJson, timestamp, nonce));
+ }
+
}
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpKfServiceImpl.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpKfServiceImpl.java
index be4f2a5850..be6c61ea92 100644
--- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpKfServiceImpl.java
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpKfServiceImpl.java
@@ -317,4 +317,81 @@ public WxCpKfGetServicerStatisticResp getServicerStatistic(WxCpKfGetServicerStat
return WxCpKfGetServicerStatisticResp.fromJson(responseContent);
}
+ @Override
+ public WxCpKfKnowledgeGroupAddResp addKnowledgeGroup(WxCpKfKnowledgeGroup group) throws WxErrorException {
+ String url = cpService.getWxCpConfigStorage().getApiUrl(KNOWLEDGE_ADD_GROUP);
+ String responseContent = cpService.post(url, GSON.toJson(group));
+ return WxCpKfKnowledgeGroupAddResp.fromJson(responseContent);
+ }
+
+ @Override
+ public WxCpBaseResp delKnowledgeGroup(String groupId) throws WxErrorException {
+ return knowledgeBaseResp(KNOWLEDGE_DEL_GROUP, "group_id", groupId);
+ }
+
+ @Override
+ public WxCpBaseResp modKnowledgeGroup(WxCpKfKnowledgeGroup group) throws WxErrorException {
+ String url = cpService.getWxCpConfigStorage().getApiUrl(KNOWLEDGE_MOD_GROUP);
+ String responseContent = cpService.post(url, GSON.toJson(group));
+ return WxCpBaseResp.fromJson(responseContent);
+ }
+
+ @Override
+ public WxCpKfKnowledgeGroupListResp listKnowledgeGroup(String cursor, Integer limit, String groupId) throws WxErrorException {
+ String url = cpService.getWxCpConfigStorage().getApiUrl(KNOWLEDGE_LIST_GROUP);
+ String responseContent = cpService.post(url, GSON.toJson(listKnowledgeJson(cursor, limit, groupId, null)));
+ return WxCpKfKnowledgeGroupListResp.fromJson(responseContent);
+ }
+
+ @Override
+ public WxCpKfKnowledgeIntentAddResp addKnowledgeIntent(WxCpKfKnowledgeIntent intent) throws WxErrorException {
+ String url = cpService.getWxCpConfigStorage().getApiUrl(KNOWLEDGE_ADD_INTENT);
+ String responseContent = cpService.post(url, GSON.toJson(intent));
+ return WxCpKfKnowledgeIntentAddResp.fromJson(responseContent);
+ }
+
+ @Override
+ public WxCpBaseResp delKnowledgeIntent(String intentId) throws WxErrorException {
+ return knowledgeBaseResp(KNOWLEDGE_DEL_INTENT, "intent_id", intentId);
+ }
+
+ @Override
+ public WxCpBaseResp modKnowledgeIntent(WxCpKfKnowledgeIntent intent) throws WxErrorException {
+ String url = cpService.getWxCpConfigStorage().getApiUrl(KNOWLEDGE_MOD_INTENT);
+ String responseContent = cpService.post(url, GSON.toJson(intent));
+ return WxCpBaseResp.fromJson(responseContent);
+ }
+
+ @Override
+ public WxCpKfKnowledgeIntentListResp listKnowledgeIntent(String cursor, Integer limit, String groupId, String intentId) throws WxErrorException {
+ String url = cpService.getWxCpConfigStorage().getApiUrl(KNOWLEDGE_LIST_INTENT);
+ String responseContent = cpService.post(url, GSON.toJson(listKnowledgeJson(cursor, limit, groupId, intentId)));
+ return WxCpKfKnowledgeIntentListResp.fromJson(responseContent);
+ }
+
+ private WxCpBaseResp knowledgeBaseResp(String apiPath, String key, String value) throws WxErrorException {
+ String url = cpService.getWxCpConfigStorage().getApiUrl(apiPath);
+ JsonObject json = new JsonObject();
+ json.addProperty(key, value);
+ String responseContent = cpService.post(url, GSON.toJson(json));
+ return WxCpBaseResp.fromJson(responseContent);
+ }
+
+ private JsonObject listKnowledgeJson(String cursor, Integer limit, String groupId, String intentId) {
+ JsonObject json = new JsonObject();
+ if (cursor != null) {
+ json.addProperty("cursor", cursor);
+ }
+ if (limit != null) {
+ json.addProperty("limit", limit);
+ }
+ if (groupId != null) {
+ json.addProperty("group_id", groupId);
+ }
+ if (intentId != null) {
+ json.addProperty("intent_id", intentId);
+ }
+ return json;
+ }
+
}
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpMenuServiceImpl.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpMenuServiceImpl.java
index d008e77083..0920c2b3e0 100644
--- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpMenuServiceImpl.java
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpMenuServiceImpl.java
@@ -27,7 +27,7 @@ public void create(WxMenu menu) throws WxErrorException {
}
@Override
- public void create(Integer agentId, WxMenu menu) throws WxErrorException {
+ public void create(Long agentId, WxMenu menu) throws WxErrorException {
String url = String.format(this.mainService.getWxCpConfigStorage().getApiUrl(MENU_CREATE), agentId);
this.mainService.post(url, menu.toJson());
}
@@ -38,7 +38,7 @@ public void delete() throws WxErrorException {
}
@Override
- public void delete(Integer agentId) throws WxErrorException {
+ public void delete(Long agentId) throws WxErrorException {
String url = String.format(this.mainService.getWxCpConfigStorage().getApiUrl(MENU_DELETE), agentId);
this.mainService.get(url, null);
}
@@ -49,7 +49,7 @@ public WxMenu get() throws WxErrorException {
}
@Override
- public WxMenu get(Integer agentId) throws WxErrorException {
+ public WxMenu get(Long agentId) throws WxErrorException {
String url = String.format(this.mainService.getWxCpConfigStorage().getApiUrl(MENU_GET), agentId);
try {
String resultContent = this.mainService.get(url, null);
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpMessageServiceImpl.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpMessageServiceImpl.java
index 6daea8ef2f..def73e4152 100644
--- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpMessageServiceImpl.java
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpMessageServiceImpl.java
@@ -21,7 +21,7 @@ public class WxCpMessageServiceImpl implements WxCpMessageService {
@Override
public WxCpMessageSendResult send(WxCpMessage message) throws WxErrorException {
- Integer agentId = message.getAgentId();
+ Long agentId = message.getAgentId();
if (null == agentId) {
message.setAgentId(this.cpService.getWxCpConfigStorage().getAgentId());
}
@@ -38,7 +38,7 @@ public WxCpMessageSendStatistics getStatistics(int timeType) throws WxErrorExcep
@Override
public WxCpLinkedCorpMessageSendResult sendLinkedCorpMessage(WxCpLinkedCorpMessage message) throws WxErrorException {
- Integer agentId = message.getAgentId();
+ Long agentId = message.getAgentId();
if (null == agentId) {
message.setAgentId(this.cpService.getWxCpConfigStorage().getAgentId());
}
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpOAuth2ServiceImpl.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpOAuth2ServiceImpl.java
index d04a051c0e..9b390b5ec8 100644
--- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpOAuth2ServiceImpl.java
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpOAuth2ServiceImpl.java
@@ -69,7 +69,7 @@ public WxCpOauth2UserInfo getUserInfo(String code) throws WxErrorException {
}
@Override
- public WxCpOauth2UserInfo getUserInfo(Integer agentId, String code) throws WxErrorException {
+ public WxCpOauth2UserInfo getUserInfo(Long agentId, String code) throws WxErrorException {
String responseText =
this.mainService.get(String.format(this.mainService.getWxCpConfigStorage().getApiUrl(GET_USER_INFO), code,
agentId), null);
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpTaskCardServiceImpl.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpTaskCardServiceImpl.java
index 8469451428..0cf0ab6665 100644
--- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpTaskCardServiceImpl.java
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpTaskCardServiceImpl.java
@@ -28,7 +28,7 @@ public class WxCpTaskCardServiceImpl implements WxCpTaskCardService {
@Override
public void update(List userIds, String taskId, String replaceName) throws WxErrorException {
- Integer agentId = this.mainService.getWxCpConfigStorage().getAgentId();
+ Long agentId = this.mainService.getWxCpConfigStorage().getAgentId();
Map data = new HashMap<>(4);
data.put("userids", userIds);
@@ -45,7 +45,7 @@ public void update(List userIds, String taskId, String replaceName) thro
public void updateTemplateCardButton(List userIds, List partyIds,
List tagIds, Integer atAll,
String responseCode, String replaceName) throws WxErrorException {
- Integer agentId = this.mainService.getWxCpConfigStorage().getAgentId();
+ Long agentId = this.mainService.getWxCpConfigStorage().getAgentId();
Map data = new HashMap<>(7);
data.put("userids", userIds);
data.put("partyids", partyIds);
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpTodoServiceImpl.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpTodoServiceImpl.java
new file mode 100644
index 0000000000..627784b36c
--- /dev/null
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpTodoServiceImpl.java
@@ -0,0 +1,50 @@
+package me.chanjar.weixin.cp.api.impl;
+
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import me.chanjar.weixin.common.error.WxErrorException;
+import me.chanjar.weixin.cp.api.WxCpService;
+import me.chanjar.weixin.cp.api.WxCpTodoService;
+import me.chanjar.weixin.cp.bean.todo.WxCpTodo;
+import me.chanjar.weixin.cp.util.json.WxCpGsonBuilder;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import static me.chanjar.weixin.cp.constant.WxCpApiPathConsts.Todo.*;
+
+/**
+ * 企业微信待办接口实现类.
+ *
+ * @author Binary Wang created on 2026-08-11
+ */
+@Slf4j
+@RequiredArgsConstructor
+public class WxCpTodoServiceImpl implements WxCpTodoService {
+ private final WxCpService cpService;
+
+ @Override
+ public WxCpTodo get(String todoId) throws WxErrorException {
+ final Map param = new HashMap<>(1);
+ param.put("todo_id", todoId);
+ final String response = this.cpService.post(this.cpService.getWxCpConfigStorage().getApiUrl(TODO_GET),
+ WxCpGsonBuilder.create().toJson(param));
+ return WxCpGsonBuilder.create().fromJson(response, WxCpTodo.class);
+ }
+
+ @Override
+ public void update(String todoId, Integer status, List attendees) throws WxErrorException {
+ final Map param = new HashMap<>(3);
+ param.put("todo_id", todoId);
+ if (status != null) {
+ param.put("status", status);
+ }
+ if (attendees != null && !attendees.isEmpty()) {
+ param.put("attendees", attendees);
+ }
+
+ this.cpService.post(this.cpService.getWxCpConfigStorage().getApiUrl(TODO_UPDATE),
+ WxCpGsonBuilder.create().toJson(param));
+ }
+}
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpAgent.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpAgent.java
index 5d61b3a199..8f96a729a0 100644
--- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpAgent.java
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpAgent.java
@@ -32,7 +32,7 @@ public class WxCpAgent implements Serializable {
private String errMsg;
@SerializedName("agentid")
- private Integer agentId;
+ private Long agentId;
@SerializedName("name")
private String name;
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpAgentJsapiSignature.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpAgentJsapiSignature.java
index 4562d9b9b0..8ca7a6cb95 100644
--- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpAgentJsapiSignature.java
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpAgentJsapiSignature.java
@@ -21,7 +21,7 @@ public class WxCpAgentJsapiSignature implements Serializable {
private String corpid;
- private Integer agentid;
+ private Long agentid;
private long timestamp;
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/corpgroup/WxCpCorpGroupCorpGetTokenReq.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/corpgroup/WxCpCorpGroupCorpGetTokenReq.java
index 6370fc7c11..7fa00a3ada 100644
--- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/corpgroup/WxCpCorpGroupCorpGetTokenReq.java
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/corpgroup/WxCpCorpGroupCorpGetTokenReq.java
@@ -17,5 +17,5 @@ public class WxCpCorpGroupCorpGetTokenReq implements Serializable {
@SerializedName("business_type")
private int businessType;
@SerializedName("agentid")
- private int agentId;
+ private long agentId;
}
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/kf/WxCpKfKnowledgeGroup.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/kf/WxCpKfKnowledgeGroup.java
new file mode 100644
index 0000000000..5cc6c3e79c
--- /dev/null
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/kf/WxCpKfKnowledgeGroup.java
@@ -0,0 +1,22 @@
+package me.chanjar.weixin.cp.bean.kf;
+
+import com.google.gson.annotations.SerializedName;
+import lombok.Data;
+
+import java.io.Serializable;
+
+/**
+ * 微信客服知识库分组。
+ */
+@Data
+public class WxCpKfKnowledgeGroup implements Serializable {
+ private static final long serialVersionUID = -170690715179803477L;
+
+ @SerializedName("group_id")
+ private String groupId;
+
+ private String name;
+
+ @SerializedName("is_default")
+ private Integer isDefault;
+}
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/kf/WxCpKfKnowledgeGroupAddResp.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/kf/WxCpKfKnowledgeGroupAddResp.java
new file mode 100644
index 0000000000..52bd89bdb1
--- /dev/null
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/kf/WxCpKfKnowledgeGroupAddResp.java
@@ -0,0 +1,23 @@
+package me.chanjar.weixin.cp.bean.kf;
+
+import com.google.gson.annotations.SerializedName;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import me.chanjar.weixin.cp.bean.WxCpBaseResp;
+import me.chanjar.weixin.cp.util.json.WxCpGsonBuilder;
+
+/**
+ * 微信客服知识库分组新增返回结果。
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+public class WxCpKfKnowledgeGroupAddResp extends WxCpBaseResp {
+ private static final long serialVersionUID = 232872665454024387L;
+
+ @SerializedName("group_id")
+ private String groupId;
+
+ public static WxCpKfKnowledgeGroupAddResp fromJson(String json) {
+ return WxCpGsonBuilder.create().fromJson(json, WxCpKfKnowledgeGroupAddResp.class);
+ }
+}
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/kf/WxCpKfKnowledgeGroupListResp.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/kf/WxCpKfKnowledgeGroupListResp.java
new file mode 100644
index 0000000000..bed6bfae82
--- /dev/null
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/kf/WxCpKfKnowledgeGroupListResp.java
@@ -0,0 +1,31 @@
+package me.chanjar.weixin.cp.bean.kf;
+
+import com.google.gson.annotations.SerializedName;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import me.chanjar.weixin.cp.bean.WxCpBaseResp;
+import me.chanjar.weixin.cp.util.json.WxCpGsonBuilder;
+
+import java.util.List;
+
+/**
+ * 微信客服知识库分组列表返回结果。
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+public class WxCpKfKnowledgeGroupListResp extends WxCpBaseResp {
+ private static final long serialVersionUID = -8350717377843545855L;
+
+ @SerializedName("next_cursor")
+ private String nextCursor;
+
+ @SerializedName("has_more")
+ private Integer hasMore;
+
+ @SerializedName("group_list")
+ private List groupList;
+
+ public static WxCpKfKnowledgeGroupListResp fromJson(String json) {
+ return WxCpGsonBuilder.create().fromJson(json, WxCpKfKnowledgeGroupListResp.class);
+ }
+}
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/kf/WxCpKfKnowledgeIntent.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/kf/WxCpKfKnowledgeIntent.java
new file mode 100644
index 0000000000..bbe569effd
--- /dev/null
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/kf/WxCpKfKnowledgeIntent.java
@@ -0,0 +1,109 @@
+package me.chanjar.weixin.cp.bean.kf;
+
+import com.google.gson.annotations.SerializedName;
+import lombok.Data;
+import me.chanjar.weixin.cp.util.json.WxCpGsonBuilder;
+
+import java.io.Serializable;
+import java.util.List;
+
+/**
+ * 微信客服知识库问答。
+ */
+@Data
+public class WxCpKfKnowledgeIntent implements Serializable {
+ private static final long serialVersionUID = -3777712166335763935L;
+
+ @SerializedName("group_id")
+ private String groupId;
+
+ @SerializedName("intent_id")
+ private String intentId;
+
+ private Question question;
+
+ @SerializedName("similar_questions")
+ private SimilarQuestions similarQuestions;
+
+ private List answers;
+
+ public static WxCpKfKnowledgeIntent fromJson(String json) {
+ return WxCpGsonBuilder.create().fromJson(json, WxCpKfKnowledgeIntent.class);
+ }
+
+ @Data
+ public static class Question implements Serializable {
+ private static final long serialVersionUID = -1833564733770700525L;
+ private Text text;
+ @SerializedName("similar_questions")
+ private SimilarQuestions similarQuestions;
+ private List answers;
+ }
+
+ @Data
+ public static class Text implements Serializable {
+ private static final long serialVersionUID = -4775152873471313775L;
+ private String content;
+ }
+
+ @Data
+ public static class SimilarQuestions implements Serializable {
+ private static final long serialVersionUID = -3338135520171174537L;
+ private List items;
+ }
+
+ @Data
+ public static class Answer implements Serializable {
+ private static final long serialVersionUID = 482114683168970317L;
+ private Text text;
+ private List attachments;
+ }
+
+ @Data
+ public static class Attachment implements Serializable {
+ private static final long serialVersionUID = 547601649734690079L;
+ @SerializedName("msgtype")
+ private String msgType;
+ private Image image;
+ private Video video;
+ private Link link;
+ @SerializedName("miniprogram")
+ private MiniProgram miniProgram;
+ }
+
+ @Data
+ public static class Image implements Serializable {
+ private static final long serialVersionUID = -6305485241850490695L;
+ @SerializedName("media_id")
+ private String mediaId;
+ private String name;
+ }
+
+ @Data
+ public static class Video implements Serializable {
+ private static final long serialVersionUID = 4002145709503795505L;
+ @SerializedName("media_id")
+ private String mediaId;
+ private String name;
+ }
+
+ @Data
+ public static class Link implements Serializable {
+ private static final long serialVersionUID = -1844812819777892606L;
+ private String title;
+ @SerializedName("pic_url")
+ private String picUrl;
+ private String desc;
+ private String url;
+ }
+
+ @Data
+ public static class MiniProgram implements Serializable {
+ private static final long serialVersionUID = 6893025025270416975L;
+ private String title;
+ @SerializedName("thumb_media_id")
+ private String thumbMediaId;
+ private String appid;
+ private String pagepath;
+ }
+}
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/kf/WxCpKfKnowledgeIntentAddResp.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/kf/WxCpKfKnowledgeIntentAddResp.java
new file mode 100644
index 0000000000..44f162e78f
--- /dev/null
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/kf/WxCpKfKnowledgeIntentAddResp.java
@@ -0,0 +1,23 @@
+package me.chanjar.weixin.cp.bean.kf;
+
+import com.google.gson.annotations.SerializedName;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import me.chanjar.weixin.cp.bean.WxCpBaseResp;
+import me.chanjar.weixin.cp.util.json.WxCpGsonBuilder;
+
+/**
+ * 微信客服知识库问答新增返回结果。
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+public class WxCpKfKnowledgeIntentAddResp extends WxCpBaseResp {
+ private static final long serialVersionUID = -2693926545826175543L;
+
+ @SerializedName("intent_id")
+ private String intentId;
+
+ public static WxCpKfKnowledgeIntentAddResp fromJson(String json) {
+ return WxCpGsonBuilder.create().fromJson(json, WxCpKfKnowledgeIntentAddResp.class);
+ }
+}
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/kf/WxCpKfKnowledgeIntentListResp.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/kf/WxCpKfKnowledgeIntentListResp.java
new file mode 100644
index 0000000000..a188a03c0d
--- /dev/null
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/kf/WxCpKfKnowledgeIntentListResp.java
@@ -0,0 +1,31 @@
+package me.chanjar.weixin.cp.bean.kf;
+
+import com.google.gson.annotations.SerializedName;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import me.chanjar.weixin.cp.bean.WxCpBaseResp;
+import me.chanjar.weixin.cp.util.json.WxCpGsonBuilder;
+
+import java.util.List;
+
+/**
+ * 微信客服知识库问答列表返回结果。
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+public class WxCpKfKnowledgeIntentListResp extends WxCpBaseResp {
+ private static final long serialVersionUID = -724770244623284115L;
+
+ @SerializedName("next_cursor")
+ private String nextCursor;
+
+ @SerializedName("has_more")
+ private Integer hasMore;
+
+ @SerializedName("intent_list")
+ private List intentList;
+
+ public static WxCpKfKnowledgeIntentListResp fromJson(String json) {
+ return WxCpGsonBuilder.create().fromJson(json, WxCpKfKnowledgeIntentListResp.class);
+ }
+}
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/message/WxCpLinkedCorpMessage.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/message/WxCpLinkedCorpMessage.java
index 7e777384eb..46784158f3 100644
--- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/message/WxCpLinkedCorpMessage.java
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/message/WxCpLinkedCorpMessage.java
@@ -55,7 +55,15 @@ public class WxCpLinkedCorpMessage implements Serializable {
/**
* 企业应用的id,整型。可在应用的设置页面查看
*/
- private Integer agentId;
+ private Long agentId;
+
+ public void setAgentId(long agentId) {
+ this.agentId = Long.valueOf(agentId);
+ }
+
+ public void setAgentId(Long agentId) {
+ this.agentId = agentId;
+ }
private String msgType;
/**
* 消息内容,最长不超过2048个字节
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/message/WxCpMessage.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/message/WxCpMessage.java
index ca3fbceccb..c25b5208f1 100644
--- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/message/WxCpMessage.java
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/message/WxCpMessage.java
@@ -45,7 +45,15 @@ public class WxCpMessage implements Serializable {
/**
* 企业应用的id,整型。企业内部开发,可在应用的设置页面查看;第三方服务商,可通过接口 获取企业授权信息 获取该参数值
*/
- private Integer agentId;
+ private Long agentId;
+
+ public void setAgentId(long agentId) {
+ this.agentId = Long.valueOf(agentId);
+ }
+
+ public void setAgentId(Long agentId) {
+ this.agentId = agentId;
+ }
/**
* 消息类型
* 文本消息: text
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/message/WxCpSchoolContactMessage.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/message/WxCpSchoolContactMessage.java
index a13205cd6b..04ec5b135b 100644
--- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/message/WxCpSchoolContactMessage.java
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/message/WxCpSchoolContactMessage.java
@@ -74,7 +74,15 @@ public class WxCpSchoolContactMessage implements Serializable {
* 企业应用的id,整型。可在应用的设置页面查看
*/
@SerializedName("agentid")
- private Integer agentId;
+ private Long agentId;
+
+ public void setAgentId(long agentId) {
+ this.agentId = Long.valueOf(agentId);
+ }
+
+ public void setAgentId(Long agentId) {
+ this.agentId = agentId;
+ }
/**
* 消息内容,最长不超过2048个字节(支持id转译)
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/messagebuilder/BaseBuilder.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/messagebuilder/BaseBuilder.java
index e7c2267018..fa0c747c16 100644
--- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/messagebuilder/BaseBuilder.java
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/messagebuilder/BaseBuilder.java
@@ -15,7 +15,7 @@ public abstract class BaseBuilder {
/**
* The Agent id.
*/
- protected Integer agentId;
+ protected Long agentId;
/**
* The To user.
*/
@@ -39,11 +39,15 @@ public abstract class BaseBuilder {
* @param agentId the agent id
* @return the t
*/
- public T agentId(Integer agentId) {
+ public T agentId(Long agentId) {
this.agentId = agentId;
return (T) this;
}
+ public T agentId(long agentId) {
+ return this.agentId(Long.valueOf(agentId));
+ }
+
/**
* To user t.
*
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/todo/WxCpTodo.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/todo/WxCpTodo.java
new file mode 100644
index 0000000000..a33eb1f4c3
--- /dev/null
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/todo/WxCpTodo.java
@@ -0,0 +1,110 @@
+package me.chanjar.weixin.cp.bean.todo;
+
+import com.google.gson.annotations.SerializedName;
+import lombok.Data;
+import lombok.experimental.Accessors;
+import me.chanjar.weixin.common.bean.ToJson;
+import me.chanjar.weixin.cp.util.json.WxCpGsonBuilder;
+
+import java.io.Serializable;
+import java.util.List;
+
+/**
+ * 待办信息bean.
+ *
+ * 官方文档:
+ * 获取待办详情
+ *
+ * @author Binary Wang created on 2026-08-11
+ */
+@Data
+@Accessors(chain = true)
+public class WxCpTodo implements Serializable, ToJson {
+ private static final long serialVersionUID = -1L;
+
+ /**
+ * 待办ID
+ */
+ @SerializedName("todo_id")
+ private String todoId;
+ /**
+ * 待办内容
+ */
+ @SerializedName("content")
+ private String content;
+ /**
+ * 待办创建人ID
+ */
+ @SerializedName("creator")
+ private String creator;
+ /**
+ * 待办状态。
+ * 0 - 已完成
+ * 1 - 进行中
+ * 2 - 已删除
+ */
+ @SerializedName("status")
+ private Integer status;
+ /**
+ * 待办创建时间戳(整型秒数)
+ */
+ @SerializedName("create_time")
+ private Long createTime;
+ /**
+ * 待办参与人列表
+ */
+ @SerializedName("attendees")
+ private List attendees;
+ /**
+ * 待办截止时间戳(整型秒数)
+ */
+ @SerializedName("end_time")
+ private Long endTime;
+ /**
+ * 提醒列表
+ */
+ @SerializedName("reminders")
+ private List reminders;
+
+ @Override
+ public String toJson() {
+ return WxCpGsonBuilder.create().toJson(this);
+ }
+
+ /**
+ * 待办参与人.
+ */
+ @Data
+ @Accessors(chain = true)
+ public static class Attendee implements Serializable {
+ private static final long serialVersionUID = -1L;
+
+ /**
+ * 待办参与人ID
+ */
+ @SerializedName("userid")
+ private String userid;
+ /**
+ * 参与人的待办状态。
+ * 0 - 完成
+ * 1 - 进行中
+ */
+ @SerializedName("status")
+ private Integer status;
+ }
+
+ /**
+ * 待办提醒.
+ */
+ @Data
+ @Accessors(chain = true)
+ public static class Reminder implements Serializable {
+ private static final long serialVersionUID = -1L;
+
+ /**
+ * 提醒时间戳(整型秒数)
+ */
+ @SerializedName("remind_time")
+ private Long remindTime;
+ }
+}
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/config/WxCpConfigStorage.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/config/WxCpConfigStorage.java
index 7f66f05094..0efe7dd606 100644
--- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/config/WxCpConfigStorage.java
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/config/WxCpConfigStorage.java
@@ -158,7 +158,7 @@ public interface WxCpConfigStorage {
*
* @return the agent id
*/
- Integer getAgentId();
+ Long getAgentId();
/**
* Gets token.
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/config/WxCpCorpGroupConfigStorage.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/config/WxCpCorpGroupConfigStorage.java
index df758ac3a2..61b3b4043b 100644
--- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/config/WxCpCorpGroupConfigStorage.java
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/config/WxCpCorpGroupConfigStorage.java
@@ -36,7 +36,7 @@ public interface WxCpCorpGroupConfigStorage {
* @param corpAccessToken the corp access token
* @param expiresInSeconds the expires in seconds
*/
- void updateCorpAccessToken(String corpId, Integer agentId, String corpAccessToken, int expiresInSeconds);
+ void updateCorpAccessToken(String corpId, Long agentId, String corpAccessToken, int expiresInSeconds);
/**
* 授权企业的access token相关
@@ -45,7 +45,7 @@ public interface WxCpCorpGroupConfigStorage {
* @param agentId 应用ID
* @return the access token
*/
- String getCorpAccessToken(String corpId, Integer agentId);
+ String getCorpAccessToken(String corpId, Long agentId);
/**
* Gets access token entity.
@@ -54,7 +54,7 @@ public interface WxCpCorpGroupConfigStorage {
* @param agentId 应用ID
* @return the access token entity
*/
- WxAccessToken getCorpAccessTokenEntity(String corpId, Integer agentId);
+ WxAccessToken getCorpAccessTokenEntity(String corpId, Long agentId);
/**
* Is access token expired boolean.
@@ -63,7 +63,7 @@ public interface WxCpCorpGroupConfigStorage {
* @param agentId 应用ID
* @return the boolean
*/
- boolean isCorpAccessTokenExpired(String corpId, Integer agentId);
+ boolean isCorpAccessTokenExpired(String corpId, Long agentId);
/**
* Expire access token.
@@ -71,7 +71,7 @@ public interface WxCpCorpGroupConfigStorage {
* @param corpId 企业ID
* @param agentId 应用ID
*/
- void expireCorpAccessToken(String corpId, Integer agentId);
+ void expireCorpAccessToken(String corpId, Long agentId);
/**
* 网络代理相关
@@ -122,11 +122,11 @@ public interface WxCpCorpGroupConfigStorage {
* @param agentId 应用ID
* @return the access token lock
*/
- Lock getCorpAccessTokenLock(String corpId, Integer agentId);
+ Lock getCorpAccessTokenLock(String corpId, Long agentId);
void setCorpId(String corpId);
- void setAgentId(Integer agentId);
+ void setAgentId(Long agentId);
/**
* Gets corp id.
@@ -140,5 +140,5 @@ public interface WxCpCorpGroupConfigStorage {
*
* @return the agent id
*/
- Integer getAgentId();
+ Long getAgentId();
}
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/config/impl/AbstractWxCpInRedisConfigImpl.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/config/impl/AbstractWxCpInRedisConfigImpl.java
index 448d2b62dd..dd9879a42a 100644
--- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/config/impl/AbstractWxCpInRedisConfigImpl.java
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/config/impl/AbstractWxCpInRedisConfigImpl.java
@@ -74,7 +74,7 @@ public AbstractWxCpInRedisConfigImpl(@NonNull WxRedisOps redisOps, String keyPre
* @param agentId 应用 agentId
*/
@Override
- public void setAgentId(Integer agentId) {
+ public void setAgentId(Long agentId) {
super.setAgentId(agentId);
String ukey;
if (agentId != null) {
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/config/impl/WxCpCorpGroupDefaultConfigImpl.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/config/impl/WxCpCorpGroupDefaultConfigImpl.java
index b3d4834426..ac57fbeb7a 100644
--- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/config/impl/WxCpCorpGroupDefaultConfigImpl.java
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/config/impl/WxCpCorpGroupDefaultConfigImpl.java
@@ -39,7 +39,7 @@ public class WxCpCorpGroupDefaultConfigImpl implements WxCpCorpGroupConfigStorag
/**
* 微信企业号应用 ID
*/
- private volatile Integer agentId;
+ private volatile Long agentId;
@Override
public void setBaseApiUrl(String baseUrl) {
@@ -65,17 +65,17 @@ public void setCorpId(String corpId) {
}
@Override
- public Integer getAgentId() {
+ public Long getAgentId() {
return agentId;
}
@Override
- public void setAgentId(Integer agentId) {
+ public void setAgentId(Long agentId) {
this.agentId = agentId;
}
@Override
- public void updateCorpAccessToken(String corpId, Integer agentId, String corpAccessToken, int expiresInSeconds) {
+ public void updateCorpAccessToken(String corpId, Long agentId, String corpAccessToken, int expiresInSeconds) {
String key = generateAccessTokenKey(corpId, agentId);
corpAccessTokenMap.put(key, corpAccessToken);
//预留200秒的时间
@@ -83,12 +83,12 @@ public void updateCorpAccessToken(String corpId, Integer agentId, String corpAcc
}
@Override
- public String getCorpAccessToken(String corpId, Integer agentId) {
+ public String getCorpAccessToken(String corpId, Long agentId) {
return this.corpAccessTokenMap.get(generateAccessTokenKey(corpId, agentId));
}
@Override
- public WxAccessToken getCorpAccessTokenEntity(String corpId, Integer agentId) {
+ public WxAccessToken getCorpAccessTokenEntity(String corpId, Long agentId) {
String key = generateAccessTokenKey(corpId, agentId);
String accessToken = corpAccessTokenMap.getOrDefault(key, StringUtils.EMPTY);
Long expire = corpAccessTokenExpireTimeMap.getOrDefault(key, 0L);
@@ -99,7 +99,7 @@ public WxAccessToken getCorpAccessTokenEntity(String corpId, Integer agentId) {
}
@Override
- public boolean isCorpAccessTokenExpired(String corpId, Integer agentId) {
+ public boolean isCorpAccessTokenExpired(String corpId, Long agentId) {
//不存在或者过期
String key = generateAccessTokenKey(corpId, agentId);
return corpAccessTokenExpireTimeMap.get(key) == null
@@ -107,7 +107,7 @@ public boolean isCorpAccessTokenExpired(String corpId, Integer agentId) {
}
@Override
- public void expireCorpAccessToken(String corpId, Integer agentId) {
+ public void expireCorpAccessToken(String corpId, Long agentId) {
String key = generateAccessTokenKey(corpId, agentId);
corpAccessTokenMap.remove(key);
corpAccessTokenExpireTimeMap.remove(key);
@@ -189,12 +189,12 @@ public boolean autoRefreshToken() {
}
@Override
- public Lock getCorpAccessTokenLock(String corpId, Integer agentId) {
+ public Lock getCorpAccessTokenLock(String corpId, Long agentId) {
return this.corpAccessTokenLocker
.computeIfAbsent(generateAccessTokenKey(corpId, agentId), key -> new ReentrantLock());
}
- private String generateAccessTokenKey(String corpId, Integer agentId) {
+ private String generateAccessTokenKey(String corpId, Long agentId) {
return String.join(":", this.corpId, String.valueOf(this.agentId), corpId, String.valueOf(agentId));
}
}
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/config/impl/WxCpCorpGroupRedissonConfigImpl.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/config/impl/WxCpCorpGroupRedissonConfigImpl.java
index 1ef05ba8b3..d5b566a5e5 100644
--- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/config/impl/WxCpCorpGroupRedissonConfigImpl.java
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/config/impl/WxCpCorpGroupRedissonConfigImpl.java
@@ -60,7 +60,7 @@ public class WxCpCorpGroupRedissonConfigImpl implements WxCpCorpGroupConfigStora
/**
* 微信企业号应用 ID
*/
- private volatile Integer agentId;
+ private volatile Long agentId;
@Override
public void setBaseApiUrl(String baseUrl) {
@@ -86,27 +86,27 @@ public void setCorpId(String corpId) {
}
@Override
- public Integer getAgentId() {
+ public Long getAgentId() {
return agentId;
}
@Override
- public void setAgentId(Integer agentId) {
+ public void setAgentId(Long agentId) {
this.agentId = agentId;
}
@Override
- public void updateCorpAccessToken(String corpId, Integer agentId, String corpAccessToken, int expiresInSeconds) {
+ public void updateCorpAccessToken(String corpId, Long agentId, String corpAccessToken, int expiresInSeconds) {
wxRedisOps.setValue(generateAccessTokenKey(corpId, agentId), corpAccessToken, expiresInSeconds, TimeUnit.SECONDS);
}
@Override
- public String getCorpAccessToken(String corpId, Integer agentId) {
+ public String getCorpAccessToken(String corpId, Long agentId) {
return wxRedisOps.getValue(generateAccessTokenKey(corpId, agentId));
}
@Override
- public WxAccessToken getCorpAccessTokenEntity(String corpId, Integer agentId) {
+ public WxAccessToken getCorpAccessTokenEntity(String corpId, Long agentId) {
String key = generateAccessTokenKey(corpId, agentId);
String accessToken = wxRedisOps.getValue(key);
Long expire = wxRedisOps.getExpire(key);
@@ -120,13 +120,13 @@ public WxAccessToken getCorpAccessTokenEntity(String corpId, Integer agentId) {
}
@Override
- public boolean isCorpAccessTokenExpired(String corpId, Integer agentId) {
+ public boolean isCorpAccessTokenExpired(String corpId, Long agentId) {
String key = generateAccessTokenKey(corpId, agentId);
return wxRedisOps.getExpire(key) == 0L || wxRedisOps.getExpire(key) == -2;
}
@Override
- public void expireCorpAccessToken(String corpId, Integer agentId) {
+ public void expireCorpAccessToken(String corpId, Long agentId) {
wxRedisOps.expire(generateAccessTokenKey(corpId, agentId), 0, TimeUnit.SECONDS);
}
@@ -206,11 +206,11 @@ public boolean autoRefreshToken() {
}
@Override
- public Lock getCorpAccessTokenLock(String corpId, Integer agentId) {
+ public Lock getCorpAccessTokenLock(String corpId, Long agentId) {
return this.getLockByKey(String.join(":", corpId, String.valueOf(agentId), LOCKER_CORP_ACCESS_TOKEN));
}
- private String generateAccessTokenKey(String corpId, Integer agentId) {
+ private String generateAccessTokenKey(String corpId, Long agentId) {
return String.join(":", keyPrefix, CG_ACCESS_TOKEN_KEY, corpId, String.valueOf(agentId));
}
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/config/impl/WxCpDefaultConfigImpl.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/config/impl/WxCpDefaultConfigImpl.java
index 6435370150..484e0c4284 100644
--- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/config/impl/WxCpDefaultConfigImpl.java
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/config/impl/WxCpDefaultConfigImpl.java
@@ -30,7 +30,7 @@ public class WxCpDefaultConfigImpl implements WxCpConfigStorage, Serializable {
/**
* The Agent id.
*/
- protected volatile Integer agentId;
+ protected volatile Long agentId;
/**
* The Jsapi ticket lock.
*/
@@ -320,7 +320,7 @@ public void setAesKey(String aesKey) {
}
@Override
- public Integer getAgentId() {
+ public Long getAgentId() {
return this.agentId;
}
@@ -329,10 +329,14 @@ public Integer getAgentId() {
*
* @param agentId the agent id
*/
- public void setAgentId(Integer agentId) {
+ public void setAgentId(Long agentId) {
this.agentId = agentId;
}
+ public void setAgentId(long agentId) {
+ this.setAgentId(Long.valueOf(agentId));
+ }
+
/**
* 设置企微会话存档路径.
*
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/config/impl/WxCpRedisConfigImpl.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/config/impl/WxCpRedisConfigImpl.java
index 85d136e01d..a013a9b930 100644
--- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/config/impl/WxCpRedisConfigImpl.java
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/config/impl/WxCpRedisConfigImpl.java
@@ -40,7 +40,7 @@ public class WxCpRedisConfigImpl implements WxCpConfigStorage {
private volatile String corpSecret;
private volatile String token;
private volatile String aesKey;
- private volatile Integer agentId;
+ private volatile Long agentId;
private volatile String msgAuditPriKey;
private volatile String msgAuditLibPath;
private volatile String oauth2redirectUri;
@@ -312,7 +312,7 @@ public void setCorpSecret(String corpSecret) {
}
@Override
- public Integer getAgentId() {
+ public Long getAgentId() {
return this.agentId;
}
@@ -321,7 +321,7 @@ public Integer getAgentId() {
*
* @param agentId the agent id
*/
- public void setAgentId(Integer agentId) {
+ public void setAgentId(Long agentId) {
this.agentId = agentId;
}
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/constant/WxCpApiPathConsts.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/constant/WxCpApiPathConsts.java
index 642e579870..bb180cc40a 100644
--- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/constant/WxCpApiPathConsts.java
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/constant/WxCpApiPathConsts.java
@@ -1719,6 +1719,23 @@ interface Kf {
*/
String CUSTOMER_CANCEL_UPGRADE_SERVICE = "/cgi-bin/kf/customer/cancel_upgrade_service";
+ /** 添加知识库分组。 */
+ String KNOWLEDGE_ADD_GROUP = "/cgi-bin/kf/knowledge/add_group";
+ /** 删除知识库分组。 */
+ String KNOWLEDGE_DEL_GROUP = "/cgi-bin/kf/knowledge/del_group";
+ /** 修改知识库分组。 */
+ String KNOWLEDGE_MOD_GROUP = "/cgi-bin/kf/knowledge/mod_group";
+ /** 获取知识库分组列表。 */
+ String KNOWLEDGE_LIST_GROUP = "/cgi-bin/kf/knowledge/list_group";
+ /** 添加知识库问答。 */
+ String KNOWLEDGE_ADD_INTENT = "/cgi-bin/kf/knowledge/add_intent";
+ /** 删除知识库问答。 */
+ String KNOWLEDGE_DEL_INTENT = "/cgi-bin/kf/knowledge/del_intent";
+ /** 修改知识库问答。 */
+ String KNOWLEDGE_MOD_INTENT = "/cgi-bin/kf/knowledge/mod_intent";
+ /** 获取知识库问答列表。 */
+ String KNOWLEDGE_LIST_INTENT = "/cgi-bin/kf/knowledge/list_intent";
+
}
/**
@@ -1884,4 +1901,22 @@ interface Hr {
*/
String UPDATE_EMPLOYEE_FIELD_INFO = "/cgi-bin/hr/update_staff_info";
}
+
+ /**
+ * 待办相关接口.
+ * 官方文档:https://developer.work.weixin.qq.com/document/path/101524
+ */
+ interface Todo {
+ /**
+ * 获取待办详情
+ * https://developer.work.weixin.qq.com/document/path/101524
+ */
+ String TODO_GET = "/cgi-bin/todo/get";
+
+ /**
+ * 更新待办状态
+ * https://developer.work.weixin.qq.com/document/path/101534
+ */
+ String TODO_UPDATE = "/cgi-bin/todo/update";
+ }
}
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/corpgroup/service/WxCpCgService.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/corpgroup/service/WxCpCgService.java
index f94c14a4f1..a8d0de682e 100644
--- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/corpgroup/service/WxCpCgService.java
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/corpgroup/service/WxCpCgService.java
@@ -24,11 +24,11 @@ public interface WxCpCgService {
* @param corpAccessToken the corp access token
* @param expiresInSeconds the expires in seconds
*/
- void updateCorpAccessToken(String corpId, Integer agentId, String corpAccessToken, int expiresInSeconds);
+ void updateCorpAccessToken(String corpId, Long agentId, String corpAccessToken, int expiresInSeconds);
- String getCorpAccessToken(String corpId, Integer agentId, Integer businessType) throws WxErrorException;
+ String getCorpAccessToken(String corpId, Long agentId, Integer businessType) throws WxErrorException;
- String getCorpAccessToken(String corpId, Integer agentId, Integer businessType, boolean forceRefresh) throws WxErrorException;
+ String getCorpAccessToken(String corpId, Long agentId, Integer businessType, boolean forceRefresh) throws WxErrorException;
/**
* 授权企业的access token相关
@@ -39,7 +39,7 @@ public interface WxCpCgService {
* @return the access token
* @throws WxErrorException 微信错误异常
*/
- WxAccessToken getCorpAccessTokenEntity(String corpId, Integer agentId, Integer businessType) throws WxErrorException;
+ WxAccessToken getCorpAccessTokenEntity(String corpId, Long agentId, Integer businessType) throws WxErrorException;
/**
* Gets access token entity.
@@ -51,7 +51,7 @@ public interface WxCpCgService {
* @return the access token entity
* @throws WxErrorException 微信错误异常
*/
- WxAccessToken getCorpAccessTokenEntity(String corpId, Integer agentId, Integer businessType, boolean forceRefresh) throws WxErrorException;
+ WxAccessToken getCorpAccessTokenEntity(String corpId, Long agentId, Integer businessType, boolean forceRefresh) throws WxErrorException;
/**
* Is access token expired boolean.
@@ -60,7 +60,7 @@ public interface WxCpCgService {
* @param agentId 应用ID
* @return the boolean
*/
- boolean isCorpAccessTokenExpired(String corpId, Integer agentId);
+ boolean isCorpAccessTokenExpired(String corpId, Long agentId);
/**
* Expire access token.
@@ -68,7 +68,7 @@ public interface WxCpCgService {
* @param corpId 企业ID
* @param agentId 应用ID
*/
- void expireCorpAccessToken(String corpId, Integer agentId);
+ void expireCorpAccessToken(String corpId, Long agentId);
/**
* 当本Service没有实现某个API的时候,可以用这个,针对所有微信API中的GET请求.
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/corpgroup/service/impl/BaseWxCpCgServiceImpl.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/corpgroup/service/impl/BaseWxCpCgServiceImpl.java
index e4fe2a686a..5439849f2a 100644
--- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/corpgroup/service/impl/BaseWxCpCgServiceImpl.java
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/corpgroup/service/impl/BaseWxCpCgServiceImpl.java
@@ -43,17 +43,17 @@ public abstract class BaseWxCpCgServiceImpl implements WxCpCgService, Requ
private final WxCpLinkedCorpService linkedCorpService = new WxCpLinkedCorpServiceImpl(this);
@Override
- public void updateCorpAccessToken(String corpId, Integer agentId, String corpAccessToken, int expiresInSeconds) {
+ public void updateCorpAccessToken(String corpId, Long agentId, String corpAccessToken, int expiresInSeconds) {
}
@Override
- public String getCorpAccessToken(String corpId, Integer agentId, Integer businessType) throws WxErrorException {
+ public String getCorpAccessToken(String corpId, Long agentId, Integer businessType) throws WxErrorException {
return getCorpAccessToken(corpId, agentId, businessType, false);
}
@Override
- public String getCorpAccessToken(String corpId, Integer agentId, Integer businessType, boolean forceRefresh) throws WxErrorException {
+ public String getCorpAccessToken(String corpId, Long agentId, Integer businessType, boolean forceRefresh) throws WxErrorException {
if (!this.configStorage.isCorpAccessTokenExpired(corpId, agentId) && !forceRefresh) {
return this.configStorage.getCorpAccessToken(corpId, agentId);
}
@@ -71,23 +71,23 @@ public String getCorpAccessToken(String corpId, Integer agentId, Integer busines
}
@Override
- public WxAccessToken getCorpAccessTokenEntity(String corpId, Integer agentId, Integer businessType) throws WxErrorException {
+ public WxAccessToken getCorpAccessTokenEntity(String corpId, Long agentId, Integer businessType) throws WxErrorException {
return this.getCorpAccessTokenEntity(corpId, agentId, businessType, false);
}
@Override
- public WxAccessToken getCorpAccessTokenEntity(String corpId, Integer agentId, Integer businessType, boolean forceRefresh) throws WxErrorException {
+ public WxAccessToken getCorpAccessTokenEntity(String corpId, Long agentId, Integer businessType, boolean forceRefresh) throws WxErrorException {
return this.configStorage.getCorpAccessTokenEntity(corpId, agentId);
}
@Override
- public boolean isCorpAccessTokenExpired(String corpId, Integer agentId) {
+ public boolean isCorpAccessTokenExpired(String corpId, Long agentId) {
return this.configStorage.isCorpAccessTokenExpired(corpId, agentId);
}
@Override
- public void expireCorpAccessToken(String corpId, Integer agentId) {
+ public void expireCorpAccessToken(String corpId, Long agentId) {
this.configStorage.expireCorpAccessToken(corpId, agentId);
}
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/util/crypto/WxCpIntelligentRobotCryptUtil.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/util/crypto/WxCpIntelligentRobotCryptUtil.java
new file mode 100644
index 0000000000..512c3073c6
--- /dev/null
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/util/crypto/WxCpIntelligentRobotCryptUtil.java
@@ -0,0 +1,88 @@
+package me.chanjar.weixin.cp.util.crypto;
+
+import com.google.gson.JsonObject;
+import me.chanjar.weixin.common.util.crypto.SHA1;
+import me.chanjar.weixin.common.util.crypto.WxCryptUtil;
+import me.chanjar.weixin.cp.util.json.WxCpGsonBuilder;
+import me.chanjar.weixin.common.error.WxRuntimeException;
+import org.apache.commons.codec.binary.Base64;
+
+import javax.crypto.Cipher;
+import javax.crypto.spec.IvParameterSpec;
+import javax.crypto.spec.SecretKeySpec;
+import java.nio.charset.StandardCharsets;
+import java.util.Arrays;
+import java.util.UUID;
+
+/**
+ * 企业微信智能机器人 API 模式消息加解密工具.
+ *
+ * 机器人 API 模式使用机器人后台配置的 Token、EncodingAESKey 和机器人 ID,
+ * 与企业应用 access_token 无关。
+ */
+public class WxCpIntelligentRobotCryptUtil extends WxCryptUtil {
+
+ public WxCpIntelligentRobotCryptUtil(String token, String encodingAesKey, String aiBotId) {
+ super(token, encodingAesKey, aiBotId);
+ }
+
+ /**
+ * 解密机器人 API 模式的 JSON 回调消息.
+ */
+ public String decrypt(String msgSignature, String timestamp, String nonce, String encryptedContent) {
+ String signature = SHA1.gen(this.token, timestamp, nonce, encryptedContent);
+ if (!signature.equals(msgSignature)) {
+ throw new WxRuntimeException("加密消息签名校验失败");
+ }
+
+ try {
+ Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding");
+ cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(this.aesKey, "AES"),
+ new IvParameterSpec(Arrays.copyOfRange(this.aesKey, 0, 16)));
+ byte[] bytes = me.chanjar.weixin.common.util.crypto.PKCS7Encoder.decode(
+ cipher.doFinal(Base64.decodeBase64(encryptedContent)));
+ if (bytes.length < 20) {
+ throw new WxRuntimeException("解密后数据长度异常,可能为错误的密文或EncodingAESKey");
+ }
+
+ int plainTextLength = 0;
+ for (int index = 16; index < 20; index++) {
+ plainTextLength = (plainTextLength << 8) | (bytes[index] & 0xff);
+ }
+ int plainTextEnd = 20 + plainTextLength;
+ if (plainTextLength < 0 || plainTextEnd > bytes.length) {
+ throw new WxRuntimeException("解密后数据格式非法:消息长度不正确,可能为错误的密文或EncodingAESKey");
+ }
+
+ String receiverId = new String(Arrays.copyOfRange(bytes, plainTextEnd, bytes.length), StandardCharsets.UTF_8);
+ if (!this.appidOrCorpid.equals(receiverId)) {
+ throw new WxRuntimeException("智能机器人ID不正确,请核实!");
+ }
+ return new String(Arrays.copyOfRange(bytes, 20, plainTextEnd), StandardCharsets.UTF_8);
+ } catch (WxRuntimeException e) {
+ throw e;
+ } catch (Exception e) {
+ throw new WxRuntimeException(e);
+ }
+ }
+
+ /**
+ * 加密机器人 API 模式的 JSON 回复消息.
+ */
+ public String encrypt(String plainJson, String timestamp, String nonce) {
+ String encryptedContent = encrypt(UUID.randomUUID().toString().replace("-", "").substring(0, 16), plainJson);
+ JsonObject result = new JsonObject();
+ result.addProperty("encrypt", encryptedContent);
+ result.addProperty("msg_signature", SHA1.gen(this.token, timestamp, nonce, encryptedContent));
+ result.addProperty("timestamp", timestamp);
+ result.addProperty("nonce", nonce);
+ return WxCpGsonBuilder.create().toJson(result);
+ }
+
+ /**
+ * 解密 URL 校验请求中的 echostr.
+ */
+ public String verifyUrl(String msgSignature, String timestamp, String nonce, String echoStr) {
+ return decrypt(msgSignature, timestamp, nonce, echoStr);
+ }
+}
diff --git a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/impl/BaseWxCpServiceImplLogTest.java b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/impl/BaseWxCpServiceImplLogTest.java
new file mode 100644
index 0000000000..2164cbeacd
--- /dev/null
+++ b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/impl/BaseWxCpServiceImplLogTest.java
@@ -0,0 +1,19 @@
+package me.chanjar.weixin.cp.api.impl;
+
+import org.testng.annotations.Test;
+
+import static org.testng.Assert.assertEquals;
+
+public class BaseWxCpServiceImplLogTest {
+
+ @Test
+ public void redactQueryStringShouldHideTemporaryResponseUrlCredentials() {
+ assertEquals(BaseWxCpServiceImpl.redactQueryString("https://example.com/reply?token=temporary-secret&nonce=123"),
+ "https://example.com/reply?******");
+ }
+
+ @Test
+ public void redactQueryStringShouldKeepUrlWithoutQueryString() {
+ assertEquals(BaseWxCpServiceImpl.redactQueryString("https://example.com/reply"), "https://example.com/reply");
+ }
+}
diff --git a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/impl/BaseWxCpServiceImplTest.java b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/impl/BaseWxCpServiceImplTest.java
index bdc85afcfc..115eafd182 100644
--- a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/impl/BaseWxCpServiceImplTest.java
+++ b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/impl/BaseWxCpServiceImplTest.java
@@ -121,7 +121,7 @@ public WxCpConfigStorage getWxCpConfigStorage() {
return config;
}
};
- config.setAgentId(1);
+ config.setAgentId(1L);
service.setWxCpConfigStorage(config);
RequestExecutor