Skip to content

Commit c1ff6cb

Browse files
committed
🐛 fix: correct message_read_v1 event data structure
Fix WebSocket message_read_v1 event deserialization error by updating data structure to match actual Feishu API format: - Replace sender/message fields with reader/message_id_list - Add EventReader struct with read_time, reader_id, tenant_key - Update websocket_client.rs example to use corrected field names - Transform websocket_client.rs into echo server with enhanced logging Resolves "missing field 'sender'" error in WebSocket event handling.
1 parent 216d524 commit c1ff6cb

File tree

2 files changed

+104
-19
lines changed

2 files changed

+104
-19
lines changed

examples/basic/websocket_client.rs

Lines changed: 87 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,19 @@ use open_lark::prelude::*;
55
async fn main() -> Result<(), Box<dyn std::error::Error>> {
66
// 初始化环境变量和日志
77
dotenvy::dotenv().ok();
8+
9+
// 设置日志级别以获取更详细的调试信息
10+
if std::env::var("RUST_LOG").is_err() {
11+
std::env::set_var("RUST_LOG", "debug");
12+
}
13+
814
env_logger::init();
915

1016
let app_id = std::env::var("APP_ID").expect("APP_ID environment variable not set");
1117
let app_secret = std::env::var("APP_SECRET").expect("APP_SECRET environment variable not set");
1218

13-
println!("🔌 WebSocket Client Example");
19+
println!("🔌 WebSocket Echo Server Example");
20+
println!("该示例演示一个简单的 Echo Server,将收到的消息原样返回给发送者");
1421
println!("Note: WebSocket features require the 'websocket' feature flag");
1522

1623
#[cfg(not(feature = "websocket"))]
@@ -38,19 +45,79 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
3845
.with_enable_token_cache(true)
3946
.build();
4047

41-
let config = Arc::new(client.config);
48+
let client_for_echo = Arc::new(client);
49+
let config = Arc::new(client_for_echo.config.clone());
4250

43-
// 创建事件处理器
51+
// 创建事件处理器,实现 echo server 功能
52+
let echo_client = client_for_echo.clone();
4453
let event_handler = match EventDispatcherHandler::builder()
45-
.register_p2_im_message_receive_v1(|event| {
46-
info!("📩 收到消息事件: {event:?}");
47-
println!("📩 收到新消息:");
48-
println!(" - 消息ID: {:?}", event.header.event_id);
49-
println!(" - 消息类型: {:?}", event.event.message.message_type);
50-
if !event.event.message.content.is_empty() {
51-
println!(" - 消息内容: {}", &event.event.message.content);
52-
}
53-
println!(" - 发送者: {:?}", event.event.sender);
54+
.register_p2_im_message_receive_v1(move |event| {
55+
let client = echo_client.clone();
56+
tokio::spawn(async move {
57+
println!("📩 收到消息接收事件:");
58+
println!(" - 事件ID: {:?}", event.header.event_id);
59+
println!(" - 消息ID: {:?}", event.event.message.message_id);
60+
println!(" - 消息类型: {:?}", event.event.message.message_type);
61+
println!(" - 发送者: {:?}", event.event.sender.sender_id.open_id);
62+
63+
if !event.event.message.content.is_empty() {
64+
println!(" - 消息内容: {}", &event.event.message.content);
65+
66+
// Echo server 逻辑:解析消息内容并回显
67+
if let Ok(content_json) =
68+
serde_json::from_str::<serde_json::Value>(&event.event.message.content)
69+
{
70+
if let Some(text) = content_json.get("text").and_then(|v| v.as_str()) {
71+
let echo_content = format!("Echo: {text}");
72+
println!("🔄 正在发送回显消息: {echo_content}");
73+
74+
// 构建回显消息
75+
let echo_request = CreateMessageRequest::builder()
76+
.receive_id_type("open_id")
77+
.request_body(
78+
CreateMessageRequestBody::builder()
79+
.receive_id(&event.event.sender.sender_id.open_id)
80+
.msg_type("text")
81+
.content(format!("{{\"text\":\"{echo_content}\"}}"))
82+
.build(),
83+
)
84+
.build();
85+
86+
// 发送回显消息
87+
match client.im.v1.message.create(echo_request, None).await {
88+
Ok(_) => {
89+
println!("✅ Echo 消息发送成功: {echo_content}");
90+
}
91+
Err(e) => {
92+
eprintln!("❌ Echo 消息发送失败: {e:?}");
93+
}
94+
}
95+
} else {
96+
println!(" - 非文本消息,跳过回显");
97+
}
98+
} else {
99+
println!(" - 无法解析消息内容");
100+
}
101+
} else {
102+
println!(" - 空消息内容");
103+
}
104+
105+
info!("📩 消息接收事件处理完成");
106+
});
107+
})
108+
.and_then(|builder| {
109+
builder.register_p2_im_message_read_v1(|event| {
110+
tokio::spawn(async move {
111+
println!("👁️ 收到消息已读事件:");
112+
println!(" - 事件ID: {:?}", event.header.event_id);
113+
println!(" - 阅读者: {:?}", event.event.reader.reader_id.open_id);
114+
println!(" - 阅读时间: {}", event.event.reader.read_time);
115+
println!(" - 已读消息ID列表: {:?}", event.event.message_id_list);
116+
println!(" - 租户: {}", event.event.reader.tenant_key);
117+
118+
info!("👁️ 消息已读事件处理完成");
119+
});
120+
})
54121
}) {
55122
Ok(builder) => builder.build(),
56123
Err(e) => {
@@ -60,8 +127,13 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
60127
};
61128

62129
println!("📡 事件处理器已注册,支持的事件类型:");
63-
println!(" - 消息接收事件 (im.message.receive_v1)");
64-
println!(" - 消息已读事件 (im.message.message_read_v1)");
130+
println!(" - 消息接收事件 (im.message.receive_v1) - 支持文本消息回显");
131+
println!(" - 消息已读事件 (im.message.message_read_v1) - 显示消息阅读状态");
132+
133+
println!("\n💡 使用提示:");
134+
println!(" - 向机器人发送文本消息将收到 'Echo: [消息内容]' 的回复");
135+
println!(" - 消息阅读状态会实时显示在控制台");
136+
println!(" - 如果遇到解析错误,请检查事件数据结构是否匹配");
65137

66138
println!("\n🚀 启动 WebSocket 连接...");
67139

@@ -71,7 +143,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
71143
return Err(format!("WebSocket connection failed: {e:?}").into());
72144
}
73145

74-
println!("✅ WebSocket 连接已建立并正常运行");
146+
println!("✅ Echo Server 已启动并正常运行,等待接收消息...");
75147
}
76148

77149
Ok(())

src/service/im/v1/p2_im_message_read_v1.rs

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use serde::{Deserialize, Serialize};
22

33
use crate::{
44
event::{context::EventHeader, dispatcher::EventHandler},
5-
service::im::v1::p2_im_message_receive_v1::{EventMessage, EventSender},
5+
service::im::v1::p2_im_message_receive_v1::UserId,
66
};
77

88
#[derive(Debug, Serialize, Deserialize)]
@@ -12,11 +12,24 @@ pub struct P2ImMessageReadV1 {
1212
pub event: P2ImMessageMessageReadV1Data,
1313
}
1414

15-
/// 事件
15+
/// 消息已读事件数据
1616
#[derive(Debug, Serialize, Deserialize)]
1717
pub struct P2ImMessageMessageReadV1Data {
18-
pub sender: EventSender,
19-
pub message: EventMessage,
18+
/// 消息阅读者信息
19+
pub reader: EventReader,
20+
/// 已读消息ID列表
21+
pub message_id_list: Vec<String>,
22+
}
23+
24+
/// 消息阅读者信息
25+
#[derive(Debug, Serialize, Deserialize)]
26+
pub struct EventReader {
27+
/// 阅读时间戳(毫秒)
28+
pub read_time: String,
29+
/// 阅读者ID信息
30+
pub reader_id: UserId,
31+
/// tenant key,为租户在飞书上的唯一标识
32+
pub tenant_key: String,
2033
}
2134

2235
pub struct P2ImMessageReadV1ProcessorImpl<F>

0 commit comments

Comments
 (0)