use phoebe::{mid_chat::*, prelude::*}; use serenity::{ client::{Context, EventHandler}, model::prelude::*, }; use tracing::debug; use crate::discord_reference; pub struct DiscordHandler { pub core_db: SqlitePool, pub discord_media_db: SqlitePool, pub chat_event_tx: ChatEventSender, pub ctx_tx: tokio::sync::mpsc::UnboundedSender, } impl DiscordHandler { async fn get_author(&self, ctx: &Context, message: &Message) -> ChatAuthor { let display_name = message .author_nick(ctx) .await .unwrap_or_else(|| message.author.name.clone()); async fn tag_color(ctx: &Context, message: &Message) -> Option<[u8; 3]> { let color = message.member(ctx).await.ok()?.colour(ctx).await?; Some([color.r(), color.b(), color.g()]) } let display_color = tag_color(ctx, message).await; ChatAuthor { reference: discord_reference(message.author.id), display_name, display_color, } } } #[async_trait] impl EventHandler for DiscordHandler { async fn ready(&self, ctx: Context, _ready: Ready) { debug!("Discord signalled ready!"); let _ = self.ctx_tx.send(ctx); } async fn message(&self, ctx: Context, message: Message) { let origin = ChatMessageReference::new(discord_reference(message.channel_id), message.id); let author = self.get_author(&ctx, &message).await; let content = discord_message_format::parse(&message.content); let content = super::chat_conv::convert(&content); let replies_to = message .referenced_message .as_ref() .map(|m| ChatMessageReference::new(discord_reference(m.channel_id), m.id)); let chat_message = ChatMessage { origin, author, content, attachments: vec![], replying: replies_to, }; let _ = self .chat_event_tx .send(ChatEvent::NewMessage(chat_message)) .expect("Failed to dispatch incoming Discord chat message"); } }