mod common;
use botrs::{Client, Context, EventHandler, Intents, Message, Ready, Token};
use common::{Config, init_logging};
use std::env;
use tracing::{info, warn};
struct AtReplyHandler;
#[async_trait::async_trait]
impl EventHandler for AtReplyHandler {
async fn ready(&self, _ctx: Context, ready: Ready) {
info!("robot 「{}」 on_ready!", ready.user.username);
}
async fn message_create(&self, ctx: Context, message: Message) {
if let Some(author) = &message.author {
if let Some(avatar) = &author.avatar {
info!("User avatar: {}", avatar);
}
if let Some(username) = &author.username {
info!("Username: {}", username);
}
}
let content = match &message.content {
Some(content) => content,
None => return,
};
if content.contains("sleep") {
info!("Received sleep command, waiting 10 seconds...");
tokio::time::sleep(tokio::time::Duration::from_secs(10)).await;
}
let bot_name = ctx
.bot_info
.as_ref()
.map(|info| info.username.as_str())
.unwrap_or("Bot");
let reply_content = format!("机器人{bot_name}收到你的@消息了: {content}");
match message.reply(&ctx.api, &ctx.token, &reply_content).await {
Ok(_) => info!("Successfully replied to message"),
Err(e) => warn!("Failed to reply to message: {}", e),
}
}
async fn error(&self, error: botrs::BotError) {
warn!("Event handler error: {}", error);
}
}
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
init_logging();
info!("Starting AT reply demo...");
let config = Config::load_with_fallback(
Some("examples/config.toml"),
env::args().nth(1), env::args().nth(2), )?;
info!("Configuration loaded successfully");
let token = Token::new(config.bot.app_id, config.bot.secret);
if let Err(e) = token.validate() {
panic!("Invalid token: {e}");
}
info!("Token validated successfully");
let intents = Intents::default().with_public_guild_messages();
info!("Configured intents: {}", intents);
let handler = AtReplyHandler;
let mut client = Client::new(token, intents, handler, true)?;
info!("Client created, starting bot...");
client.start().await?;
info!("Bot stopped");
Ok(())
}