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