From 87fd7b502ba861dbec7a80876bf24bde249fd5da Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Tue, 19 May 2026 04:59:12 +0000
Subject: [PATCH 1/3] Initial plan
From 93417276dcacebeedbb290cc3cf355676e090131 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Tue, 19 May 2026 05:07:02 +0000
Subject: [PATCH 2/3] =?UTF-8?q?=E6=94=AF=E6=8C=81=E4=BC=81=E4=B8=9A?=
=?UTF-8?q?=E5=BE=AE=E4=BF=A1=E6=99=BA=E8=83=BD=E6=9C=BA=E5=99=A8=E4=BA=BA?=
=?UTF-8?q?JSON=E5=9B=9E=E8=B0=83=E6=B6=88=E6=81=AF=E8=A7=A3=E6=9E=90?=
=?UTF-8?q?=E5=B9=B6=E8=A1=A5=E5=85=85=E6=B5=8B=E8=AF=95?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Agent-Logs-Url: https://github.com/binarywang/WxJava/sessions/07e83fbe-cc11-4b67-82ec-6cb21fb184a3
Co-authored-by: binarywang <1343140+binarywang@users.noreply.github.com>
---
weixin-java-cp/INTELLIGENT_ROBOT.md | 11 +-
.../WxCpIntelligentRobotMessage.java | 196 ++++++++++++++++++
.../WxCpIntelligentRobotMessageTest.java | 76 +++++++
3 files changed, 282 insertions(+), 1 deletion(-)
create mode 100644 weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/intelligentrobot/WxCpIntelligentRobotMessage.java
create mode 100644 weixin-java-cp/src/test/java/me/chanjar/weixin/cp/bean/intelligentrobot/WxCpIntelligentRobotMessageTest.java
diff --git a/weixin-java-cp/INTELLIGENT_ROBOT.md b/weixin-java-cp/INTELLIGENT_ROBOT.md
index dcd90e1a1a..093a55660b 100644
--- a/weixin-java-cp/INTELLIGENT_ROBOT.md
+++ b/weixin-java-cp/INTELLIGENT_ROBOT.md
@@ -109,6 +109,15 @@ String fromUser = message.getFromUserName(); // 发送用户
// ...
```
+对于智能机器人 API 模式的 JSON 回调消息,可使用 `WxCpIntelligentRobotMessage` 解析:
+
+```java
+WxCpIntelligentRobotMessage callbackMessage = WxCpIntelligentRobotMessage.fromJson(jsonBody);
+String botId = callbackMessage.getAiBotId();
+String userId = callbackMessage.getFrom().getUserid();
+String msgType = callbackMessage.getMsgType();
+```
+
### 删除智能机器人
```java
@@ -146,4 +155,4 @@ robotService.deleteRobot(robotId);
1. 需要确保企业微信应用具有智能机器人相关权限
2. 智能机器人功能可能需要特定的企业微信版本支持
3. 会话ID可以用于保持对话的连续性,提升用户体验
-4. 机器人状态: 0表示停用,1表示启用
\ No newline at end of file
+4. 机器人状态: 0表示停用,1表示启用
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/intelligentrobot/WxCpIntelligentRobotMessage.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/intelligentrobot/WxCpIntelligentRobotMessage.java
new file mode 100644
index 0000000000..d485b59d69
--- /dev/null
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/intelligentrobot/WxCpIntelligentRobotMessage.java
@@ -0,0 +1,196 @@
+package me.chanjar.weixin.cp.bean.intelligentrobot;
+
+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;
+
+/**
+ * 企业微信智能机器人回调消息.
+ *
+ *
官方文档: https://developer.work.weixin.qq.com/document/path/100719
+ */
+@Data
+public class WxCpIntelligentRobotMessage implements Serializable {
+ private static final long serialVersionUID = -1L;
+
+ /**
+ * 本次回调的唯一性标志.
+ */
+ @SerializedName("msgid")
+ private String msgId;
+
+ /**
+ * 智能机器人id.
+ */
+ @SerializedName("aibotid")
+ private String aiBotId;
+
+ /**
+ * 会话id,仅群聊类型时返回.
+ */
+ @SerializedName("chatid")
+ private String chatId;
+
+ /**
+ * 会话类型,single/group.
+ */
+ @SerializedName("chattype")
+ private String chatType;
+
+ /**
+ * 消息发送者.
+ */
+ @SerializedName("from")
+ private From from;
+
+ /**
+ * 支持主动回复消息的临时url.
+ */
+ @SerializedName("response_url")
+ private String responseUrl;
+
+ /**
+ * 消息类型.
+ */
+ @SerializedName("msgtype")
+ private String msgType;
+
+ @SerializedName("text")
+ private Text text;
+
+ @SerializedName("image")
+ private Image image;
+
+ @SerializedName("mixed")
+ private Mixed mixed;
+
+ @SerializedName("voice")
+ private Voice voice;
+
+ @SerializedName("file")
+ private FileInfo file;
+
+ @SerializedName("video")
+ private Video video;
+
+ @SerializedName("quote")
+ private Quote quote;
+
+ @SerializedName("stream")
+ private Stream stream;
+
+ public static WxCpIntelligentRobotMessage fromJson(String json) {
+ return WxCpGsonBuilder.create().fromJson(json, WxCpIntelligentRobotMessage.class);
+ }
+
+ public String toJson() {
+ return WxCpGsonBuilder.create().toJson(this);
+ }
+
+ @Data
+ public static class From implements Serializable {
+ private static final long serialVersionUID = -1L;
+
+ @SerializedName("userid")
+ private String userid;
+ }
+
+ @Data
+ public static class Text implements Serializable {
+ private static final long serialVersionUID = -1L;
+
+ @SerializedName("content")
+ private String content;
+ }
+
+ @Data
+ public static class Image implements Serializable {
+ private static final long serialVersionUID = -1L;
+
+ @SerializedName("url")
+ private String url;
+ }
+
+ @Data
+ public static class Voice implements Serializable {
+ private static final long serialVersionUID = -1L;
+
+ @SerializedName("content")
+ private String content;
+ }
+
+ @Data
+ public static class FileInfo implements Serializable {
+ private static final long serialVersionUID = -1L;
+
+ @SerializedName("url")
+ private String url;
+ }
+
+ @Data
+ public static class Video implements Serializable {
+ private static final long serialVersionUID = -1L;
+
+ @SerializedName("url")
+ private String url;
+ }
+
+ @Data
+ public static class Stream implements Serializable {
+ private static final long serialVersionUID = -1L;
+
+ @SerializedName("id")
+ private String id;
+ }
+
+ @Data
+ public static class Mixed implements Serializable {
+ private static final long serialVersionUID = -1L;
+
+ @SerializedName("msg_item")
+ private List msgItem;
+ }
+
+ @Data
+ public static class MixedItem implements Serializable {
+ private static final long serialVersionUID = -1L;
+
+ @SerializedName("msgtype")
+ private String msgType;
+
+ @SerializedName("text")
+ private Text text;
+
+ @SerializedName("image")
+ private Image image;
+ }
+
+ @Data
+ public static class Quote implements Serializable {
+ private static final long serialVersionUID = -1L;
+
+ @SerializedName("msgtype")
+ private String msgType;
+
+ @SerializedName("text")
+ private Text text;
+
+ @SerializedName("image")
+ private Image image;
+
+ @SerializedName("mixed")
+ private Mixed mixed;
+
+ @SerializedName("voice")
+ private Voice voice;
+
+ @SerializedName("file")
+ private FileInfo file;
+
+ @SerializedName("video")
+ private Video video;
+ }
+}
diff --git a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/bean/intelligentrobot/WxCpIntelligentRobotMessageTest.java b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/bean/intelligentrobot/WxCpIntelligentRobotMessageTest.java
new file mode 100644
index 0000000000..f8f8791d0d
--- /dev/null
+++ b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/bean/intelligentrobot/WxCpIntelligentRobotMessageTest.java
@@ -0,0 +1,76 @@
+package me.chanjar.weixin.cp.bean.intelligentrobot;
+
+import org.testng.annotations.Test;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertNotNull;
+import static org.testng.Assert.assertNull;
+
+/**
+ * 智能机器人回调消息测试.
+ */
+public class WxCpIntelligentRobotMessageTest {
+
+ @Test
+ public void testFromJsonWithTextMessage() {
+ String json = "{"
+ + "\"msgid\":\"msg_1\","
+ + "\"aibotid\":\"bot_1\","
+ + "\"chatid\":\"chat_1\","
+ + "\"chattype\":\"group\","
+ + "\"from\":{\"userid\":\"zhangsan\"},"
+ + "\"response_url\":\"https://example.com/reply\","
+ + "\"msgtype\":\"text\","
+ + "\"text\":{\"content\":\"@robot hello\"}"
+ + "}";
+
+ WxCpIntelligentRobotMessage message = WxCpIntelligentRobotMessage.fromJson(json);
+ assertEquals(message.getMsgId(), "msg_1");
+ assertEquals(message.getAiBotId(), "bot_1");
+ assertEquals(message.getChatId(), "chat_1");
+ assertEquals(message.getChatType(), "group");
+ assertNotNull(message.getFrom());
+ assertEquals(message.getFrom().getUserid(), "zhangsan");
+ assertEquals(message.getResponseUrl(), "https://example.com/reply");
+ assertEquals(message.getMsgType(), "text");
+ assertNotNull(message.getText());
+ assertEquals(message.getText().getContent(), "@robot hello");
+ assertNull(message.getMixed());
+ assertNull(message.getStream());
+ }
+
+ @Test
+ public void testFromJsonWithMixedAndQuote() {
+ String json = "{"
+ + "\"msgid\":\"msg_2\","
+ + "\"aibotid\":\"bot_2\","
+ + "\"chattype\":\"single\","
+ + "\"from\":{\"userid\":\"lisi\"},"
+ + "\"msgtype\":\"mixed\","
+ + "\"mixed\":{\"msg_item\":["
+ + "{\"msgtype\":\"text\",\"text\":{\"content\":\"hello\"}},"
+ + "{\"msgtype\":\"image\",\"image\":{\"url\":\"https://example.com/1.png\"}}"
+ + "]},"
+ + "\"quote\":{\"msgtype\":\"text\",\"text\":{\"content\":\"quoted\"}}"
+ + "}";
+
+ WxCpIntelligentRobotMessage message = WxCpIntelligentRobotMessage.fromJson(json);
+ assertEquals(message.getMsgType(), "mixed");
+ assertNotNull(message.getMixed());
+ assertNotNull(message.getMixed().getMsgItem());
+ assertEquals(message.getMixed().getMsgItem().size(), 2);
+ assertEquals(message.getMixed().getMsgItem().get(0).getMsgType(), "text");
+ assertEquals(message.getMixed().getMsgItem().get(0).getText().getContent(), "hello");
+ assertEquals(message.getMixed().getMsgItem().get(1).getMsgType(), "image");
+ assertEquals(message.getMixed().getMsgItem().get(1).getImage().getUrl(), "https://example.com/1.png");
+ assertNotNull(message.getQuote());
+ assertEquals(message.getQuote().getMsgType(), "text");
+ assertEquals(message.getQuote().getText().getContent(), "quoted");
+
+ String serialized = message.toJson();
+ WxCpIntelligentRobotMessage deserialized = WxCpIntelligentRobotMessage.fromJson(serialized);
+ assertEquals(deserialized.getAiBotId(), "bot_2");
+ assertEquals(deserialized.getFrom().getUserid(), "lisi");
+ assertEquals(deserialized.getMixed().getMsgItem().size(), 2);
+ }
+}
From 2782478a0e55d7e4ca9be3ffbe2a7d3a3faa0a20 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Wed, 20 May 2026 01:55:02 +0000
Subject: [PATCH 3/3] =?UTF-8?q?=E4=B8=BA=E6=99=BA=E8=83=BD=E6=9C=BA?=
=?UTF-8?q?=E5=99=A8=E4=BA=BA=E5=9B=9E=E8=B0=83=E6=A8=A1=E5=9E=8B=E8=A1=A5?=
=?UTF-8?q?=E5=85=85=E6=9C=8D=E5=8A=A1=E8=B0=83=E7=94=A8=E5=85=A5=E5=8F=A3?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Agent-Logs-Url: https://github.com/binarywang/WxJava/sessions/153a6a9d-1d0b-4a49-a3c4-493265b9b6fa
Co-authored-by: binarywang <1343140+binarywang@users.noreply.github.com>
---
weixin-java-cp/INTELLIGENT_ROBOT.md | 3 ++-
.../weixin/cp/api/WxCpIntelligentRobotService.java | 10 +++++++++-
.../api/impl/WxCpIntelligentRobotServiceImpl.java | 7 ++++++-
.../impl/WxCpIntelligentRobotServiceImplTest.java | 13 ++++++++++++-
4 files changed, 29 insertions(+), 4 deletions(-)
diff --git a/weixin-java-cp/INTELLIGENT_ROBOT.md b/weixin-java-cp/INTELLIGENT_ROBOT.md
index 093a55660b..18dd0c677f 100644
--- a/weixin-java-cp/INTELLIGENT_ROBOT.md
+++ b/weixin-java-cp/INTELLIGENT_ROBOT.md
@@ -112,7 +112,8 @@ String fromUser = message.getFromUserName(); // 发送用户
对于智能机器人 API 模式的 JSON 回调消息,可使用 `WxCpIntelligentRobotMessage` 解析:
```java
-WxCpIntelligentRobotMessage callbackMessage = WxCpIntelligentRobotMessage.fromJson(jsonBody);
+WxCpIntelligentRobotMessage callbackMessage =
+ robotService.parseCallbackMessage(jsonBody);
String botId = callbackMessage.getAiBotId();
String userId = callbackMessage.getFrom().getUserid();
String msgType = callbackMessage.getMsgType();
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpIntelligentRobotService.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpIntelligentRobotService.java
index bc5f3f1915..58f4373ceb 100644
--- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpIntelligentRobotService.java
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpIntelligentRobotService.java
@@ -74,4 +74,12 @@ public interface WxCpIntelligentRobotService {
*/
WxCpIntelligentRobotSendMessageResponse sendMessage(WxCpIntelligentRobotSendMessageRequest request) throws WxErrorException;
-}
\ No newline at end of file
+ /**
+ * 解析智能机器人 API 模式回调消息.
+ *
+ * @param callbackMessageJson 回调消息JSON
+ * @return 解析后的回调消息对象
+ */
+ WxCpIntelligentRobotMessage parseCallbackMessage(String callbackMessageJson);
+
+}
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 8a12fa4ff4..aba1ee85c4 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
@@ -67,4 +67,9 @@ public WxCpIntelligentRobotSendMessageResponse sendMessage(WxCpIntelligentRobotS
return WxCpIntelligentRobotSendMessageResponse.fromJson(responseText);
}
-}
\ No newline at end of file
+ @Override
+ public WxCpIntelligentRobotMessage parseCallbackMessage(String callbackMessageJson) {
+ return WxCpIntelligentRobotMessage.fromJson(callbackMessageJson);
+ }
+
+}
diff --git a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/impl/WxCpIntelligentRobotServiceImplTest.java b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/impl/WxCpIntelligentRobotServiceImplTest.java
index 85104ee73a..843bf6aac0 100644
--- a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/impl/WxCpIntelligentRobotServiceImplTest.java
+++ b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/impl/WxCpIntelligentRobotServiceImplTest.java
@@ -119,4 +119,15 @@ public void testSendMessageResponse() {
assert response.getSessionId().equals("session123");
assert response.getErrcode() == 0;
}
-}
\ No newline at end of file
+
+ @Test
+ public void testParseCallbackMessage() {
+ String callbackJson = "{\"msgid\":\"msg_1\",\"aibotid\":\"bot_1\",\"chattype\":\"single\","
+ + "\"from\":{\"userid\":\"user_1\"},\"msgtype\":\"text\",\"text\":{\"content\":\"hello\"}}";
+ WxCpIntelligentRobotMessage message = this.wxCpService.getIntelligentRobotService().parseCallbackMessage(callbackJson);
+ assert message.getMsgId().equals("msg_1");
+ assert message.getAiBotId().equals("bot_1");
+ assert message.getFrom().getUserid().equals("user_1");
+ assert message.getText().getContent().equals("hello");
+ }
+}