use super::{Anonymous, Sender};
use crate::event::{MsgEvent, PostType, RepliableEvent};
use crate::message_trait::MessageRegistrar as _;
use crate::onebot_message::OneBotMessage;
use kovi::bot::runtimebot::{CanSendApi, send_api_request_with_forget};
use kovi::bot::{BotInformation, SendApi};
use kovi::error::EventBuildError;
use kovi::event::id::ref_id::RefID;
use kovi::event::{Event, InternalEvent, MessageEventTrait};
use kovi::message::Message as KoviMessage;
use kovi::types::ApiAndOptOneshot;
use log::info;
use serde::Serialize;
use serde_json::value::Index;
use serde_json::{self, Value, json};
use tokio::sync::mpsc;
#[derive(Debug, Clone)]
pub struct GroupMsgEvent {
pub time: i64,
pub self_id: i64,
pub post_type: PostType,
pub message_type: String,
pub sub_type: String,
pub message: KoviMessage,
pub message_id: i32,
pub group_id: i64,
pub user_id: i64,
pub anonymous: Option<Anonymous>,
pub raw_message: String,
pub font: i32,
pub sender: Sender,
pub text: Option<String>,
pub human_text: String,
pub original_json: Value,
pub api_tx: mpsc::Sender<ApiAndOptOneshot>,
}
impl Event for GroupMsgEvent {
fn de(
event: &InternalEvent,
_: &BotInformation,
api_tx: &mpsc::Sender<ApiAndOptOneshot>,
) -> Option<Self> {
let InternalEvent::DriverEvent(json) = event else {
return None;
};
let event = Self::new(api_tx.clone(), json.clone()).ok()?;
Some(event)
}
}
impl GroupMsgEvent {
fn new(
api_tx: mpsc::Sender<ApiAndOptOneshot>,
json: Value,
) -> Result<GroupMsgEvent, EventBuildError> {
let msg_event = MsgEvent::new(api_tx, json)?;
Ok(GroupMsgEvent {
time: msg_event.time,
self_id: msg_event.self_id,
post_type: msg_event.post_type,
message_type: msg_event.message_type,
sub_type: msg_event.sub_type,
message: msg_event.message,
message_id: msg_event.message_id,
group_id: match msg_event.group_id {
Some(id) => id,
None => {
return Err(EventBuildError::ParseError(
"group_id unreachable".to_string(),
));
}
},
user_id: msg_event.user_id,
anonymous: msg_event.anonymous,
raw_message: msg_event.raw_message,
font: msg_event.font,
sender: msg_event.sender,
text: msg_event.text,
human_text: msg_event.human_text,
original_json: msg_event.original_json,
api_tx: msg_event.api_tx,
})
}
}
impl GroupMsgEvent {
pub fn get<I: Index>(&self, index: I) -> Option<&Value> {
self.original_json.get(index)
}
}
impl<I> std::ops::Index<I> for GroupMsgEvent
where
I: Index,
{
type Output = Value;
fn index(&self, index: I) -> &Self::Output {
&self.original_json[index]
}
}
impl GroupMsgEvent {
fn reply_builder<M>(&self, msg: M, auto_escape: bool) -> SendApi
where
M: Into<OneBotMessage>,
{
RepliableEvent::reply_builder(self, msg, auto_escape)
}
#[cfg(not(feature = "cqstring"))]
pub fn reply<T>(&self, msg: T)
where
KoviMessage: From<T>,
T: Serialize,
{
RepliableEvent::reply(self, msg)
}
#[cfg(feature = "cqstring")]
pub fn reply<T>(&self, msg: T)
where
CQMessage: From<T>,
T: Serialize,
{
RepliableEvent::reply(self, msg)
}
#[cfg(not(feature = "cqstring"))]
pub fn reply_and_quote<T>(&self, msg: T)
where
KoviMessage: From<T>,
T: Serialize,
{
RepliableEvent::reply_and_quote(self, msg);
}
#[cfg(feature = "cqstring")]
fn reply_and_quote<T>(&self, msg: T)
where
CQMessage: From<T>,
T: Serialize,
{
RepliableEvent::reply_and_quote(self, msg);
}
#[cfg(feature = "cqstring")]
fn reply_text<T>(&self, msg: T)
where
String: From<T>,
T: Serialize,
{
RepliableEvent::reply_text(self, msg)
}
pub fn get_text(&self) -> String {
RepliableEvent::get_text(self)
}
pub fn get_sender_nickname(&self) -> String {
RepliableEvent::get_sender_nickname(self)
}
pub fn borrow_text(&self) -> Option<&str> {
RepliableEvent::borrow_text(self)
}
}
impl RepliableEvent for GroupMsgEvent {
fn reply_builder<M>(&self, msg: M, auto_escape: bool) -> SendApi
where
M: Into<OneBotMessage>,
{
let msg = msg.into();
SendApi::new(
"send_msg",
json!({
"message_type":"group",
"group_id":self.group_id,
"message":msg,
"auto_escape":auto_escape,
}),
)
}
#[cfg(not(feature = "cqstring"))]
fn reply<T>(&self, msg: T)
where
KoviMessage: From<T>,
T: Serialize,
{
let msg = KoviMessage::from(msg);
let nickname = self.get_sender_nickname();
let id = &self.sender.user_id;
let message_type = &self.message_type;
let group_id = &self.group_id;
let human_msg = msg.to_human_string();
info!("[reply] [to {message_type} {group_id} {nickname} {id}]: {human_msg}");
let send_msg = self.reply_builder(msg, false);
send_api_request_with_forget(&self.api_tx, send_msg)
}
#[cfg(feature = "cqstring")]
fn reply<T>(&self, msg: T)
where
CQMessage: From<T>,
T: Serialize,
{
let msg = CQMessage::from(msg);
let send_msg = self.reply_builder(&msg, false);
let nickname = self.get_sender_nickname();
let id = &self.sender.user_id;
let message_type = &self.message_type;
let group_id = &self.group_id;
let human_msg = Message::from(msg).to_human_string();
info!("[reply] [to {message_type} {group_id} {nickname} {id}]: {human_msg}");
send_api_request_with_forget(&self.api_tx, send_msg);
}
#[cfg(not(feature = "cqstring"))]
fn reply_and_quote<T>(&self, msg: T)
where
KoviMessage: From<T>,
T: Serialize,
{
let msg = KoviMessage::from(msg).add_reply(self.message_id);
let nickname = self.get_sender_nickname();
let id = &self.sender.user_id;
let message_type = &self.message_type;
let group_id = &self.group_id;
let human_msg = msg.to_human_string();
info!("[reply] [to {message_type} {group_id} {nickname} {id}]: {human_msg}");
let send_msg = self.reply_builder(msg, false);
send_api_request_with_forget(&self.api_tx, send_msg);
}
#[cfg(feature = "cqstring")]
fn reply_and_quote<T>(&self, msg: T)
where
CQMessage: From<T>,
T: Serialize,
{
let msg = CQMessage::from(msg).add_reply(self.message_id);
let send_msg = self.reply_builder(&msg, false);
let nickname = self.get_sender_nickname();
let id = &self.sender.user_id;
let message_type = &self.message_type;
let group_id = &self.group_id;
let human_msg = Message::from(msg).to_human_string();
info!("[reply] [to {message_type} {group_id} {nickname} {id}]: {human_msg}");
send_api_request_with_forget(&self.api_tx, send_msg);
}
#[cfg(feature = "cqstring")]
fn reply_text<T>(&self, msg: T)
where
String: From<T>,
T: Serialize,
{
let send_msg = self.reply_builder(&msg, true);
let nickname = self.get_sender_nickname();
let id = &self.sender.user_id;
let message_type = &self.message_type;
let group_id = &self.group_id;
let msg = String::from(msg);
info!("[reply] [to {message_type} {group_id} {nickname} {id}]: {msg}");
send_api_request_with_forget(&self.api_tx, send_msg);
}
fn get_text(&self) -> String {
match self.text.clone() {
Some(v) => v,
None => "".to_string(),
}
}
fn get_sender_nickname(&self) -> String {
if let Some(v) = &self.sender.nickname {
v.clone()
} else {
"".to_string()
}
}
fn borrow_text(&self) -> Option<&str> {
self.text.as_deref()
}
}
impl CanSendApi for GroupMsgEvent {
fn __get_api_tx(&self) -> &tokio::sync::mpsc::Sender<kovi::types::ApiAndOptOneshot> {
&self.api_tx
}
}
impl MessageEventTrait for GroupMsgEvent {
fn get_sender_name(&self) -> Option<&str> {
self.sender.nickname.as_deref()
}
fn get_message(&self) -> &KoviMessage {
&self.message
}
fn get_message_type_str(&self) -> Option<&str> {
Some(&self.message_type)
}
fn get_sender_id(&self) -> RefID<'_> {
RefID::new(&self.sender.user_id)
}
fn get_group_id(&self) -> Option<RefID<'_>> {
Some(RefID::new(&self.group_id))
}
}