客户日报
This commit is contained in:
parent
52f46aabdc
commit
0d813d73f0
@ -101,6 +101,7 @@ public class FoundationProperties {
|
|||||||
private boolean enabled;
|
private boolean enabled;
|
||||||
private String corpId;
|
private String corpId;
|
||||||
private String defaultApp = "general";
|
private String defaultApp = "general";
|
||||||
|
private String studentContactApp;
|
||||||
private String studentContactSecret;
|
private String studentContactSecret;
|
||||||
private String token;
|
private String token;
|
||||||
private String encodingAesKey;
|
private String encodingAesKey;
|
||||||
@ -112,6 +113,8 @@ public class FoundationProperties {
|
|||||||
public void setCorpId(String corpId) { this.corpId = corpId; }
|
public void setCorpId(String corpId) { this.corpId = corpId; }
|
||||||
public String getDefaultApp() { return defaultApp; }
|
public String getDefaultApp() { return defaultApp; }
|
||||||
public void setDefaultApp(String defaultApp) { this.defaultApp = defaultApp; }
|
public void setDefaultApp(String defaultApp) { this.defaultApp = defaultApp; }
|
||||||
|
public String getStudentContactApp() { return studentContactApp; }
|
||||||
|
public void setStudentContactApp(String studentContactApp) { this.studentContactApp = studentContactApp; }
|
||||||
public String getStudentContactSecret() { return studentContactSecret; }
|
public String getStudentContactSecret() { return studentContactSecret; }
|
||||||
public void setStudentContactSecret(String studentContactSecret) { this.studentContactSecret = studentContactSecret; }
|
public void setStudentContactSecret(String studentContactSecret) { this.studentContactSecret = studentContactSecret; }
|
||||||
public String getToken() { return token; }
|
public String getToken() { return token; }
|
||||||
|
|||||||
@ -105,8 +105,9 @@ public class WecomClient {
|
|||||||
.block();
|
.block();
|
||||||
|
|
||||||
if (response == null || !response.success()) {
|
if (response == null || !response.success()) {
|
||||||
log.error("wecom student contact get follow users failed err={}", response == null ? "null" : response.errmsg());
|
String error = apiError(response == null ? null : response.errcode(), response == null ? null : response.errmsg());
|
||||||
throw new IllegalStateException("WeCom student contact get follow users failed: " + (response == null ? "null" : response.errmsg()));
|
log.error("wecom student contact get follow users failed {}", error);
|
||||||
|
throw new IllegalStateException("WeCom student contact get follow users failed: " + error);
|
||||||
}
|
}
|
||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
@ -125,8 +126,9 @@ public class WecomClient {
|
|||||||
.block();
|
.block();
|
||||||
|
|
||||||
if (response == null || !response.success()) {
|
if (response == null || !response.success()) {
|
||||||
log.error("wecom student contact batch get failed err={}", response == null ? "null" : response.errmsg());
|
String error = apiError(response == null ? null : response.errcode(), response == null ? null : response.errmsg());
|
||||||
throw new IllegalStateException("WeCom student contact batch get failed: " + (response == null ? "null" : response.errmsg()));
|
log.error("wecom student contact batch get failed {}", error);
|
||||||
|
throw new IllegalStateException("WeCom student contact batch get failed: " + error);
|
||||||
}
|
}
|
||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
@ -145,8 +147,9 @@ public class WecomClient {
|
|||||||
.block();
|
.block();
|
||||||
|
|
||||||
if (response == null || !response.success()) {
|
if (response == null || !response.success()) {
|
||||||
log.error("wecom student contact behavior data failed err={}", response == null ? "null" : response.errmsg());
|
String error = apiError(response == null ? null : response.errcode(), response == null ? null : response.errmsg());
|
||||||
throw new IllegalStateException("WeCom student contact behavior data failed: " + (response == null ? "null" : response.errmsg()));
|
log.error("wecom student contact behavior data failed {}", error);
|
||||||
|
throw new IllegalStateException("WeCom student contact behavior data failed: " + error);
|
||||||
}
|
}
|
||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
@ -194,19 +197,24 @@ public class WecomClient {
|
|||||||
|
|
||||||
boolean success = response != null;
|
boolean success = response != null;
|
||||||
String error = "null";
|
String error = "null";
|
||||||
|
Integer errorCode = null;
|
||||||
if (response instanceof WecomGroupMessageListResponse value) {
|
if (response instanceof WecomGroupMessageListResponse value) {
|
||||||
success = value.success();
|
success = value.success();
|
||||||
error = value.errmsg();
|
error = value.errmsg();
|
||||||
|
errorCode = value.errcode();
|
||||||
} else if (response instanceof WecomGroupMessageTaskResponse value) {
|
} else if (response instanceof WecomGroupMessageTaskResponse value) {
|
||||||
success = value.success();
|
success = value.success();
|
||||||
error = value.errmsg();
|
error = value.errmsg();
|
||||||
|
errorCode = value.errcode();
|
||||||
} else if (response instanceof WecomGroupMessageSendResultResponse value) {
|
} else if (response instanceof WecomGroupMessageSendResultResponse value) {
|
||||||
success = value.success();
|
success = value.success();
|
||||||
error = value.errmsg();
|
error = value.errmsg();
|
||||||
|
errorCode = value.errcode();
|
||||||
}
|
}
|
||||||
if (!success) {
|
if (!success) {
|
||||||
log.error("wecom student contact {} failed err={}", operation, error);
|
String apiError = apiError(errorCode, error);
|
||||||
throw new IllegalStateException("WeCom " + operation + " failed: " + error);
|
log.error("wecom student contact {} failed {}", operation, apiError);
|
||||||
|
throw new IllegalStateException("WeCom " + operation + " failed: " + apiError);
|
||||||
}
|
}
|
||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
@ -229,8 +237,9 @@ public class WecomClient {
|
|||||||
.block();
|
.block();
|
||||||
|
|
||||||
if (response == null || !response.success() || response.accessToken() == null) {
|
if (response == null || !response.success() || response.accessToken() == null) {
|
||||||
log.error("wecom gettoken failed err={}", response == null ? "null" : response.errmsg());
|
String error = apiError(response == null ? null : response.errcode(), response == null ? null : response.errmsg());
|
||||||
throw new IllegalStateException("WeCom gettoken failed: " + (response == null ? "null" : response.errmsg()));
|
log.error("wecom gettoken failed {}", error);
|
||||||
|
throw new IllegalStateException("WeCom gettoken failed: " + error);
|
||||||
}
|
}
|
||||||
|
|
||||||
cache.token = response.accessToken();
|
cache.token = response.accessToken();
|
||||||
@ -242,7 +251,17 @@ public class WecomClient {
|
|||||||
|
|
||||||
private String studentContactSecret() {
|
private String studentContactSecret() {
|
||||||
String secret = properties.getWecom().getStudentContactSecret();
|
String secret = properties.getWecom().getStudentContactSecret();
|
||||||
return secret == null || secret.isBlank() ? app(properties.getWecom().getDefaultApp()).getSecret() : secret;
|
if (secret != null && !secret.isBlank()) {
|
||||||
|
return secret;
|
||||||
|
}
|
||||||
|
String appKey = requireText(properties.getWecom().getStudentContactApp(),
|
||||||
|
"WeCom customer contact credential is missing: configure student-contact-secret or student-contact-app");
|
||||||
|
return app(appKey).getSecret();
|
||||||
|
}
|
||||||
|
|
||||||
|
private String apiError(Integer errcode, String errmsg) {
|
||||||
|
return "errcode=" + (errcode == null ? "unknown" : errcode)
|
||||||
|
+ ", errmsg=" + (errmsg == null || errmsg.isBlank() ? "unknown" : errmsg);
|
||||||
}
|
}
|
||||||
|
|
||||||
private FoundationProperties.Wecom.App app(String appKey) {
|
private FoundationProperties.Wecom.App app(String appKey) {
|
||||||
|
|||||||
@ -62,10 +62,48 @@ public class WecomCustomerOperationsReportIntentHandler implements SemanticInten
|
|||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.error("wecom customer operations report failed wecomUserId={} range={}~{} err={}",
|
log.error("wecom customer operations report failed wecomUserId={} range={}~{} err={}",
|
||||||
context.wecomUserId(), range.startDate(), range.endDate(), e.getMessage(), e);
|
context.wecomUserId(), range.startDate(), range.endDate(), e.getMessage(), e);
|
||||||
return "企业微信客户运营日报查询失败,请稍后重试。";
|
return failureMessage(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private String failureMessage(Exception exception) {
|
||||||
|
String message = rootMessage(exception);
|
||||||
|
String lower = message.toLowerCase();
|
||||||
|
if (lower.contains("customer contact credential is missing")) {
|
||||||
|
return "企业微信客户联系凭证未配置:请设置 WECOM_STUDENT_CONTACT_SECRET,或配置可调用应用。";
|
||||||
|
}
|
||||||
|
if (lower.contains("errcode=60020") || lower.contains("not allow to access from your ip")) {
|
||||||
|
return "企业微信客户接口拒绝访问(60020):请将运行8880服务的服务器出口公网IP加入企业可信IP。";
|
||||||
|
}
|
||||||
|
if (lower.contains("errcode=48002") || lower.contains("api forbidden")) {
|
||||||
|
return "企业微信客户接口未授权(48002):请为当前应用开通客户联系接口权限,并检查客户联系Secret。";
|
||||||
|
}
|
||||||
|
if (lower.contains("errcode=40014") || lower.contains("invalid access_token")) {
|
||||||
|
return "企业微信客户接口凭证无效(40014):请检查客户联系Secret配置。";
|
||||||
|
}
|
||||||
|
if (lower.contains("errcode=60011") || lower.contains("no privilege to access")) {
|
||||||
|
return "企业微信客户接口无数据权限(60011):请检查应用可见范围和客户联系权限。";
|
||||||
|
}
|
||||||
|
if (lower.contains("wecom")) {
|
||||||
|
return "企业微信客户运营日报查询失败:" + shorten(message, 180);
|
||||||
|
}
|
||||||
|
return "企业微信客户运营日报查询失败,请查看服务器日志。";
|
||||||
|
}
|
||||||
|
|
||||||
|
private String rootMessage(Throwable throwable) {
|
||||||
|
Throwable current = throwable;
|
||||||
|
while (current.getCause() != null && current.getCause() != current) {
|
||||||
|
current = current.getCause();
|
||||||
|
}
|
||||||
|
String message = current.getMessage();
|
||||||
|
return message == null || message.isBlank() ? throwable.getClass().getSimpleName() : message;
|
||||||
|
}
|
||||||
|
|
||||||
|
private String shorten(String value, int maxLength) {
|
||||||
|
String normalized = value.replaceAll("[\\r\\n]+", " ").trim();
|
||||||
|
return normalized.length() <= maxLength ? normalized : normalized.substring(0, maxLength) + "…";
|
||||||
|
}
|
||||||
|
|
||||||
private String format(JsonNode report, SemanticDateRangeResolver.DateRange range) {
|
private String format(JsonNode report, SemanticDateRangeResolver.DateRange range) {
|
||||||
StringBuilder reply = new StringBuilder("### 🌱 企业微信客户运营日报\n> 日期:")
|
StringBuilder reply = new StringBuilder("### 🌱 企业微信客户运营日报\n> 日期:")
|
||||||
.append(range.startDate());
|
.append(range.startDate());
|
||||||
|
|||||||
@ -51,6 +51,8 @@ foundation:
|
|||||||
enabled: true
|
enabled: true
|
||||||
corp-id: wwaec174f56094f2b5
|
corp-id: wwaec174f56094f2b5
|
||||||
default-app: general
|
default-app: general
|
||||||
|
student-contact-app: sports-venue
|
||||||
|
student-contact-secret: ${WECOM_STUDENT_CONTACT_SECRET:}
|
||||||
token: crmAgentToken2026
|
token: crmAgentToken2026
|
||||||
encoding-aes-key: k3F8mN2vQ7xLp9sTd4YwH6cRb1JuEz5AaZq7BnVcK2D
|
encoding-aes-key: k3F8mN2vQ7xLp9sTd4YwH6cRb1JuEz5AaZq7BnVcK2D
|
||||||
apps:
|
apps:
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user