use std::sync::atomic::AtomicBool; use poise::{Event, FrameworkContext}; use poise::futures_util::future::ok; use poise::serenity_prelude::async_trait; use poise::serenity_prelude::model::{ gateway::Ready, id::ChannelId, }; use poise::serenity_prelude::{Context, EventHandler, Message}; use crate::{ManifoldConfig, ManifoldContext, ManifoldData, ManifoldDataInner}; use crate::error::{ManifoldError, ManifoldResult}; use crate::models::user::UserInfo; use crate::responses::Responses; pub struct Handler { pub timer_running: AtomicBool, } impl Handler { pub fn new() -> Self { Handler { timer_running: AtomicBool::from(false) } } pub async fn listen(ctx: &Context, framework_ctx: FrameworkContext<'_, ManifoldData, ManifoldError>, event: &Event<'_>) -> ManifoldResult<()> { match event { Event::Ready { data_about_bot} => Handler::standard_startup(&ctx, &framework_ctx, data_about_bot).await, Event::Message { new_message } => Handler::message(&ctx, &framework_ctx, &new_message).await, Event::MessageUpdate { old_if_available, new, event } => Handler::message_edited(&ctx, &framework_ctx, old_if_available, new).await, _ => Ok(()) } } pub async fn standard_startup(ctx: &Context, framework_ctx: &FrameworkContext<'_, ManifoldData, ManifoldError>, data_about_bot: &Ready) -> ManifoldResult<()> { let config = &framework_ctx.user_data().await.bot_config; let responses = &framework_ctx.user_data().await.responses; let greeting = match responses.get_response(&"bot startup".to_string()) { Some(g) => g.to_owned(), None => "Manifold bot connected to discord and ready to begin broadcast operations.".to_string(), }; let bot_nickname = config.get_value(&"BotNickname".to_string()).unwrap_or("BrokenManifoldBot".to_string()); let channel: ChannelId = config.get_channel(&"Log".to_string()).expect("Specified log channel invalid or unavailable"); for guild in &data_about_bot.guilds { match guild.id.edit_nickname(&ctx, Some(&*bot_nickname)).await { Ok(()) => (), Err(e) => { error!("Error setting bot nickname (lack permission?): {:?}", e); } } } channel.say(&ctx, greeting).await.expect("Couldn't message log channel!"); Ok(()) } async fn message(_ctx: &Context, fctx: &FrameworkContext<'_, ManifoldData, ManifoldError>, msg: &Message) -> ManifoldResult<()> { let userinfo = &mut fctx.user_data().await.user_info.lock().await; if let Some(u) = userinfo.get_mut(&msg.author.id.as_u64()) { u.last_seen = Some(chrono::Utc::now().timestamp()); } else { let new_user = UserInfo { user_id: msg.author.id.as_u64().clone() as i64, username: msg.author.name.to_owned(), weather_location: None, weather_units: None, timezone: None, last_seen: Some(chrono::Utc::now().timestamp()), }; userinfo.insert(msg.author.id.as_u64().clone(), new_user); } Ok(()) } async fn message_edited(ctx: &Context, fctx: &FrameworkContext<'_, ManifoldData, ManifoldError>, original: &Option, new_message: &Option) -> ManifoldResult<()> { let log_channel = fctx.user_data().await.bot_config.get_channel(&"Log".to_string()).unwrap(); if let Some(new) = new_message.as_ref() { log_channel.send_message(ctx, |f| { f .content("") .embed(|e| { e .title("Message updated") .author(|a| a.name(new.author.name.clone())) .timestamp(new.timestamp) .field("Original Content", match original.as_ref() { Some(m) => m.content.clone(), None => "Not available".to_string(), }, false) .field("New Content", new.content.clone(), false) }) }).await?; } Ok(()) } }