Skip to main content

revolt_database/util/
acker.rs

1use redis_kiss::{get_connection, AsyncCommands};
2use revolt_permissions::{calculate_channel_permissions, ChannelPermission};
3use revolt_result::{Result, ToRevoltError};
4
5use crate::{events::client::EventV1, Channel, Database, Server, User, AMQP};
6
7pub async fn ack_channel(user: &str, channel: &str, message: &str, amqp: &AMQP) -> Result<()> {
8    let mut redis = get_connection()
9        .await
10        .map_err(|_| create_error!(InternalError))?;
11
12    let old: Option<String> = redis
13        .getset(format!("acker:{user}+{channel}"), message)
14        .await
15        .to_internal_error()?;
16
17    if old.is_none() || old.unwrap() == message {
18        amqp.process_ack(user, Some(channel), None)
19            .await
20            .to_internal_error()?;
21    }
22
23    Ok(())
24}
25
26pub async fn ack_server(user: &User, server: &Server, db: &Database, amqp: &AMQP) -> Result<()> {
27    let mut redis = get_connection()
28        .await
29        .map_err(|_| create_error!(InternalError))?;
30
31    let channels = db.fetch_channels(&server.channels).await?;
32    let query = crate::util::permissions::DatabasePermissionQuery::new(db, user).server(server);
33
34    for channel in channels {
35        let channel_id = channel.id();
36        let mut q = query.clone().channel(&channel);
37
38        if calculate_channel_permissions(&mut q)
39            .await
40            .has_channel_permission(ChannelPermission::ViewChannel)
41        {
42            let channel_last_msg = match &channel {
43                Channel::TextChannel {
44                    last_message_id, ..
45                } => last_message_id,
46                _ => unreachable!(),
47            }
48            .clone();
49
50            if let Some(channel_last_msg) = channel_last_msg {
51                let old: Option<String> = redis
52                    .getset(
53                        format!("acker:{}+{}", user.id, channel_id),
54                        &channel_last_msg,
55                    )
56                    .await
57                    .to_internal_error()?;
58
59                if old.is_none() || old.unwrap() == channel_last_msg {
60                    amqp.process_ack(&user.id, Some(channel_id), Some(&server.id))
61                        .await
62                        .to_internal_error()?;
63
64                    EventV1::ChannelAck {
65                        id: channel_id.to_string(),
66                        user: user.id.clone(),
67                        message_id: channel_last_msg,
68                    }
69                    .private(user.id.clone())
70                    .await;
71                }
72            }
73        }
74    }
75
76    Ok(())
77}