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