1use super::{Anonymous, Sender};
2use crate::event::{MsgEvent, PostType, RepliableEvent, UniversalMessage};
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};
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 AdminMsgEvent {
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: Option<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 AdminMsgEvent {
59 fn de(
60 event: &InternalEvent,
61 bot_info: &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 if !bot_info.any_admins_contains(RefID::new(&event.sender.user_id)) {
70 return None;
71 }
72
73 Some(event)
74 }
75}
76
77impl AdminMsgEvent {
78 fn new(
79 api_tx: mpsc::Sender<ApiAndOptOneshot>,
80 json: Value,
81 ) -> Result<AdminMsgEvent, EventBuildError> {
82 let msg_event = MsgEvent::new(api_tx, json)?;
83
84 Ok(AdminMsgEvent {
85 time: msg_event.time,
86 self_id: msg_event.self_id,
87 post_type: msg_event.post_type,
88 message_type: msg_event.message_type,
89 sub_type: msg_event.sub_type,
90 message: msg_event.message,
91 message_id: msg_event.message_id,
92 group_id: msg_event.group_id,
93 user_id: msg_event.user_id,
94 anonymous: msg_event.anonymous,
95 raw_message: msg_event.raw_message,
96 font: msg_event.font,
97 sender: msg_event.sender,
98 text: msg_event.text,
99 human_text: msg_event.human_text,
100 original_json: msg_event.original_json,
101 api_tx: msg_event.api_tx,
102 })
103 }
104}
105
106impl AdminMsgEvent {
107 pub fn get<I: Index>(&self, index: I) -> Option<&Value> {
121 self.original_json.get(index)
122 }
123}
124
125impl<I> std::ops::Index<I> for AdminMsgEvent
126where
127 I: Index,
128{
129 type Output = Value;
130
131 fn index(&self, index: I) -> &Self::Output {
132 &self.original_json[index]
133 }
134}
135
136impl AdminMsgEvent {
137 fn reply_builder<M>(&self, msg: M, auto_escape: bool) -> SendApi
138 where
139 M: Into<OneBotMessage>,
140 {
141 RepliableEvent::reply_builder(self, msg, auto_escape)
142 }
143
144 #[cfg(not(feature = "cqstring"))]
145 pub fn reply<T>(&self, msg: T)
146 where
147 KoviMessage: From<T>,
148 T: Serialize,
149 {
150 RepliableEvent::reply(self, msg)
151 }
152
153 #[cfg(feature = "cqstring")]
154 pub fn reply<T>(&self, msg: T)
155 where
156 CQMessage: From<T>,
157 T: Serialize,
158 {
159 RepliableEvent::reply(self, msg)
160 }
161
162 #[cfg(not(feature = "cqstring"))]
163 pub fn reply_and_quote<T>(&self, msg: T)
164 where
165 KoviMessage: From<T>,
166 T: Serialize,
167 {
168 RepliableEvent::reply_and_quote(self, msg);
169 }
170
171 #[cfg(feature = "cqstring")]
172 fn reply_and_quote<T>(&self, msg: T)
173 where
174 CQMessage: From<T>,
175 T: Serialize,
176 {
177 RepliableEvent::reply_and_quote(self, msg);
178 }
179
180 #[cfg(feature = "cqstring")]
181 fn reply_text<T>(&self, msg: T)
182 where
183 String: From<T>,
184 T: Serialize,
185 {
186 RepliableEvent::reply_text(self, msg)
187 }
188
189 pub fn get_text(&self) -> String {
190 RepliableEvent::get_text(self)
191 }
192
193 pub fn get_sender_nickname(&self) -> String {
194 RepliableEvent::get_sender_nickname(self)
195 }
196
197 pub fn borrow_text(&self) -> Option<&str> {
198 RepliableEvent::borrow_text(self)
199 }
200
201 pub fn is_group(&self) -> bool {
202 UniversalMessage::is_group(self)
203 }
204
205 pub fn is_private(&self) -> bool {
206 UniversalMessage::is_private(self)
207 }
208}
209
210impl UniversalMessage for AdminMsgEvent {
211 fn is_group(&self) -> bool {
212 self.group_id.is_some()
213 }
214
215 fn is_private(&self) -> bool {
216 self.group_id.is_none()
217 }
218}
219
220impl RepliableEvent for AdminMsgEvent {
221 fn reply_builder<M>(&self, msg: M, auto_escape: bool) -> SendApi
222 where
223 M: Into<OneBotMessage>,
224 {
225 let msg = msg.into();
226
227 if self.is_private() {
228 SendApi::new(
229 "send_msg",
230 json!({
231 "message_type":"private",
232 "user_id":self.user_id,
233 "message":msg,
234 "auto_escape":auto_escape,
235 }),
236 )
237 } else {
238 SendApi::new(
239 "send_msg",
240 json!({
241 "message_type":"group",
242 "group_id":self.group_id.expect("unreachable"),
243 "message":msg,
244 "auto_escape":auto_escape,
245 }),
246 )
247 }
248 }
249
250 #[cfg(not(feature = "cqstring"))]
251 fn reply<T>(&self, msg: T)
253 where
254 KoviMessage: From<T>,
255 T: Serialize,
256 {
257 let msg = KoviMessage::from(msg);
258 let mut nickname = self.get_sender_nickname();
259 nickname.insert(0, ' ');
260 let id = &self.sender.user_id;
261 let message_type = &self.message_type;
262 let group_id = match &self.group_id {
263 Some(v) => format!(" {v}"),
264 None => "".to_string(),
265 };
266 let human_msg = msg.to_human_string();
267 info!("[reply] [to {message_type}{group_id}{nickname} {id}]: {human_msg}");
268
269 let send_msg = self.reply_builder(msg, false);
270
271 send_api_request_with_forget(&self.api_tx, send_msg)
272 }
273
274 #[cfg(feature = "cqstring")]
275 fn reply<T>(&self, msg: T)
277 where
278 CQMessage: From<T>,
279 T: Serialize,
280 {
281 let msg = CQMessage::from(msg);
282 let send_msg = self.reply_builder(&msg, false);
283 let mut nickname = self.get_sender_nickname();
284 nickname.insert(0, ' ');
285 let id = &self.sender.user_id;
286 let message_type = &self.message_type;
287 let group_id = match &self.group_id {
288 Some(v) => format!(" {v}"),
289 None => "".to_string(),
290 };
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(not(feature = "cqstring"))]
297 fn reply_and_quote<T>(&self, msg: T)
299 where
300 KoviMessage: From<T>,
301 T: Serialize,
302 {
303 let msg = KoviMessage::from(msg).add_reply(self.message_id);
304 let mut nickname = self.get_sender_nickname();
305 nickname.insert(0, ' ');
306 let id = &self.sender.user_id;
307 let message_type = &self.message_type;
308 let group_id = match &self.group_id {
309 Some(v) => format!(" {v}"),
310 None => "".to_string(),
311 };
312 let human_msg = msg.to_human_string();
313 info!("[reply] [to {message_type}{group_id}{nickname} {id}]: {human_msg}");
314
315 let send_msg = self.reply_builder(msg, false);
316 send_api_request_with_forget(&self.api_tx, send_msg);
317 }
318
319 #[cfg(feature = "cqstring")]
320 fn reply_and_quote<T>(&self, msg: T)
322 where
323 CQMessage: From<T>,
324 T: Serialize,
325 {
326 let msg = CQMessage::from(msg).add_reply(self.message_id);
327 let send_msg = self.reply_builder(&msg, false);
328
329 let mut nickname = self.get_sender_nickname();
330 nickname.insert(0, ' ');
331 let id = &self.sender.user_id;
332 let message_type = &self.message_type;
333 let group_id = match &self.group_id {
334 Some(v) => format!(" {v}"),
335 None => "".to_string(),
336 };
337 let human_msg = Message::from(msg).to_human_string();
338 info!("[reply] [to {message_type}{group_id}{nickname} {id}]: {human_msg}");
339 send_api_request_with_forget(&self.api_tx, send_msg);
340 }
341
342 #[cfg(feature = "cqstring")]
343 fn reply_text<T>(&self, msg: T)
345 where
346 String: From<T>,
347 T: Serialize,
348 {
349 let send_msg = self.reply_builder(&msg, true);
350 let mut nickname = self.get_sender_nickname();
351 nickname.insert(0, ' ');
352 let id = &self.sender.user_id;
353 let message_type = &self.message_type;
354 let group_id = match &self.group_id {
355 Some(v) => format!(" {v}"),
356 None => "".to_string(),
357 };
358 let msg = String::from(msg);
359 info!("[reply] [to {message_type}{group_id} {nickname} {id}]: {msg}");
360 send_api_request_with_forget(&self.api_tx, send_msg);
361 }
362
363 fn get_text(&self) -> String {
365 match self.text.clone() {
366 Some(v) => v,
367 None => "".to_string(),
368 }
369 }
370
371 fn get_sender_nickname(&self) -> String {
373 if let Some(v) = &self.sender.nickname {
374 v.clone()
375 } else {
376 "".to_string()
377 }
378 }
379
380 fn borrow_text(&self) -> Option<&str> {
382 self.text.as_deref()
383 }
384}
385
386impl CanSendApi for AdminMsgEvent {
387 fn __get_api_tx(&self) -> &tokio::sync::mpsc::Sender<kovi::types::ApiAndOptOneshot> {
388 &self.api_tx
389 }
390}