From 4586e4738a99410fcde3e3d201bccdee860acabc Mon Sep 17 00:00:00 2001 From: Zomatree Date: Fri, 19 Jun 2026 21:05:22 +0100 Subject: [PATCH] feat: publish events over amqp Signed-off-by: Zomatree --- crates/core/config/Revolt.toml | 1 + crates/core/config/src/lib.rs | 1 + crates/core/database/src/amqp/amqp.rs | 46 ++++++++++++++++++++--- crates/core/database/src/amqp/mod.rs | 2 + crates/core/database/src/events/client.rs | 14 +++++-- 5 files changed, 55 insertions(+), 9 deletions(-) diff --git a/crates/core/config/Revolt.toml b/crates/core/config/Revolt.toml index e598a3dc..b63d5dde 100644 --- a/crates/core/config/Revolt.toml +++ b/crates/core/config/Revolt.toml @@ -34,6 +34,7 @@ default_exchange = "revolt.default" [rabbit.queues] acks = "internal.ack" +events = "internal.event" [api] diff --git a/crates/core/config/src/lib.rs b/crates/core/config/src/lib.rs index 1ba041ca..649c19d2 100644 --- a/crates/core/config/src/lib.rs +++ b/crates/core/config/src/lib.rs @@ -125,6 +125,7 @@ pub struct Database { #[derive(Deserialize, Debug, Clone)] pub struct RabbitQueues { pub acks: String, + pub events: String, } #[derive(Deserialize, Debug, Clone)] diff --git a/crates/core/database/src/amqp/amqp.rs b/crates/core/database/src/amqp/amqp.rs index b0e5e175..a4f02e06 100644 --- a/crates/core/database/src/amqp/amqp.rs +++ b/crates/core/database/src/amqp/amqp.rs @@ -1,20 +1,29 @@ -use std::collections::HashSet; -use std::sync::Arc; +use std::{ + collections::HashSet, + sync::{Arc, OnceLock}, +}; -use crate::events::rabbit::*; +use crate::events::{client::EventV1, rabbit::*}; use crate::User; use lapin::{ options::BasicPublishOptions, protocol::basic::AMQPProperties, types::{AMQPValue, FieldTable}, - Channel, Connection, ConnectionProperties, Error as AMQPError, + BasicProperties, Channel, Connection, ConnectionProperties, Error as AMQPError, }; +use revolt_config::config; use revolt_models::v0::PushNotification; use revolt_presence::filter_online; use revolt_result::Result; use serde_json::to_string; +static AMQP_INSTANCE: OnceLock = OnceLock::new(); + +pub fn get_amqp() -> &'static AMQP { + AMQP_INSTANCE.get().expect("No AMQP instance set.") +} + #[derive(Clone)] pub struct AMQP { friend_request_accepted: Arc, @@ -25,13 +34,14 @@ pub struct AMQP { ack_notification_message: Arc, dm_call_updated: Arc, process_ack: Arc, + publish_event: Arc, #[allow(unused)] connection: Arc, } impl AMQP { pub async fn new(connection: Arc) -> Self { - Self { + let this = Self { friend_request_accepted: Self::create_channel(&connection).await, friend_request_received: Self::create_channel(&connection).await, generic_message: Self::create_channel(&connection).await, @@ -40,8 +50,13 @@ impl AMQP { ack_notification_message: Self::create_channel(&connection).await, dm_call_updated: Self::create_channel(&connection).await, process_ack: Self::create_channel(&connection).await, + publish_event: Self::create_channel(&connection).await, connection, - } + }; + + let _ = AMQP_INSTANCE.set(this.clone()); + + this } pub async fn new_auto() -> Self { @@ -379,4 +394,23 @@ impl AMQP { Ok(()) } + + pub async fn publish_event(&self, channel: String, event: &EventV1) -> Result<(), AMQPError> { + let mut headers = FieldTable::default(); + headers.insert("c".into(), AMQPValue::LongString(channel.into())); + + let config = config().await; + + self.publish_event + .basic_publish( + config.rabbit.default_exchange.clone().into(), + config.rabbit.queues.events.into(), + BasicPublishOptions::default(), + &serde_json::to_vec(event).unwrap(), + BasicProperties::default().with_headers(headers), + ) + .await?; + + Ok(()) + } } diff --git a/crates/core/database/src/amqp/mod.rs b/crates/core/database/src/amqp/mod.rs index 9ed09d34..de58dbc0 100644 --- a/crates/core/database/src/amqp/mod.rs +++ b/crates/core/database/src/amqp/mod.rs @@ -1,2 +1,4 @@ #[allow(clippy::module_inception)] pub mod amqp; + +pub use amqp::{AMQP, get_amqp}; \ No newline at end of file diff --git a/crates/core/database/src/events/client.rs b/crates/core/database/src/events/client.rs index 31864cee..041868c8 100644 --- a/crates/core/database/src/events/client.rs +++ b/crates/core/database/src/events/client.rs @@ -11,7 +11,7 @@ use revolt_models::v0::{ UserVoiceState, Webhook, }; -use crate::Database; +use crate::{Database, amqp::get_amqp}; /// Ping Packet #[derive(Serialize, Deserialize, Debug, Clone)] @@ -372,8 +372,16 @@ impl EventV1 { #[cfg(debug_assertions)] info!("Publishing event to {channel}: {self:?}"); - #[cfg(debug_assertions)] - redis_kiss::publish(channel, self).await.unwrap(); + // #[cfg(debug_assertions)] + // redis_kiss::publish(channel, self).await.unwrap(); + + if let Err(e) = get_amqp().publish_event(channel, &self).await { + if cfg!(debug_assertions) { + panic!("{e:?}"); + } else { + log::error!("{e:?}"); + }; + }; } /// Publish user event