use crate::api_resp;
use crate::event::MessageEvent;
use crate::{api, config, message, utils, ApiChannelItem, ApiResp};
use colored::*;
use tokio::sync::{mpsc, watch};
use tracing::{event, Level};
mod _api;
#[derive(Debug, Clone)]
pub struct Bot {
pub bot_id: String,
pub connect_time: i64,
pub config: config::BotConfig,
pub api_sender: mpsc::Sender<ApiChannelItem>,
pub action_sender: crate::ActionSender,
pub api_resp_watcher: watch::Receiver<ApiResp>,
}
impl Bot {
pub fn new(
bot_id: String,
config: config::BotConfig,
api_sender: mpsc::Sender<ApiChannelItem>,
action_sender: crate::ActionSender,
api_resp_watcher: watch::Receiver<ApiResp>,
) -> Self {
Bot {
bot_id: bot_id,
connect_time: crate::utils::timestamp(),
config: config,
api_sender: api_sender,
action_sender: action_sender,
api_resp_watcher: api_resp_watcher,
}
}
pub async fn send_group_msg(&self, group_id: &str, msg: Vec<message::Message>) {
self.api_sender
.send(ApiChannelItem::Api(crate::api::Api::send_group_msg(
crate::api::SendGroupMsg {
group_id: group_id.to_string(),
message: msg.clone(),
auto_escape: false,
},
)))
.await
.unwrap();
event!(
Level::INFO,
"Bot [{}] Send {:?} to Group ({})",
self.config.bot_id.red(),
msg,
group_id.to_string().magenta()
);
}
pub async fn send_private_msg(&self, user_id: &str, msg: Vec<message::Message>) {
self.api_sender
.send(ApiChannelItem::Api(crate::api::Api::send_private_msg(
crate::api::SendPrivateMsg {
user_id: user_id.to_string(),
message: msg.clone(),
auto_escape: false,
},
)))
.await
.unwrap();
event!(
Level::INFO,
"Bot [{}] Send {:?} to Friend ({})",
self.config.bot_id.red(),
msg,
user_id.to_string().green()
);
}
pub async fn send_by_message_event(&self, event: &MessageEvent, msg: Vec<message::Message>) {
match event {
MessageEvent::Private(p) => self.send_private_msg(&p.user_id, msg).await,
MessageEvent::Group(g) => self.send_group_msg(&g.group_id, msg).await,
}
}
pub async fn call_api(&self, api: api::Api) {
self.api_sender
.send(ApiChannelItem::Api(api.clone()))
.await
.unwrap();
event!(
Level::INFO,
"Bot [{}] Calling Api {:?}",
self.config.bot_id.red(),
api
);
}
pub async fn call_api_resp(&self, api: api::Api) -> Option<api_resp::ApiResp> {
let echo = api.get_echo();
self.api_sender
.send(ApiChannelItem::Api(api.clone()))
.await
.unwrap();
event!(
Level::INFO,
"Bot [{}] Calling Api {:?}",
self.config.bot_id.red(),
api
);
let time = utils::timestamp();
let mut watcher = self.api_resp_watcher.clone();
while let Ok(_) = watcher.changed().await {
let resp = self.api_resp_watcher.borrow().clone();
if resp.echo == echo {
return Some(resp);
}
if utils::timestamp() > time + 30 {
return None;
}
}
None
}
}