Skip to content

Commit 0e6e55a

Browse files
committed
🆕 #3815 【企业微信】增加智能机器人消息接收和主动发送功能
1 parent 626ca16 commit 0e6e55a

File tree

9 files changed

+240
-0
lines changed

9 files changed

+240
-0
lines changed

weixin-java-cp/INTELLIGENT_ROBOT.md

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,42 @@ String sessionId = "session123";
7373
robotService.resetSession(robotId, userid, sessionId);
7474
```
7575

76+
### 主动发送消息
77+
78+
智能机器人可以主动向用户发送消息,用于推送通知或提醒。
79+
80+
```java
81+
WxCpIntelligentRobotSendMessageRequest request = new WxCpIntelligentRobotSendMessageRequest();
82+
request.setRobotId("robot_id_here");
83+
request.setUserid("user123");
84+
request.setMessage("您好,这是来自智能机器人的主动消息");
85+
request.setSessionId("session123"); // 可选,用于保持会话连续性
86+
87+
WxCpIntelligentRobotSendMessageResponse response = robotService.sendMessage(request);
88+
String msgId = response.getMsgId();
89+
String sessionId = response.getSessionId();
90+
```
91+
92+
### 接收用户消息
93+
94+
当用户向智能机器人发送消息时,企业微信会通过回调接口推送消息。可以使用 `WxCpXmlMessage` 接收和解析这些消息:
95+
96+
```java
97+
// 在接收回调消息的接口中
98+
WxCpXmlMessage message = WxCpXmlMessage.fromEncryptedXml(
99+
requestBody, wxCpConfigStorage, timestamp, nonce, msgSignature
100+
);
101+
102+
// 获取智能机器人相关字段
103+
String robotId = message.getRobotId(); // 机器人ID
104+
String sessionId = message.getSessionId(); // 会话ID
105+
String content = message.getContent(); // 消息内容
106+
String fromUser = message.getFromUserName(); // 发送用户
107+
108+
// 处理消息并回复
109+
// ...
110+
```
111+
76112
### 删除智能机器人
77113

78114
```java
@@ -87,13 +123,19 @@ robotService.deleteRobot(robotId);
87123
- `WxCpIntelligentRobotCreateRequest`: 创建机器人请求
88124
- `WxCpIntelligentRobotUpdateRequest`: 更新机器人请求
89125
- `WxCpIntelligentRobotChatRequest`: 智能对话请求
126+
- `WxCpIntelligentRobotSendMessageRequest`: 主动发送消息请求
90127

91128
### 响应类
92129

93130
- `WxCpIntelligentRobotCreateResponse`: 创建机器人响应
94131
- `WxCpIntelligentRobotChatResponse`: 智能对话响应
132+
- `WxCpIntelligentRobotSendMessageResponse`: 主动发送消息响应
95133
- `WxCpIntelligentRobot`: 机器人信息实体
96134

135+
### 消息接收
136+
137+
- `WxCpXmlMessage`: 支持接收智能机器人回调消息,包含 `robotId``sessionId` 字段
138+
97139
### 服务接口
98140

99141
- `WxCpIntelligentRobotService`: 智能机器人服务接口

weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpIntelligentRobotService.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,4 +64,14 @@ public interface WxCpIntelligentRobotService {
6464
*/
6565
void resetSession(String robotId, String userid, String sessionId) throws WxErrorException;
6666

67+
/**
68+
* 智能机器人主动发送消息
69+
* 官方文档: https://developer.work.weixin.qq.com/document/path/100719
70+
*
71+
* @param request 发送消息请求参数
72+
* @return 发送消息响应
73+
* @throws WxErrorException 微信接口异常
74+
*/
75+
WxCpIntelligentRobotSendMessageResponse sendMessage(WxCpIntelligentRobotSendMessageRequest request) throws WxErrorException;
76+
6777
}

weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpIntelligentRobotServiceImpl.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,4 +61,10 @@ public void resetSession(String robotId, String userid, String sessionId) throws
6161
this.cpService.post(RESET_SESSION, jsonObject.toString());
6262
}
6363

