forked from jmug/stoatchat
* 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>
139 lines
4.4 KiB
Rust
139 lines
4.4 KiB
Rust
use crate::consumers::inbound::internal::*;
|
|
use amqprs::{
|
|
channel::{BasicPublishArguments, Channel},
|
|
connection::Connection,
|
|
consumer::AsyncConsumer,
|
|
BasicProperties, Deliver,
|
|
};
|
|
use async_trait::async_trait;
|
|
use revolt_database::{events::rabbit::*, Database};
|
|
|
|
pub struct AckConsumer {
|
|
#[allow(dead_code)]
|
|
db: Database,
|
|
authifier_db: authifier::Database,
|
|
conn: Option<Connection>,
|
|
channel: Option<Channel>,
|
|
}
|
|
|
|
impl Channeled for AckConsumer {
|
|
fn get_connection(&self) -> Option<&Connection> {
|
|
if self.conn.is_none() {
|
|
None
|
|
} else {
|
|
Some(self.conn.as_ref().unwrap())
|
|
}
|
|
}
|
|
|
|
fn get_channel(&self) -> Option<&Channel> {
|
|
if self.channel.is_none() {
|
|
None
|
|
} else {
|
|
Some(self.channel.as_ref().unwrap())
|
|
}
|
|
}
|
|
|
|
fn set_connection(&mut self, conn: Connection) {
|
|
self.conn = Some(conn);
|
|
}
|
|
|
|
fn set_channel(&mut self, channel: Channel) {
|
|
self.channel = Some(channel)
|
|
}
|
|
}
|
|
|
|
impl AckConsumer {
|
|
pub fn new(db: Database, authifier_db: authifier::Database) -> AckConsumer {
|
|
AckConsumer {
|
|
db,
|
|
authifier_db,
|
|
conn: None,
|
|
channel: None,
|
|
}
|
|
}
|
|
}
|
|
|
|
#[allow(unused_variables)]
|
|
#[async_trait]
|
|
impl AsyncConsumer for AckConsumer {
|
|
/// This consumer processes all acks the platform receives, and sends relevant badge updates to apple platforms.
|
|
async fn consume(
|
|
&mut self,
|
|
channel: &Channel,
|
|
deliver: Deliver,
|
|
basic_properties: BasicProperties,
|
|
content: Vec<u8>,
|
|
) {
|
|
let content = String::from_utf8(content).unwrap();
|
|
let payload: AckPayload = serde_json::from_str(content.as_str()).unwrap();
|
|
|
|
// Step 1: fetch unreads and don't continue if there's no unreads
|
|
#[allow(clippy::disallowed_methods)]
|
|
let unreads = self.db.fetch_unread_mentions(&payload.user_id).await;
|
|
|
|
if let Ok(u) = &unreads {
|
|
if u.is_empty() {
|
|
return;
|
|
}
|
|
} else {
|
|
return;
|
|
}
|
|
|
|
if let Ok(sessions) = self.authifier_db.find_sessions(&payload.user_id).await {
|
|
let config = revolt_config::config().await;
|
|
// Step 2: find any apple sessions, since we don't need to calculate this for anything else.
|
|
// If there's no apple sessions, we can return early
|
|
let apple_sessions: Vec<&authifier::models::Session> = sessions
|
|
.iter()
|
|
.filter(|session| {
|
|
if let Some(sub) = &session.subscription {
|
|
sub.endpoint == "apn"
|
|
} else {
|
|
false
|
|
}
|
|
})
|
|
.collect();
|
|
|
|
if apple_sessions.is_empty() {
|
|
return;
|
|
}
|
|
|
|
// Step 3: calculate the actual mention count, since we have to send it out
|
|
let mut mention_count = 0;
|
|
for u in &unreads.unwrap() {
|
|
mention_count += u.mentions.as_ref().unwrap().len()
|
|
}
|
|
|
|
// Step 4: loop through each apple session and send the badge update
|
|
for session in apple_sessions {
|
|
let service_payload = PayloadToService {
|
|
notification: PayloadKind::BadgeUpdate(mention_count),
|
|
user_id: payload.user_id.clone(),
|
|
session_id: session.id.clone(),
|
|
token: session.subscription.as_ref().unwrap().auth.clone(),
|
|
extras: Default::default(),
|
|
};
|
|
let raw_service_payload = serde_json::to_string(&service_payload);
|
|
|
|
if let Ok(p) = raw_service_payload {
|
|
let args = BasicPublishArguments::new(
|
|
config.pushd.exchange.as_str(),
|
|
config.pushd.apn.queue.as_str(),
|
|
)
|
|
.finish();
|
|
|
|
log::debug!(
|
|
"Publishing ack to apn session {}",
|
|
session.subscription.as_ref().unwrap().auth
|
|
);
|
|
|
|
publish_message(self, p.into(), args).await;
|
|
} else {
|
|
log::warn!("Failed to serialize ack badge update payload!");
|
|
revolt_config::capture_error(&raw_service_payload.unwrap_err());
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|