84 lines
2.5 KiB
Rust
84 lines
2.5 KiB
Rust
use phoebe::{get_message_link_id, 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<Context>,
|
|
}
|
|
|
|
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,
|
|
avatar_url: message
|
|
.author
|
|
.static_avatar_url()
|
|
.unwrap_or_else(|| message.author.default_avatar_url()),
|
|
}
|
|
}
|
|
}
|
|
|
|
#[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);
|
|
|
|
// skip messages linked to ones we have already seen
|
|
if let Ok(mut conn) = self.core_db.acquire().await {
|
|
if get_message_link_id(&mut conn, &origin).await.is_ok() {
|
|
return;
|
|
}
|
|
}
|
|
|
|
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");
|
|
}
|
|
}
|