2022-04-16 10:04:38 +00:00
|
|
|
use phoebe::{get_message_link_id, mid_chat::*, prelude::*};
|
2022-04-11 11:52:29 +00:00
|
|
|
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;
|
|
|
|
|
2022-04-17 11:34:04 +00:00
|
|
|
let avatar_url = message
|
|
|
|
.author
|
|
|
|
.static_avatar_url()
|
|
|
|
.unwrap_or_else(|| message.author.default_avatar_url());
|
|
|
|
|
2022-04-11 11:52:29 +00:00
|
|
|
ChatAuthor {
|
|
|
|
reference: discord_reference(message.author.id),
|
|
|
|
display_name,
|
|
|
|
display_color,
|
2022-04-17 11:34:04 +00:00
|
|
|
avatar: ChatAttachment::Online {
|
|
|
|
media_type: None,
|
|
|
|
url: avatar_url,
|
|
|
|
},
|
2022-04-11 11:52:29 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[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) {
|
2022-04-16 08:06:48 +00:00
|
|
|
let origin = ChatMessageReference::new(discord_reference(message.channel_id), message.id);
|
2022-04-11 11:52:29 +00:00
|
|
|
|
2022-04-16 10:04:38 +00:00
|
|
|
// 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;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-04-11 11:52:29 +00:00
|
|
|
let author = self.get_author(&ctx, &message).await;
|
|
|
|
|
|
|
|
let content = discord_message_format::parse(&message.content);
|
|
|
|
let content = super::chat_conv::convert(&content);
|
|
|
|
|
2022-04-16 08:06:48 +00:00
|
|
|
let replies_to = message
|
|
|
|
.referenced_message
|
|
|
|
.as_ref()
|
|
|
|
.map(|m| ChatMessageReference::new(discord_reference(m.channel_id), m.id));
|
2022-04-11 11:52:29 +00:00
|
|
|
|
2022-04-17 11:08:11 +00:00
|
|
|
let attachments = message
|
|
|
|
.attachments
|
|
|
|
.into_iter()
|
2022-04-17 11:34:04 +00:00
|
|
|
.map(|a| ChatAttachment::Online {
|
|
|
|
media_type: a.content_type,
|
|
|
|
url: a.url,
|
|
|
|
})
|
2022-04-17 11:08:11 +00:00
|
|
|
.collect::<Vec<_>>();
|
|
|
|
|
2022-04-11 11:52:29 +00:00
|
|
|
let chat_message = ChatMessage {
|
|
|
|
origin,
|
|
|
|
author,
|
|
|
|
content,
|
2022-04-17 11:08:11 +00:00
|
|
|
attachments,
|
2022-04-11 11:52:29 +00:00
|
|
|
replying: replies_to,
|
|
|
|
};
|
|
|
|
|
|
|
|
let _ = self
|
|
|
|
.chat_event_tx
|
2022-04-17 12:03:21 +00:00
|
|
|
.send(ChatEvent::NewMessage(Box::new(chat_message)))
|
2022-04-11 11:52:29 +00:00
|
|
|
.expect("Failed to dispatch incoming Discord chat message");
|
|
|
|
}
|
2022-04-17 12:03:21 +00:00
|
|
|
|
|
|
|
async fn message_delete(
|
|
|
|
&self,
|
|
|
|
_ctx: Context,
|
|
|
|
channel_id: ChannelId,
|
|
|
|
deleted_message_id: MessageId,
|
|
|
|
_guild_id: Option<GuildId>,
|
|
|
|
) {
|
|
|
|
let origin = ChatMessageReference::new(discord_reference(channel_id), deleted_message_id);
|
|
|
|
let _ = self
|
|
|
|
.chat_event_tx
|
|
|
|
.send(ChatEvent::DeleteMessage(origin))
|
|
|
|
.expect("Failed to dispatch incoming Discord chat message deletion");
|
|
|
|
}
|
2022-04-18 14:47:05 +00:00
|
|
|
|
|
|
|
async fn message_update(
|
|
|
|
&self,
|
|
|
|
ctx: Context,
|
|
|
|
_old_if_available: Option<Message>,
|
|
|
|
new: Option<Message>,
|
|
|
|
event: MessageUpdateEvent,
|
|
|
|
) {
|
|
|
|
if let Ok(new_message) = {
|
|
|
|
if let Some(m) = new {
|
|
|
|
Ok(m)
|
|
|
|
} else {
|
|
|
|
event.channel_id.message(&ctx, event.id).await
|
|
|
|
}
|
|
|
|
} {
|
|
|
|
let origin = ChatMessageReference::new(
|
|
|
|
discord_reference(new_message.channel_id),
|
|
|
|
new_message.id,
|
|
|
|
);
|
|
|
|
let author = self.get_author(&ctx, &new_message).await;
|
|
|
|
|
|
|
|
let content = discord_message_format::parse(&new_message.content);
|
|
|
|
let content = super::chat_conv::convert(&content);
|
|
|
|
|
|
|
|
let edit = ChatMessageEdit {
|
|
|
|
origin: origin.clone(),
|
|
|
|
author,
|
|
|
|
new_content: content,
|
|
|
|
};
|
|
|
|
|
|
|
|
let _ = self
|
|
|
|
.chat_event_tx
|
|
|
|
.send(ChatEvent::EditMessage(origin, Box::new(edit)))
|
|
|
|
.expect("Failed to dispatch incoming Discord chat message update");
|
|
|
|
}
|
|
|
|
}
|
2022-04-11 11:52:29 +00:00
|
|
|
}
|