use color_eyre::Result; use tracing::info; use tracing_subscriber::EnvFilter; use phoebe::{ get_linked_channels, link_messages, prelude::{ChatEvent, SqlitePool}, service::Service, DynServiceLookup, }; async fn handle_events( dyn_service: DynServiceLookup, db: SqlitePool, mut service: Box, mut rx: tokio::sync::broadcast::Receiver, ) { info!("Handling events for {}…", service.tag()); let mut conn = db .acquire() .await .expect("Failed to acquire core DB connection"); while let Ok(event) = rx.recv().await { match event { phoebe::prelude::ChatEvent::NewMessage(message) => { let linked_channels = get_linked_channels(&mut conn, dyn_service, &message.origin.channel).await; let mut resulting_messages = vec![]; for destination_channel in linked_channels { resulting_messages.extend( service .send_chat_message(&message, destination_channel) .await, ) } if let Err(e) = link_messages(&mut conn, &message.origin, &resulting_messages).await { tracing::error!("Failed to link messages: {e}"); } } } } } #[tokio::main] async fn main() -> Result<()> { color_eyre::install()?; tracing_subscriber::fmt() .with_target(true) .with_env_filter(EnvFilter::from_default_env()) .init(); let (tx, _) = tokio::sync::broadcast::channel(512); let db = phoebe::open_core_db().await?; fn dyn_service(service: &str) -> &'static str { match service { "discord" => "discord", "matrix" => "matrix", _ => panic!("Unsupported service: {}", service), } } let services: Vec> = vec![Box::new( phoebe_discord::setup(db.clone(), tx.clone(), dyn_service).await?, )]; let handles = services .into_iter() .map(|srv| tokio::spawn(handle_events(dyn_service, db.clone(), srv, tx.subscribe()))); let _ = futures::future::join_all(handles).await; Ok(()) }