1use super::{Anonymous, Sender};
2use crate::event::{MsgEvent, PostType, RepliableEvent};
3use crate::message_trait::MessageRegistrar as _;
4use crate::onebot_message::OneBotMessage;
5use kovi::bot::runtimebot::{CanSendApi, send_api_request_with_forget};
6use kovi::bot::{BotInformation, SendApi};
7use kovi::error::EventBuildError;
8use kovi::event::{Event, InternalEvent};
9use kovi::message::Message as KoviMessage;
10use kovi::types::ApiAndOptOneshot;
11use log::info;
12use serde::Serialize;
13use serde_json::value::Index;
14use serde_json::{self, Value, json};
15use tokio::sync::mpsc;
16
17#[derive(Debug, Clone)]
18pub struct GroupMsgEvent {
19 pub time: i64,
21 pub self_id: i64,
23 pub post_type: PostType,
25 pub message_type: String,
27 pub sub_type: String,
29 pub message: KoviMessage,
31 pub message_id: i32,
33 pub group_id: i64,
35 pub user_id: i64,
37 pub anonymous: Option<Anonymous>,
39 pub raw_message: String,
41 pub font: i32,
43 pub sender: Sender,
45
46 pub text: Option<String>,
48 pub human_text: String,
50 pub original_json: Value,
52
53 pub api_tx: mpsc::Sender<ApiAndOptOneshot>,
55}
56
57impl Event for GroupMsgEvent {
58 fn de(
59 event: &InternalEvent,
60 _: &BotInformation,
61 api_tx: &mpsc::Sender<ApiAndOptOneshot>,
62 ) -> Option<Self> {
63 let InternalEvent::DriverEvent(json) = event else {
64 return None;
65 };
66 let event = Self::new(api_tx.clone(), json.clone()).ok()?;
67
68 Some(event)
69 }
70}
71
72impl GroupMsgEvent {
73 fn new(
74 api_tx: mpsc::Sender<ApiAndOptOneshot>,
75 json: Value,
76 ) -> Result<GroupMsgEvent, EventBuildError> {
77 let msg_event = MsgEvent::new(api_tx, json)?;
78
79 Ok(GroupMsgEvent {
80 time: msg_event.time,
81 self_id: msg_event.self_id,
82 post_type: msg_event.post_type,
83 message_type: msg_event.message_type,
84 sub_type: msg_event.sub_type,
85 message: msg_event.message,
86 message_id: msg_event.message_id,
87 group_id: match msg_event.group_id {
88 Some(id) => id,
89 None => {
90 return Err(EventBuildError::ParseError(
91 "group_id unreachable".to_string(),
92 ));
93 }
94 },
95 user_id: msg_event.user_id,
96 anonymous: msg_event.anonymous,
97 raw_message: msg_event.raw_message,
98 font: msg_event.font,
99 sender: msg_event.sender,
100 text: msg_event.text,
101 human_text: msg_event.human_text,
102 original_json: msg_event.original_json,
103 api_tx: msg_event.api_tx,
104 })
105 }
106}
107
108impl GroupMsgEvent {
109 pub fn get<I: Index>(&self, index: I) -> Option<&Value> {
123 self.original_json.get(index)
124 }
125}
126
127impl<I> std::ops::Index<I> for GroupMsgEvent
128where
129 I: Index,
130{
131 type Output = Value;
132
133 fn index(&self, index: I) -> &Self::Output {
134 &self.original_json[index]
135 }
136}
137
138impl GroupMsgEvent {
139 fn reply_builder<M>(&self, msg: M, auto_escape: bool) -> SendApi
140 where
141 M: Into<OneBotMessage>,
142 {
143 RepliableEvent::reply_builder(self, msg, auto_escape)
144 }
145
146 #[cfg(not(feature = "cqstring"))]
147 pub fn reply<T>(&self, msg: T)
148 where
149 KoviMessage: From<T>,
150 T: Serialize,
151 {
152 RepliableEvent::reply(self, msg)
153 }
154
155 #[cfg(feature = "cqstring")]
156 pub fn reply<T>(&self, msg: T)
157 where
158 CQMessage: From<T>,
159 T: Serialize,
160 {
161 RepliableEvent::reply(self, msg)
162 }
163
164 #[cfg(not(feature = "cqstring"))]
165 pub fn reply_and_quote<T>(&self, msg: T)
166 where
167 KoviMessage: From<T>,
168 T: Serialize,
169 {
170 RepliableEvent::reply_and_quote(self, msg);
171 }
172
173 #[cfg(feature = "cqstring")]
174 fn reply_and_quote<T>(&self, msg: T)
175 where
176 CQMessage: From<T>,
177 T: Serialize,
178 {
179 RepliableEvent::reply_and_quote(self, msg);
180 }
181
182 #[cfg(feature = "cqstring")]
183 fn reply_text<T>(&self, msg: T)
184 where
185 String: From<T>,
186 T: Serialize,
187 {
188 RepliableEvent::reply_text(self, msg)
189 }
190
191 pub fn get_text(&self) -> String {
192 RepliableEvent::get_text(self)
193 }
194
195 pub fn get_sender_nickname(&self) -> String {
196 RepliableEvent::get_sender_nickname(self)
197 }
198
199 pub fn borrow_text(&self) -> Option<&str> {
200 RepliableEvent::borrow_text(self)
201 }
202}
203
204impl RepliableEvent for GroupMsgEvent {
205 fn reply_builder<M>(&self, msg: M, auto_escape: bool) -> SendApi
206 where
207 M: Into<OneBotMessage>,
208 {
209 let msg = msg.into();
210 SendApi::new(
211 "send_msg",
212 json!({
213 "message_type":"group",
214 "group_id":self.group_id,
215 "message":msg,
216 "auto_escape":auto_escape,
217 }),
218 )
219 }
220
221 #[cfg(not(feature = "cqstring"))]
222 fn reply<T>(&self, msg: T)
224 where
225 KoviMessage: From<T>,
226 T: Serialize,
227 {
228 let msg = KoviMessage::from(msg);
229 let nickname = self.get_sender_nickname();
230 let id = &self.sender.user_id;
231 let message_type = &self.message_type;
232 let group_id = &self.group_id;
233 let human_msg = msg.to_human_string();
234 info!("[reply] [to {message_type} {group_id} {nickname} {id}]: {human_msg}");
235
236 let send_msg = self.reply_builder(msg, false);
237 send_api_request_with_forget(&self.api_tx, send_msg)
238 }
239
240 #[cfg(feature = "cqstring")]
241 fn reply<T>(&self, msg: T)
243 where
244 CQMessage: From<T>,
245 T: Serialize,
246 {
247 let msg = CQMessage::from(msg);
248 let send_msg = self.reply_builder(&msg, false);
249 let nickname = self.get_sender_nickname();
250 let id = &self.sender.user_id;
251 let message_type = &self.message_type;
252 let group_id = &self.group_id;
253 let human_msg = Message::from(msg).to_human_string();
254 info!("[reply] [to {message_type} {group_id} {nickname} {id}]: {human_msg}");
255 send_api_request_with_forget(&self.api_tx, send_msg);
256 }
257
258 #[cfg(not(feature = "cqstring"))]
259 fn reply_and_quote<T>(&self, msg: T)
261 where
262 KoviMessage: From<T>,
263 T: Serialize,
264 {
265 let msg = KoviMessage::from(msg).add_reply(self.message_id);
266 let nickname = self.get_sender_nickname();
267 let id = &self.sender.user_id;
268 let message_type = &self.message_type;
269 let group_id = &self.group_id;
270 let human_msg = msg.to_human_string();
271 info!("[reply] [to {message_type} {group_id} {nickname} {id}]: {human_msg}");
272
273 let send_msg = self.reply_builder(msg, false);
274 send_api_request_with_forget(&self.api_tx, send_msg);
275 }
276
277 #[cfg(feature = "cqstring")]
278 fn reply_and_quote<T>(&self, msg: T)
280 where
281 CQMessage: From<T>,
282 T: Serialize,
283 {
284 let msg = CQMessage::from(msg).add_reply(self.message_id);
285 let send_msg = self.reply_builder(&msg, false);
286 let nickname = self.get_sender_nickname();
287 let id = &self.sender.user_id;
288 let message_type = &self.message_type;
289 let group_id = &self.group_id;
290 let human_msg = Message::from(msg).to_human_string();
291 info!("[reply] [to {message_type} {group_id} {nickname} {id}]: {human_msg}");
292 send_api_request_with_forget(&self.api_tx, send_msg);
293 }
294
295 #[cfg(feature = "cqstring")]
296 fn reply_text<T>(&self, msg: T)
298 where
299 String: From<T>,
300 T: Serialize,
301 {
302 let send_msg = self.reply_builder(&msg, true);
303 let nickname = self.get_sender_nickname();
304 let id = &self.sender.user_id;
305 let message_type = &self.message_type;
306 let group_id = &self.group_id;
307 let msg = String::from(msg);
308 info!("[reply] [to {message_type} {group_id} {nickname} {id}]: {msg}");
309 send_api_request_with_forget(&self.api_tx, send_msg);
310 }
311
312 fn get_text(&self) -> String {
314 match self.text.clone() {
315 Some(v) => v,
316 None => "".to_string(),
317 }
318 }
319
320 fn get_sender_nickname(&self) -> String {
322 if let Some(v) = &self.sender.nickname {
323 v.clone()
324 } else {
325 "".to_string()
326 }
327 }
328
329 fn borrow_text(&self) -> Option<&str> {
331 self.text.as_deref()
332 }
333}
334
335impl CanSendApi for GroupMsgEvent {
336 fn __get_api_tx(&self) -> &tokio::sync::mpsc::Sender<kovi::types::ApiAndOptOneshot> {
337 &self.api_tx
338 }
339}