phoebe/services/phoebe-discord/src/lib.rs

78 lines
2.0 KiB
Rust

use phoebe::{
mid_chat::{self, ChatMessage, ChatMessageReference, ChatReference},
prelude::*,
};
use serenity::{client::Context, Client};
use tracing::{debug, info};
mod chat_conv;
mod handler;
mod sender;
pub fn discord_reference(id: impl ToString) -> mid_chat::ChatReference {
mid_chat::ChatReference {
service: "discord",
id: id.to_string(),
}
}
pub struct DiscordService {
pub discord_ctx: Context,
}
pub async fn setup(core_db: SqlitePool, tx: ChatEventSender) -> Result<DiscordService> {
info!("Setting up Discord service…");
let discord_media_db = phoebe::db::open("discord_media").await?;
sqlx::migrate!().run(&discord_media_db).await?;
let (ctx_tx, mut ctx_rx) = tokio::sync::mpsc::unbounded_channel::<Context>();
let discord_handler = handler::DiscordHandler {
core_db,
discord_media_db,
chat_event_tx: tx,
ctx_tx,
};
debug!("Logging in…");
let discord_token = std::env::var("PHOEBE_DISCORD_TOKEN")
.expect("PHOEBE_DISCORD_TOKEN environment variable was not set!");
let mut client = Client::builder(&discord_token)
.event_handler(discord_handler)
.await?;
tokio::spawn(async move {
client
.start()
.await
.expect("Failed to start Discord client")
});
let discord_ctx = ctx_rx.recv().await.expect("Couldn't get Discord context");
debug!("Logged in!");
Ok(DiscordService { discord_ctx })
}
#[async_trait]
impl Service for DiscordService {
async fn send_chat_message(
&mut self,
source: &ChatMessage,
destination_channel: ChatReference,
) -> Vec<ChatMessageReference> {
assert_eq!(destination_channel.service, "discord");
sender::send_discord_message(&mut self.discord_ctx, source, destination_channel)
.await
.ok()
.into_iter()
.collect()
}
fn tag(&self) -> &'static str {
"discord"
}
}