64+
@Override
65+
public WxCpIntelligentRobotSendMessageResponse sendMessage(WxCpIntelligentRobotSendMessageRequest request) throws WxErrorException {
66+
String responseText = this.cpService.post(SEND_MESSAGE, request.toJson());
67+
return WxCpIntelligentRobotSendMessageResponse.fromJson(responseText);
68+
}
69+
6470
}
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
package me.chanjar.weixin.cp.bean.intelligentrobot;
2+
3+
import com.google.gson.annotations.SerializedName;
4+
import lombok.Data;
5+
import me.chanjar.weixin.cp.util.json.WxCpGsonBuilder;
6+
7+
import java.io.Serializable;
8+
9+
/**
10+
* 智能机器人发送消息请求
11+
* 官方文档: https://developer.work.weixin.qq.com/document/path/100719
12+
*
13+
* @author Binary Wang
14+
*/
15+
@Data
16+
public class WxCpIntelligentRobotSendMessageRequest implements Serializable {
17+
private static final long serialVersionUID = -1L;
18+
19+
/**
20+
* 机器人ID,必填
21+
*/
22+
@SerializedName("robot_id")
23+
private String robotId;
24+
25+
/**
26+
* 接收消息的用户ID,必填
27+
*/
28+
@SerializedName("userid")
29+
private String userid;
30+
31+
/**
32+
* 消息内容,必填
33+
*/
34+
@SerializedName("message")
35+
private String message;
36+
37+
/**
38+
* 会话ID,可选,用于保持会话连续性
39+
*/
40+
@SerializedName("session_id")
41+
private String sessionId;
42+
43+
/**
44+
* 消息ID,可选
45+
*/
46+
@SerializedName("msg_id")
47+
private String msgId;
48+
49+
public String toJson() {
50+
return WxCpGsonBuilder.create().toJson(this);
51+
}
52+
53+
public static WxCpIntelligentRobotSendMessageRequest fromJson(String json) {
54+
return WxCpGsonBuilder.create().fromJson(json, WxCpIntelligentRobotSendMessageRequest.class);
55+
}
56+
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
package me.chanjar.weixin.cp.bean.intelligentrobot;
2+
3+
import com.google.gson.annotations.SerializedName;
4+
import lombok.Data;
5+
import lombok.EqualsAndHashCode;
6+
import me.chanjar.weixin.cp.bean.WxCpBaseResp;
7+
import me.chanjar.weixin.cp.util.json.WxCpGsonBuilder;
8+
9+
import java.io.Serializable;
10+
11+
/**
12+
* 智能机器人发送消息响应
13+
* 官方文档: https://developer.work.weixin.qq.com/document/path/100719
14+
*
15+
* @author Binary Wang
16+
*/
17+
@Data
18+
@EqualsAndHashCode(callSuper = true)
19+
public class WxCpIntelligentRobotSendMessageResponse extends WxCpBaseResp implements Serializable {
20+
private static final long serialVersionUID = -1L;
21+
22+
/**
23+
* 消息ID
24+
*/
25+
@SerializedName("msg_id")
26+
private String msgId;
27+
28+
/**
29+
* 会话ID
30+
*/
31+
@SerializedName("session_id")
32+
private String sessionId;
33+
34+
public static WxCpIntelligentRobotSendMessageResponse fromJson(String json) {
35+
return WxCpGsonBuilder.create().fromJson(json, WxCpIntelligentRobotSendMessageResponse.class);
36+
}
37+
38+
@Override
39+
public String toJson() {
40+
return WxCpGsonBuilder.create().toJson(this);
41+
}
42+
}

weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/message/WxCpXmlMessage.java

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -253,6 +253,24 @@ public class WxCpXmlMessage implements Serializable {
253253
@XStreamConverter(value = XStreamCDataConverter.class)
254254
private String linkId;
255255

256+
/**
257+
* 智能机器人ID
258+
* 接收智能机器人消息时使用
259+
* https://developer.work.weixin.qq.com/document/path/100719
260+
*/
261+
@XStreamAlias("RobotId")
262+
@XStreamConverter(value = XStreamCDataConverter.class)
263+
private String robotId;
264+
265+
/**
266+
* 智能机器人会话ID
267+
* 接收智能机器人消息时使用,用于保持会话连续性
268+
* https://developer.work.weixin.qq.com/document/path/100719
269+
*/
270+
@XStreamAlias("SessionId")
271+
@XStreamConverter(value = XStreamCDataConverter.class)
272+
private String sessionId;
273+
256274
/**
257275
* 通讯录变更事件.
258276
* 请参考常量 me.chanjar.weixin.cp.constant.WxCpConsts.ContactChangeType

weixin-java-cp/src/main/java/me/chanjar/weixin/cp/constant/WxCpApiPathConsts.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1666,5 +1666,11 @@ interface IntelligentRobot {
16661666
* 重置智能机器人会话
16671667
*/
16681668
String RESET_SESSION = "/cgi-bin/intelligent_robot/reset_session";
1669+
1670+
/**
1671+
* 智能机器人主动发送消息
1672+
* 官方文档: https://developer.work.weixin.qq.com/document/path/100719
1673+
*/
1674+
String SEND_MESSAGE = "/cgi-bin/intelligent_robot/send_message";
16691675
}
16701676
}

weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/impl/WxCpIntelligentRobotServiceImplTest.java

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,4 +85,38 @@ public void testServiceIntegration() {
8585
assert this.wxCpService.getIntelligentRobotService() != null;
8686
assert this.wxCpService.getIntelligentRobotService() instanceof WxCpIntelligentRobotServiceImpl;
8787
}
88+
89+
@Test
90+
public void testSendMessageRequest() {
91+
// 测试主动发送消息请求对象创建
92+
WxCpIntelligentRobotSendMessageRequest request = new WxCpIntelligentRobotSendMessageRequest();
93+
request.setRobotId("robot123");
94+
request.setUserid("user123");
95+
request.setMessage("您好,这是来自智能机器人的主动消息");
96+
request.setSessionId("session123");
97+
request.setMsgId("msg123");
98+
99+
// 验证JSON序列化
100+
String json = request.toJson();
101+
assert json.contains("robot123");
102+
assert json.contains("您好,这是来自智能机器人的主动消息");
103+
assert json.contains("session123");
104+
105+
// 验证反序列化
106+
WxCpIntelligentRobotSendMessageRequest fromJson = WxCpIntelligentRobotSendMessageRequest.fromJson(json);
107+
assert fromJson.getRobotId().equals("robot123");
108+
assert fromJson.getMessage().equals("您好,这是来自智能机器人的主动消息");
109+
assert fromJson.getSessionId().equals("session123");
110+
}
111+
112+
@Test
113+
public void testSendMessageResponse() {
114+
// 测试主动发送消息响应对象
115+
String responseJson = "{\"errcode\":0,\"errmsg\":\"ok\",\"msg_id\":\"msg123\",\"session_id\":\"session123\"}";
116+
WxCpIntelligentRobotSendMessageResponse response = WxCpIntelligentRobotSendMessageResponse.fromJson(responseJson);
117+
118+
assert response.getMsgId().equals("msg123");
119+
assert response.getSessionId().equals("session123");
120+
assert response.getErrcode() == 0;
121+
}
88122
}

weixin-java-cp/src/test/java/me/chanjar/weixin/cp/bean/message/WxCpXmlMessageTest.java

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -471,4 +471,30 @@ public void testMsgIdStringAndNumericFormats() {
471471
WxCpXmlMessage wxMessageString = WxCpXmlMessage.fromXml(xmlWithString);
472472
assertEquals(wxMessageString.getMsgId(), "CAIQg/PKxgYY2sC9tpuAgAMg9/zKaw==");
473473
}
474+
475+
/**
476+
* Test intelligent robot message parsing
477+
* 测试智能机器人消息解析
478+
*/
479+
public void testIntelligentRobotMessage() {
480+
String xml = "<xml>"
481+
+ "<ToUserName><![CDATA[toUser]]></ToUserName>"
482+
+ "<FromUserName><![CDATA[fromUser]]></FromUserName>"
483+
+ "<CreateTime>1348831860</CreateTime>"
484+
+ "<MsgType><![CDATA[text]]></MsgType>"
485+
+ "<Content><![CDATA[你好,智能机器人]]></Content>"
486+
+ "<MsgId>msg123456</MsgId>"
487+
+ "<RobotId><![CDATA[robot_id_123]]></RobotId>"
488+
+ "<SessionId><![CDATA[session_id_456]]></SessionId>"
489+
+ "</xml>";
490+
WxCpXmlMessage wxMessage = WxCpXmlMessage.fromXml(xml);
491+
assertEquals(wxMessage.getToUserName(), "toUser");
492+
assertEquals(wxMessage.getFromUserName(), "fromUser");
493+
assertEquals(wxMessage.getCreateTime(), Long.valueOf(1348831860));
494+
assertEquals(wxMessage.getMsgType(), WxConsts.XmlMsgType.TEXT);
495+
assertEquals(wxMessage.getContent(), "你好,智能机器人");
496+
assertEquals(wxMessage.getMsgId(), "msg123456");
497+
assertEquals(wxMessage.getRobotId(), "robot_id_123");
498+
assertEquals(wxMessage.getSessionId(), "session_id_456");
499+
}
474500
}

0 commit comments

Comments
 (0)