98 lines
3.7 KiB
Java
98 lines
3.7 KiB
Java
|
|
package com.company.agentfoundation.integration.wecom;
|
||
|
|
|
||
|
|
import com.company.agentfoundation.config.FoundationProperties;
|
||
|
|
import com.company.agentfoundation.domain.ChatRequest;
|
||
|
|
import com.company.agentfoundation.domain.ChatResponse;
|
||
|
|
import com.company.agentfoundation.security.AgentContext;
|
||
|
|
import com.company.agentfoundation.service.ChatService;
|
||
|
|
import com.fasterxml.jackson.dataformat.xml.XmlMapper;
|
||
|
|
import org.springframework.http.MediaType;
|
||
|
|
import org.springframework.web.bind.annotation.*;
|
||
|
|
|
||
|
|
import java.nio.charset.StandardCharsets;
|
||
|
|
import java.security.MessageDigest;
|
||
|
|
import java.util.Arrays;
|
||
|
|
import java.util.HexFormat;
|
||
|
|
import java.util.List;
|
||
|
|
|
||
|
|
@RestController
|
||
|
|
@RequestMapping("/v1/integrations/wecom")
|
||
|
|
public class WecomCallbackController {
|
||
|
|
private final FoundationProperties properties;
|
||
|
|
private final ChatService chatService;
|
||
|
|
private final WecomClient wecomClient;
|
||
|
|
private final XmlMapper xmlMapper = new XmlMapper();
|
||
|
|
|
||
|
|
public WecomCallbackController(FoundationProperties properties, ChatService chatService, WecomClient wecomClient) {
|
||
|
|
this.properties = properties;
|
||
|
|
this.chatService = chatService;
|
||
|
|
this.wecomClient = wecomClient;
|
||
|
|
}
|
||
|
|
|
||
|
|
@GetMapping("/callback")
|
||
|
|
public String verify(@RequestParam("msg_signature") String signature,
|
||
|
|
@RequestParam("timestamp") String timestamp,
|
||
|
|
@RequestParam("nonce") String nonce,
|
||
|
|
@RequestParam("echostr") String echostr) {
|
||
|
|
if (!validSignature(signature, timestamp, nonce)) {
|
||
|
|
throw new IllegalArgumentException("Invalid WeCom signature");
|
||
|
|
}
|
||
|
|
return echostr;
|
||
|
|
}
|
||
|
|
|
||
|
|
@PostMapping(value = "/callback", consumes = {MediaType.TEXT_XML_VALUE, MediaType.APPLICATION_XML_VALUE})
|
||
|
|
public String receive(@RequestParam("msg_signature") String signature,
|
||
|
|
@RequestParam("timestamp") String timestamp,
|
||
|
|
@RequestParam("nonce") String nonce,
|
||
|
|
@RequestBody String body) throws Exception {
|
||
|
|
if (!validSignature(signature, timestamp, nonce)) {
|
||
|
|
throw new IllegalArgumentException("Invalid WeCom signature");
|
||
|
|
}
|
||
|
|
|
||
|
|
WecomIncomingMessage msg = xmlMapper.readValue(body, WecomIncomingMessage.class);
|
||
|
|
if (msg == null || msg.getMsgType() == null || !"text".equalsIgnoreCase(msg.getMsgType())) {
|
||
|
|
return "success";
|
||
|
|
}
|
||
|
|
|
||
|
|
String userText = msg.getContent() == null ? "" : msg.getContent().trim();
|
||
|
|
if (userText.isBlank()) {
|
||
|
|
return "success";
|
||
|
|
}
|
||
|
|
|
||
|
|
ChatRequest req = new ChatRequest(
|
||
|
|
null,
|
||
|
|
List.of(
|
||
|
|
new ChatRequest.Message("system", "你是企业CRM智能助手。请给出简洁、可执行的客户跟进建议。"),
|
||
|
|
new ChatRequest.Message("user", userText)
|
||
|
|
),
|
||
|
|
0.3
|
||
|
|
);
|
||
|
|
|
||
|
|
ChatResponse chat = chatService.chat(new AgentContext(properties.getWecom().getCrmAgentId()), req);
|
||
|
|
String reply = (chat.content() == null || chat.content().isBlank()) ? "我已收到你的请求,但暂时无法生成建议。" : chat.content();
|
||
|
|
wecomClient.sendText(msg.getFromUserName(), reply);
|
||
|
|
|
||
|
|
return "success";
|
||
|
|
}
|
||
|
|
|
||
|
|
private boolean validSignature(String signature, String timestamp, String nonce) {
|
||
|
|
String token = properties.getWecom().getToken();
|
||
|
|
if (token == null || token.isBlank()) {
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
String[] arr = new String[]{token, timestamp, nonce};
|
||
|
|
Arrays.sort(arr);
|
||
|
|
String raw = String.join("", arr);
|
||
|
|
|
||
|
|
try {
|
||
|
|
MessageDigest digest = MessageDigest.getInstance("SHA-1");
|
||
|
|
byte[] sha1 = digest.digest(raw.getBytes(StandardCharsets.UTF_8));
|
||
|
|
String localSignature = HexFormat.of().formatHex(sha1);
|
||
|
|
return signature.equalsIgnoreCase(localSignature);
|
||
|
|
} catch (Exception e) {
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|