Skip to main content

basic_usage/
basic_usage.rs

1use std::sync::Arc;
2
3use log::{LevelFilter, error, info};
4use milky_rust_sdk::prelude::*;
5use milky_rust_sdk::utils::get_plain_text_from_segments;
6use milky_rust_sdk::{Communication, MilkyClient, Result};
7use milky_rust_sdk::{WebSocketConfig, logger};
8use tokio::sync::mpsc;
9
10// 辅助函数,用于创建文本消息段
11fn text_segment(text: &str) -> OutgoingSegment {
12    OutgoingSegment::Text(TextData {
13        text: text.to_string(),
14    })
15}
16
17#[tokio::main]
18async fn main() -> Result<()> {
19    logger::init_logger(Some(LevelFilter::Info)); // 初始化日志
20
21    // 创建事件通道
22    let (event_tx, mut event_rx) = mpsc::channel::<Event>(100);
23
24    // 初始化 MilkyClient
25    // 示例中使用的是WebSocket的通信方式,如果你想通过WebHook方式与服务端通信,可以参考下面的代码
26    // let wh_config = WebHookConfig::new(None, 8080, "http://127.0.0.1:3000".to_string(), None);
27    // let client = MilkyClient::new(Communication::WebHook(wh_config), event_tx)?;
28    let ws_config = WebSocketConfig::new("ws://127.0.0.1:3002".to_string(), None);
29    let client = MilkyClient::new(Communication::WebSocket(ws_config), event_tx)?;
30    let client = Arc::new(client);
31
32    // 连接到件流
33    if let Err(e) = client.connect_events().await {
34        error!("未能连接到事件流: {e:?}");
35        return Err(e);
36    }
37    info!("成功连接到 Milky 服务器事件流。");
38
39    // 启动一个异步任务来处理接收到的事件
40    let client_for_task = Arc::clone(&client);
41    let _event_handle = tokio::spawn(async move {
42        info!("事件监听器已启动。");
43        while let Some(event) = event_rx.recv().await {
44            info!("收到事件: {event:?}",); // 打印原始事件
45
46            match event.kind {
47                EventKind::MessageReceive {
48                    message: message_event,
49                } => {
50                    match message_event {
51                        MessageEvent::Friend(friend_msg) => {
52                            let plain_text = get_plain_text_from_segments(&friend_msg.message.segments);
53                            info!(
54                                "收到好友消息: {} (QQ: {}) - {}",
55                                friend_msg.friend.remark,
56                                friend_msg.message.sender_id,
57                                plain_text
58                            );
59
60                            // 示例:复读
61                            if plain_text.starts_with("/echo") {
62                                let reply_segments =
63                                    vec![text_segment(plain_text.replace("/echo", "").trim())];
64                                match client_for_task
65                                    .send_private_message(friend_msg.message.sender_id, reply_segments)
66                                    .await
67                                {
68                                    Ok(resp) => info!("自动回复成功: seq={}", resp.message_seq),
69                                    Err(e) => error!("自动回复失败: {e:?}",),
70                                }
71                            }
72                        }
73                        MessageEvent::Group(group_msg) => {
74                            let plain_text = get_plain_text_from_segments(&group_msg.message.segments);
75                            info!(
76                                "收到群消息: [{}] {} (QQ: {}) - {}",
77                                group_msg.group.group_name,
78                                group_msg.group_member.card,
79                                group_msg.message.sender_id,
80                                plain_text
81                            );
82                        }
83                        MessageEvent::Temp(temp_msg) => {
84                            let plain_text = get_plain_text_from_segments(&temp_msg.message.segments);
85                            info!(
86                                "收到临时消息: QQ: {} - {}",
87                                temp_msg.message.sender_id,
88                                plain_text
89                            );
90                        }
91                    }
92                }
93                EventKind::GroupMemberIncrease {
94                    group_id, user_id, ..
95                } => {
96                    info!("群 {} 新成员加入: {}", group_id, user_id);
97                }
98                // ... 处理其他事件类型
99                _ => {}
100            }
101        }
102        info!("事件监听器已停止。");
103    });
104
105    // 等待连接稳定和事件监听器启动
106    tokio::time::sleep(std::time::Duration::from_secs(2)).await;
107
108    // 调用 API 示例
109    // 获取登录信息
110    match client.get_login_info().await {
111        Ok(login_info) => {
112            info!(
113                "登录信息: QQ={}, 昵称='{}'",
114                login_info.uin, login_info.nickname
115            );
116        }
117        Err(e) => {
118            error!("未能获取登录信息: {e:?}",);
119        }
120    }
121
122    // 发送私聊消息 (请替换为有效的 user_id)
123    let user_id_to_send: i64 = 123456789; // 示例QQ号
124    let message_to_send = vec![text_segment("你好,这是一个来自 Vivian SDK 的测试消息!")];
125    match client
126        .send_private_message(user_id_to_send, message_to_send)
127        .await
128    {
129        Ok(response) => {
130            info!(
131                "私聊消息成功发送至 {}: message_seq={}",
132                user_id_to_send, response.message_seq
133            );
134        }
135        Err(e) => {
136            error!("未能发送私聊消息至 {user_id_to_send}: {e:?}");
137        }
138    }
139
140    // 保持主程序运行以处理事件。
141    info!("示例正在运行。按 Ctrl-C 退出。");
142    tokio::signal::ctrl_c().await?; // 等待 Ctrl-C信号
143    info!("收到 Ctrl-C,正在关闭...");
144    client.shutdown().await;
145    // 可以选择性地等待一小段时间,以确保关闭消息被处理
146    tokio::time::sleep(std::time::Duration::from_millis(250)).await;
147
148    Ok(())
149}