use log::info; use serenity::{async_trait, model::prelude::*, prelude::*}; use tokio::sync::mpsc; use crate::{ message_ast, messages::{MessageAuthor, MessageReference, SentMessage}, }; pub use serenity::client::Context; impl From<&Message> for MessageReference { fn from(message: &Message) -> Self { Self::Discord(message.channel_id.0, message.id.0) } } // TODO: Some way to emit messages for matrix, // and some way to receive messages from matrix. struct DiscordHandler { ctx_tx: mpsc::UnboundedSender, message_tx: mpsc::UnboundedSender, } #[async_trait] impl EventHandler for DiscordHandler { async fn ready(&self, ctx: Context, _ready: Ready) { let _ = self.ctx_tx.send(ctx); info!("Discord ready!"); // TODO: Scan for channels to link } async fn message(&self, ctx: Context, message: Message) { if message.author.id == ctx.cache.current_user_id().await { return; } let message_ref = MessageReference::from(&message); // TODO: Store this message ref & associations in the DB let content = discord_message_format::parse(&message.content); let content = message_ast::convert_discord(&content); let _ = self.message_tx.send(SentMessage { source: message_ref, content, author: MessageAuthor { display_name: message .author_nick(&ctx.http) .await .unwrap_or(message.author.name), }, }); } } pub async fn create_discord_client( ctx_tx: mpsc::UnboundedSender, message_tx: mpsc::UnboundedSender, token: &str, ) -> Client { let handler = DiscordHandler { ctx_tx, message_tx }; info!("Discord logging in…"); let client = Client::builder(token) .event_handler(handler) .await .expect("Failed to create discord client"); info!("Discord starting…"); client }