revolt_database/events/
client.rs

1use authifier::AuthifierEvent;
2use revolt_result::Error;
3use serde::{Deserialize, Serialize};
4
5use revolt_models::v0::{
6    AppendMessage, Channel, ChannelUnread, ChannelVoiceState, Emoji, FieldsChannel, FieldsMember, FieldsMessage, FieldsRole, FieldsServer, FieldsUser, FieldsWebhook, Member, MemberCompositeKey, Message, PartialChannel, PartialMember, PartialMessage, PartialRole, PartialServer, PartialUser, PartialUserVoiceState, PartialWebhook, PolicyChange, RemovalIntention, Report, Server, User, UserSettings, UserVoiceState, Webhook
7};
8
9use crate::Database;
10
11/// Ping Packet
12#[derive(Serialize, Deserialize, Debug, Clone)]
13#[serde(untagged)]
14pub enum Ping {
15    Binary(Vec<u8>),
16    Number(usize),
17}
18
19/// Fields provided in Ready payload
20#[derive(PartialEq, Debug, Clone, Deserialize)]
21pub struct ReadyPayloadFields {
22    pub users: bool,
23    pub servers: bool,
24    pub channels: bool,
25    pub members: bool,
26    pub emojis: bool,
27    pub voice_states: bool,
28    pub user_settings: Vec<String>,
29    pub channel_unreads: bool,
30    pub policy_changes: bool,
31}
32
33impl Default for ReadyPayloadFields {
34    fn default() -> Self {
35        Self {
36            users: true,
37            servers: true,
38            channels: true,
39            members: true,
40            emojis: true,
41            voice_states: true,
42            user_settings: Vec::new(),
43            channel_unreads: false,
44            policy_changes: true,
45        }
46    }
47}
48
49/// Protocol Events
50#[derive(Serialize, Deserialize, Debug, Clone)]
51#[serde(tag = "type")]
52pub enum EventV1 {
53    /// Multiple events
54    Bulk { v: Vec<EventV1> },
55    /// Error event
56    Error { data: Error },
57
58    /// Successfully authenticated
59    Authenticated,
60    /// Logged out
61    Logout,
62    /// Basic data to cache
63    Ready {
64        #[serde(skip_serializing_if = "Option::is_none")]
65        users: Option<Vec<User>>,
66        #[serde(skip_serializing_if = "Option::is_none")]
67        servers: Option<Vec<Server>>,
68        #[serde(skip_serializing_if = "Option::is_none")]
69        channels: Option<Vec<Channel>>,
70        #[serde(skip_serializing_if = "Option::is_none")]
71        members: Option<Vec<Member>>,
72        #[serde(skip_serializing_if = "Option::is_none")]
73        emojis: Option<Vec<Emoji>>,
74        #[serde(skip_serializing_if = "Option::is_none")]
75        voice_states: Option<Vec<ChannelVoiceState>>,
76
77        #[serde(skip_serializing_if = "Option::is_none")]
78        user_settings: Option<UserSettings>,
79        #[serde(skip_serializing_if = "Option::is_none")]
80        channel_unreads: Option<Vec<ChannelUnread>>,
81
82        #[serde(skip_serializing_if = "Option::is_none")]
83        policy_changes: Option<Vec<PolicyChange>>,
84    },
85
86    /// Ping response
87    Pong { data: Ping },
88    /// New message
89    Message(Message),
90
91    /// Update existing message
92    MessageUpdate {
93        id: String,
94        channel: String,
95        data: PartialMessage,
96        #[serde(default)]
97        clear: Vec<FieldsMessage>,
98    },
99
100    /// Append information to existing message
101    MessageAppend {
102        id: String,
103        channel: String,
104        append: AppendMessage,
105    },
106
107    /// Delete message
108    MessageDelete { id: String, channel: String },
109
110    /// New reaction to a message
111    MessageReact {
112        id: String,
113        channel_id: String,
114        user_id: String,
115        emoji_id: String,
116    },
117
118    /// Remove user's reaction from message
119    MessageUnreact {
120        id: String,
121        channel_id: String,
122        user_id: String,
123        emoji_id: String,
124    },
125
126    /// Remove a reaction from message
127    MessageRemoveReaction {
128        id: String,
129        channel_id: String,
130        emoji_id: String,
131    },
132
133    /// Bulk delete messages
134    BulkMessageDelete { channel: String, ids: Vec<String> },
135
136    /// New server
137    ServerCreate {
138        id: String,
139        server: Server,
140        channels: Vec<Channel>,
141        emojis: Vec<Emoji>,
142        voice_states: Vec<ChannelVoiceState>
143    },
144
145    /// Update existing server
146    ServerUpdate {
147        id: String,
148        data: PartialServer,
149        #[serde(default)]
150        clear: Vec<FieldsServer>,
151    },
152
153    /// Delete server
154    ServerDelete { id: String },
155
156    /// Update existing server member
157    ServerMemberUpdate {
158        id: MemberCompositeKey,
159        data: PartialMember,
160        #[serde(default)]
161        clear: Vec<FieldsMember>,
162    },
163
164    /// User joins server
165    ServerMemberJoin {
166        id: String,
167        // Deprecated: use member.id.user
168        #[deprecated = "Use member.id.user instead"]
169        user: String,
170        member: Member,
171    },
172
173    /// User left server
174    ServerMemberLeave {
175        id: String,
176        user: String,
177        reason: RemovalIntention,
178    },
179
180    /// Server role created or updated
181    ServerRoleUpdate {
182        id: String,
183        role_id: String,
184        data: PartialRole,
185        #[serde(default)]
186        clear: Vec<FieldsRole>,
187    },
188
189    /// Server role deleted
190    ServerRoleDelete { id: String, role_id: String },
191
192    /// Server roles ranks updated
193    ServerRoleRanksUpdate { id: String, ranks: Vec<String> },
194
195    /// Update existing user
196    UserUpdate {
197        id: String,
198        data: PartialUser,
199        #[serde(default)]
200        clear: Vec<FieldsUser>,
201        event_id: Option<String>,
202    },
203
204    /// Relationship with another user changed
205    UserRelationship { id: String, user: User },
206    /// Settings updated remotely
207    UserSettingsUpdate { id: String, update: UserSettings },
208
209    /// User has been platform banned or deleted their account
210    ///
211    /// Clients should remove the following associated data:
212    /// - Messages
213    /// - DM Channels
214    /// - Relationships
215    /// - Server Memberships
216    ///
217    /// User flags are specified to explain why a wipe is occurring though not all reasons will necessarily ever appear.
218    UserPlatformWipe { user_id: String, flags: i32 },
219    /// New emoji
220    EmojiCreate(Emoji),
221
222    /// Delete emoji
223    EmojiDelete { id: String },
224
225    /// New report
226    ReportCreate(Report),
227    /// New channel
228    ChannelCreate(Channel),
229
230    /// Update existing channel
231    ChannelUpdate {
232        id: String,
233        data: PartialChannel,
234        #[serde(default)]
235        clear: Vec<FieldsChannel>,
236    },
237
238    /// Delete channel
239    ChannelDelete { id: String },
240
241    /// User joins a group
242    ChannelGroupJoin { id: String, user: String },
243
244    /// User leaves a group
245    ChannelGroupLeave { id: String, user: String },
246
247    /// User started typing in a channel
248    ChannelStartTyping { id: String, user: String },
249
250    /// User stopped typing in a channel
251    ChannelStopTyping { id: String, user: String },
252
253    /// User acknowledged message in channel
254    ChannelAck {
255        id: String,
256        user: String,
257        message_id: String,
258    },
259
260    /// New webhook
261    WebhookCreate(Webhook),
262
263    /// Update existing webhook
264    WebhookUpdate {
265        id: String,
266        data: PartialWebhook,
267        remove: Vec<FieldsWebhook>,
268    },
269
270    /// Delete webhook
271    WebhookDelete { id: String },
272
273    /// Auth events
274    Auth(AuthifierEvent),
275
276    /// Voice events
277    VoiceChannelJoin {
278        id: String,
279        state: UserVoiceState,
280    },
281    VoiceChannelLeave {
282        id: String,
283        user: String,
284    },
285    VoiceChannelMove {
286        user: String,
287        from: String,
288        to: String,
289        state: UserVoiceState
290    },
291    UserVoiceStateUpdate {
292        id: String,
293        channel_id: String,
294        data: PartialUserVoiceState,
295    },
296    UserMoveVoiceChannel {
297        node: String,
298        from: String,
299        to: String,
300        token: String,
301    }
302}
303
304impl EventV1 {
305    /// Publish helper wrapper
306    pub async fn p(self, channel: String) {
307        #[cfg(not(debug_assertions))]
308        redis_kiss::p(channel, self).await;
309
310        #[cfg(debug_assertions)]
311        info!("Publishing event to {channel}: {self:?}");
312
313        #[cfg(debug_assertions)]
314        redis_kiss::publish(channel, self).await.unwrap();
315    }
316
317    /// Publish user event
318    pub async fn p_user(self, id: String, db: &Database) {
319        self.clone().p(id.clone()).await;
320
321        // TODO: this should be captured by member list in the future and not immediately fanned out to users
322        if let Ok(members) = db.fetch_all_memberships(&id).await {
323            for member in members {
324                self.clone().server(member.id.server).await;
325            }
326        }
327    }
328
329    /// Publish private event
330    pub async fn private(self, id: String) {
331        self.p(format!("{id}!")).await;
332    }
333
334    /// Publish server member event
335    pub async fn server(self, id: String) {
336        self.p(format!("{id}u")).await;
337    }
338
339    /// Publish internal global event
340    pub async fn global(self) {
341        self.p("global".to_string()).await;
342    }
343}