Feat: Push notification server (#387)
* feat: create base of push daemon Signed-off-by: IAmTomahawkx <iamtomahawkx@gmail.com> * Add outbound senders * Make web_push send to rabbit instead (temp stuff) * feat: stability and friend requests * make vapid fr stuff not suck * swap naming of queue * move pushd into daemons folder * fix cargo file for move into daemons folder * feat: probably working fcm push notifs * comment out fcm webpush stuff since the config keys dont exist * fix fcm, name queues according to their prod status and configure routing keys * add pushd to docker * mix: Remove old code, add stuff to pushd * fix: lockfile * feat: update rocket to 5.0.1 * fix: fix queues and ack bugs * Move rabbit messsage processing into ack queue * chore: update readme * chore: optimizations for ack database hits * pushd flowchart * misc: update flowchart * exit dependancy hell * add rocket_impl flag to authifier * make the tests file of delta actually compile * fix: don't silence every push message * fix: don't silence all messages * add debug logging for sending data to rabbit from message events * validate mentions at a server membership level * put back that import that was actually important * minor fix to lockfile * update delta authifier * feat: proper permissions for push notifications * add unit test for mention sanitization * remove local file dependancy on authifier * update ports to proper defaults * fixTM the node bindings * Theoretically configure docker releases for pushd Signed-off-by: IAmTomahawkx <iamtomahawkx@gmail.com> * declare exchange in pushd and delta * fix createbuckets script Signed-off-by: IAmTomahawkx <iamtomahawkx@gmail.com> * fix: reference db implementation Signed-off-by: IAmTomahawkx <iamtomahawkx@gmail.com> * fix: remove finally redundant code Signed-off-by: IAmTomahawkx <iamtomahawkx@gmail.com> * fix: changes Signed-off-by: IAmTomahawkx <iamtomahawkx@gmail.com> * fix: other changes Signed-off-by: IAmTomahawkx <iamtomahawkx@gmail.com> * fix: make channel name return result Signed-off-by: IAmTomahawkx <iamtomahawkx@gmail.com> --------- Signed-off-by: IAmTomahawkx <iamtomahawkx@gmail.com>
This commit is contained in:
211
crates/core/database/src/amqp/amqp.rs
Normal file
211
crates/core/database/src/amqp/amqp.rs
Normal file
@@ -0,0 +1,211 @@
|
||||
use std::collections::HashSet;
|
||||
|
||||
use crate::events::rabbit::*;
|
||||
use crate::User;
|
||||
use amqprs::channel::BasicPublishArguments;
|
||||
use amqprs::{channel::Channel, connection::Connection, error::Error as AMQPError};
|
||||
use amqprs::{BasicProperties, FieldTable};
|
||||
use revolt_models::v0::PushNotification;
|
||||
use revolt_presence::filter_online;
|
||||
|
||||
use serde_json::to_string;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct AMQP {
|
||||
#[allow(unused)]
|
||||
connection: Connection,
|
||||
channel: Channel,
|
||||
}
|
||||
|
||||
impl AMQP {
|
||||
pub fn new(connection: Connection, channel: Channel) -> AMQP {
|
||||
AMQP {
|
||||
connection,
|
||||
channel,
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn friend_request_accepted(
|
||||
&self,
|
||||
accepted_request_user: &User,
|
||||
sent_request_user: &User,
|
||||
) -> Result<(), AMQPError> {
|
||||
let config = revolt_config::config().await;
|
||||
let payload = FRAcceptedPayload {
|
||||
accepted_user: accepted_request_user.to_owned(),
|
||||
user: sent_request_user.id.clone(),
|
||||
};
|
||||
let payload = to_string(&payload).unwrap();
|
||||
|
||||
debug!(
|
||||
"Sending friend request accept payload on channel {}: {}",
|
||||
config.pushd.get_fr_accepted_routing_key(),
|
||||
payload
|
||||
);
|
||||
self.channel
|
||||
.basic_publish(
|
||||
BasicProperties::default()
|
||||
.with_content_type("application/json")
|
||||
.with_persistence(true)
|
||||
.finish(),
|
||||
payload.into(),
|
||||
BasicPublishArguments::new(
|
||||
&config.pushd.exchange,
|
||||
&config.pushd.get_fr_accepted_routing_key(),
|
||||
),
|
||||
)
|
||||
.await
|
||||
}
|
||||
|
||||
pub async fn friend_request_received(
|
||||
&self,
|
||||
received_request_user: &User,
|
||||
sent_request_user: &User,
|
||||
) -> Result<(), AMQPError> {
|
||||
let config = revolt_config::config().await;
|
||||
let payload = FRReceivedPayload {
|
||||
from_user: sent_request_user.to_owned(),
|
||||
user: received_request_user.id.clone(),
|
||||
};
|
||||
let payload = to_string(&payload).unwrap();
|
||||
|
||||
debug!(
|
||||
"Sending friend request received payload on channel {}: {}",
|
||||
config.pushd.get_fr_received_routing_key(),
|
||||
payload
|
||||
);
|
||||
|
||||
self.channel
|
||||
.basic_publish(
|
||||
BasicProperties::default()
|
||||
.with_content_type("application/json")
|
||||
.with_persistence(true)
|
||||
.finish(),
|
||||
payload.into(),
|
||||
BasicPublishArguments::new(
|
||||
&config.pushd.exchange,
|
||||
&config.pushd.get_fr_received_routing_key(),
|
||||
),
|
||||
)
|
||||
.await
|
||||
}
|
||||
|
||||
pub async fn generic_message(
|
||||
&self,
|
||||
user: &User,
|
||||
title: String,
|
||||
body: String,
|
||||
icon: Option<String>,
|
||||
) -> Result<(), AMQPError> {
|
||||
let config = revolt_config::config().await;
|
||||
let payload = GenericPayload {
|
||||
title,
|
||||
body,
|
||||
icon,
|
||||
user: user.to_owned(),
|
||||
};
|
||||
let payload = to_string(&payload).unwrap();
|
||||
|
||||
debug!(
|
||||
"Sending generic payload on channel {}: {}",
|
||||
config.pushd.get_generic_routing_key(),
|
||||
payload
|
||||
);
|
||||
|
||||
self.channel
|
||||
.basic_publish(
|
||||
BasicProperties::default()
|
||||
.with_content_type("application/json")
|
||||
.with_persistence(true)
|
||||
.finish(),
|
||||
payload.into(),
|
||||
BasicPublishArguments::new(
|
||||
&config.pushd.exchange,
|
||||
&config.pushd.get_generic_routing_key(),
|
||||
),
|
||||
)
|
||||
.await
|
||||
}
|
||||
|
||||
pub async fn message_sent(
|
||||
&self,
|
||||
recipients: Vec<String>,
|
||||
payload: PushNotification,
|
||||
) -> Result<(), AMQPError> {
|
||||
if recipients.is_empty() {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
let config = revolt_config::config().await;
|
||||
|
||||
let online_ids = filter_online(&recipients).await;
|
||||
let recipients = (&recipients.into_iter().collect::<HashSet<String>>() - &online_ids)
|
||||
.into_iter()
|
||||
.collect::<Vec<String>>();
|
||||
|
||||
let payload = MessageSentPayload {
|
||||
notification: payload,
|
||||
users: recipients,
|
||||
};
|
||||
let payload = to_string(&payload).unwrap();
|
||||
|
||||
debug!(
|
||||
"Sending message payload on channel {}: {}",
|
||||
config.pushd.get_message_routing_key(),
|
||||
payload
|
||||
);
|
||||
|
||||
self.channel
|
||||
.basic_publish(
|
||||
BasicProperties::default()
|
||||
.with_content_type("application/json")
|
||||
.with_persistence(true)
|
||||
.finish(),
|
||||
payload.into(),
|
||||
BasicPublishArguments::new(
|
||||
&config.pushd.exchange,
|
||||
&config.pushd.get_message_routing_key(),
|
||||
),
|
||||
)
|
||||
.await
|
||||
}
|
||||
|
||||
pub async fn ack_message(
|
||||
&self,
|
||||
user_id: String,
|
||||
channel_id: String,
|
||||
message_id: String,
|
||||
) -> Result<(), AMQPError> {
|
||||
let config = revolt_config::config().await;
|
||||
|
||||
let payload = AckPayload {
|
||||
user_id: user_id.clone(),
|
||||
channel_id: channel_id.clone(),
|
||||
message_id,
|
||||
};
|
||||
let payload = to_string(&payload).unwrap();
|
||||
|
||||
info!(
|
||||
"Sending ack payload on channel {}: {}",
|
||||
config.pushd.ack_queue, payload
|
||||
);
|
||||
|
||||
let mut headers = FieldTable::new();
|
||||
headers.insert(
|
||||
"x-deduplication-header".try_into().unwrap(),
|
||||
format!("{}-{}", &user_id, &channel_id).into(),
|
||||
);
|
||||
|
||||
self.channel
|
||||
.basic_publish(
|
||||
BasicProperties::default()
|
||||
.with_content_type("application/json")
|
||||
.with_persistence(true)
|
||||
//.with_headers(headers)
|
||||
.finish(),
|
||||
payload.into(),
|
||||
BasicPublishArguments::new(&config.pushd.exchange, &config.pushd.ack_queue),
|
||||
)
|
||||
.await
|
||||
}
|
||||
}
|
||||
2
crates/core/database/src/amqp/mod.rs
Normal file
2
crates/core/database/src/amqp/mod.rs
Normal file
@@ -0,0 +1,2 @@
|
||||
#[allow(clippy::module_inception)]
|
||||
pub mod amqp;
|
||||
Reference in New Issue
Block a user