85 lines
3.3 KiB
Java
85 lines
3.3 KiB
Java
package com.company.agentfoundation.integration.wecom;
|
|
|
|
import com.company.agentfoundation.config.FoundationProperties;
|
|
import org.slf4j.Logger;
|
|
import org.slf4j.LoggerFactory;
|
|
import org.springframework.http.MediaType;
|
|
import org.springframework.stereotype.Service;
|
|
import org.springframework.web.reactive.function.client.WebClient;
|
|
|
|
import java.time.Instant;
|
|
|
|
@Service
|
|
public class WecomClient {
|
|
private static final Logger log = LoggerFactory.getLogger(WecomClient.class);
|
|
private final FoundationProperties properties;
|
|
private final WebClient webClient;
|
|
|
|
private volatile String cachedToken;
|
|
private volatile Instant tokenExpireAt = Instant.EPOCH;
|
|
|
|
public WecomClient(FoundationProperties properties, WebClient.Builder builder) {
|
|
this.properties = properties;
|
|
this.webClient = builder.baseUrl("https://qyapi.weixin.qq.com").build();
|
|
}
|
|
|
|
public void sendText(String toUser, String content) {
|
|
log.info("wecom sendText start toUser={} agentId={} contentPreview={}", toUser, properties.getWecom().getAgentId(), preview(content));
|
|
String token = getAccessToken();
|
|
WecomSendMessageRequest req = new WecomSendMessageRequest();
|
|
req.setToUser(toUser);
|
|
req.setAgentId(properties.getWecom().getAgentId());
|
|
WecomSendMessageRequest.Text text = new WecomSendMessageRequest.Text();
|
|
text.setContent(content);
|
|
req.setText(text);
|
|
|
|
WecomApiResponse response = webClient.post()
|
|
.uri(uriBuilder -> uriBuilder.path("/cgi-bin/message/send").queryParam("access_token", token).build())
|
|
.contentType(MediaType.APPLICATION_JSON)
|
|
.bodyValue(req)
|
|
.retrieve()
|
|
.bodyToMono(WecomApiResponse.class)
|
|
.block();
|
|
|
|
if (response == null || !response.success()) {
|
|
log.error("wecom sendText failed toUser={} err={}", toUser, response == null ? "null" : response.errmsg());
|
|
throw new IllegalStateException("WeCom send failed: " + (response == null ? "null" : response.errmsg()));
|
|
}
|
|
log.info("wecom sendText success toUser={}", toUser);
|
|
}
|
|
|
|
private String getAccessToken() {
|
|
if (cachedToken != null && Instant.now().isBefore(tokenExpireAt)) {
|
|
log.info("wecom gettoken use cached token expireAt={}", tokenExpireAt);
|
|
return cachedToken;
|
|
}
|
|
|
|
WecomTokenResponse response = webClient.get()
|
|
.uri(uriBuilder -> uriBuilder.path("/cgi-bin/gettoken")
|
|
.queryParam("corpid", properties.getWecom().getCorpId())
|
|
.queryParam("corpsecret", properties.getWecom().getSecret())
|
|
.build())
|
|
.retrieve()
|
|
.bodyToMono(WecomTokenResponse.class)
|
|
.block();
|
|
|
|
if (response == null || !response.success() || response.accessToken() == null) {
|
|
log.error("wecom gettoken failed err={}", response == null ? "null" : response.errmsg());
|
|
throw new IllegalStateException("WeCom gettoken failed: " + (response == null ? "null" : response.errmsg()));
|
|
}
|
|
|
|
cachedToken = response.accessToken();
|
|
int expires = response.expiresIn() == null ? 7200 : response.expiresIn();
|
|
tokenExpireAt = Instant.now().plusSeconds(Math.max(300, expires - 120));
|
|
log.info("wecom gettoken success expireAt={}", tokenExpireAt);
|
|
return cachedToken;
|
|
}
|
|
|
|
private String preview(String text) {
|
|
if (text == null || text.isBlank()) {
|
|
return "";
|
|
}
|
|
return text.length() <= 80 ? text : text.substring(0, 80) + "...";
|
|
}
|
|
}
|