fix(send-routing): address final code review findings
- WeComBotSender.resolveWebhookUrl: use custom URL as-is when no %s placeholder - WeComBotSender: treat unparseable/blank response body as failure - ConversationService.isAccountCompatibleWithConversation: ignore scene for single chats - SendService.selectSendAccountCandidates: apply accountTypes filter for non-conversation records - SendService: replace account type magic numbers with AccountType constants - WeComChannelAdapter: use AccountType.WECOM_BOT.getCode() instead of literal 6 - admin-web Conversation.vue: fallback to channelType filter when scene is unset - add tests for single-chat null scene, webhook_url propagation, and custom URL without %s
This commit is contained in:
@@ -62,6 +62,11 @@ public class WeComBotSender {
|
||||
String url = resolveWebhookUrl(request.getExtra(), key);
|
||||
ResponseEntity<String> response = restTemplate.postForEntity(url, entity, String.class);
|
||||
Map<String, Object> responseBody = parseResponseBody(response.getBody());
|
||||
if (responseBody == null) {
|
||||
result.setSuccess(false);
|
||||
result.setMessage("企微群机器人返回无法解析的响应");
|
||||
return result;
|
||||
}
|
||||
int errcode = parseInt(responseBody.get("errcode"));
|
||||
if (errcode != 0) {
|
||||
result.setSuccess(false);
|
||||
@@ -88,21 +93,20 @@ public class WeComBotSender {
|
||||
if (customUrl.contains("%s")) {
|
||||
return customUrl.replace("%s", key);
|
||||
}
|
||||
log.warn("[WeComBot] custom webhook_url missing %s placeholder; appending key param");
|
||||
return customUrl.contains("?") ? customUrl + "&key=" + key : customUrl + "?key=" + key;
|
||||
return customUrl;
|
||||
}
|
||||
return String.format(DEFAULT_WEBHOOK_URL, key);
|
||||
}
|
||||
|
||||
private Map<String, Object> parseResponseBody(String body) {
|
||||
if (body == null || body.isBlank()) {
|
||||
return new HashMap<>();
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
return objectMapper.readValue(body, Map.class);
|
||||
} catch (Exception e) {
|
||||
log.warn("[WeComBot] 解析响应失败: {}", body, e);
|
||||
return new HashMap<>();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@ import com.sino.mci.channel.common.dto.ChannelInitRequest;
|
||||
import com.sino.mci.channel.common.dto.ChannelInitResult;
|
||||
import com.sino.mci.channel.common.dto.SendMessageRequest;
|
||||
import com.sino.mci.channel.common.dto.SendMessageResult;
|
||||
import com.sino.mci.channel.common.model.AccountType;
|
||||
import com.sino.mci.channel.common.model.ChannelType;
|
||||
import com.sino.mci.channel.common.spi.ChannelAdapter;
|
||||
import com.sino.mci.channel.wecom.support.WeComServiceFactory;
|
||||
@@ -86,7 +87,7 @@ public class WeComChannelAdapter implements ChannelAdapter {
|
||||
}
|
||||
|
||||
Integer accountType = getAccountType(request);
|
||||
if (accountType != null && accountType == 6) {
|
||||
if (accountType != null && accountType == AccountType.WECOM_BOT.getCode()) {
|
||||
return weComBotSender.send(request);
|
||||
}
|
||||
|
||||
|
||||
@@ -109,4 +109,33 @@ class WeComBotSenderTest {
|
||||
assertTrue(result.isSuccess(), result.getMessage());
|
||||
server.verify();
|
||||
}
|
||||
|
||||
@Test
|
||||
void sendUsesCustomWebhookUrlWithoutPlaceholder() throws Exception {
|
||||
server.expect(requestTo("https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=REALKEY"))
|
||||
.andExpect(content().json("{\"msgtype\":\"text\",\"text\":{\"content\":\"hello\"}}"))
|
||||
.andRespond(withSuccess("{\"errcode\":0,\"errmsg\":\"ok\"}", MediaType.APPLICATION_JSON));
|
||||
|
||||
SendMessageRequest request = new SendMessageRequest();
|
||||
request.setExtra(Map.of("account_id", "dummy", "webhook_url", "https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=REALKEY"));
|
||||
request.setContentType("text");
|
||||
request.setContent(Map.of("text", "hello"));
|
||||
SendMessageResult result = sender.send(request);
|
||||
assertTrue(result.isSuccess(), result.getMessage());
|
||||
server.verify();
|
||||
}
|
||||
|
||||
@Test
|
||||
void sendFailsOnUnparseableResponseBody() {
|
||||
server.expect(requestTo("https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=dummy"))
|
||||
.andRespond(withSuccess("not-json", MediaType.TEXT_PLAIN));
|
||||
|
||||
SendMessageRequest request = new SendMessageRequest();
|
||||
request.setExtra(Map.of("account_id", "dummy"));
|
||||
request.setContentType("text");
|
||||
request.setContent(Map.of("text", "hello"));
|
||||
SendMessageResult result = sender.send(request);
|
||||
assertFalse(result.isSuccess());
|
||||
assertTrue(result.getMessage().contains("无法解析"));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user