90 lines
2.4 KiB
Rust
90 lines
2.4 KiB
Rust
use log::info;
|
|
use serenity::{async_trait, model::prelude::*, prelude::*};
|
|
use tokio::sync::mpsc;
|
|
|
|
use crate::{
|
|
message_ast::{self, format_discord},
|
|
messages::{MessageAuthor, MessageReference, SentMessage},
|
|
};
|
|
|
|
pub use serenity::client::Context;
|
|
pub use serenity::model::id::ChannelId;
|
|
|
|
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<Context>,
|
|
message_tx: mpsc::UnboundedSender<SentMessage>,
|
|
}
|
|
|
|
#[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 forward_to_discord(
|
|
discord_ctx: &Context,
|
|
channel: ChannelId,
|
|
message: &SentMessage,
|
|
) -> Option<MessageReference> {
|
|
channel
|
|
.send_message(&discord_ctx.http, |m| {
|
|
m.content(format_discord(&message.content))
|
|
})
|
|
.await
|
|
.as_ref()
|
|
.ok()
|
|
.map(MessageReference::from)
|
|
}
|
|
|
|
pub async fn create_discord_client(
|
|
ctx_tx: mpsc::UnboundedSender<Context>,
|
|
message_tx: mpsc::UnboundedSender<SentMessage>,
|
|
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
|
|
}
|