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