serenity_voice_model/payload.rs
1//! Message bodies used in gateway event-handling.
2
3use std::net::IpAddr;
4
5use serde::{Deserialize, Serialize};
6
7use crate::id::*;
8use crate::protocol_data::ProtocolData;
9use crate::speaking_state::SpeakingState;
10use crate::util::json_safe_u64;
11
12/// Message indicating that another user has connected to the voice channel.
13///
14/// Acts as a source of UserId+SSRC identification.
15#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq, Deserialize, Serialize)]
16pub struct ClientConnect {
17 /// SSRC of any audio packets sent by this newly joined user.
18 pub audio_ssrc: u32,
19 /// ID of the connecting user.
20 pub user_id: UserId,
21 /// SSRC of any audio packets sent by this newly joined user.
22 ///
23 /// Bots should not see any packets with this SSRC.
24 pub video_ssrc: u32,
25}
26/// Message indicating that another user has disconnected from the voice channel.
27#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq, Deserialize, Serialize)]
28pub struct ClientDisconnect {
29 /// Id of the disconnected user.
30 pub user_id: UserId,
31}
32
33/// List of user IDs currently in the voice channel.
34#[derive(Clone, Debug, Eq, Hash, PartialEq, Deserialize, Serialize)]
35pub struct ClientsConnect {
36 /// List of user IDs in the voice channel.
37 pub user_ids: Vec<UserId>,
38}
39
40/// Video stream information (opcode 10, unused by bots).
41#[derive(Clone, Debug, Eq, Hash, PartialEq, Deserialize, Serialize)]
42pub struct Video {
43 /// SSRC for the video stream.
44 #[serde(default)]
45 pub audio_ssrc: u32,
46 /// Video SSRC.
47 #[serde(default)]
48 pub video_ssrc: u32,
49 /// User ID of the video sender.
50 #[serde(default)]
51 pub user_id: Option<UserId>,
52}
53
54/// Media sink wants update (opcode 14, unused by bots).
55#[derive(Clone, Debug, Eq, Hash, PartialEq, Deserialize, Serialize)]
56pub struct MediaSinkWants {
57 /// Any value - structure unknown.
58 #[serde(default)]
59 pub any: Option<u32>,
60}
61
62/// Voice backend version (opcode 15, unused by bots).
63#[derive(Clone, Debug, Eq, Hash, PartialEq, Deserialize, Serialize)]
64pub struct VoiceBackendVersion {
65 /// Voice backend version string.
66 #[serde(default)]
67 pub voice: String,
68 /// RTC worker version string.
69 #[serde(default)]
70 pub rtc_worker: String,
71}
72
73/// Channel options update (opcode 16, unused by bots).
74#[derive(Clone, Debug, Eq, Hash, PartialEq, Deserialize, Serialize)]
75pub struct ChannelOptionsUpdate {
76 /// Any value - structure unknown.
77 #[serde(default)]
78 pub any: Option<u32>,
79}
80
81/// User flags in voice (muted, deafened, etc.).
82#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq, Deserialize, Serialize)]
83pub struct Flags {
84 /// User ID whose flags changed.
85 pub user_id: UserId,
86 /// Flags bitfield. Is None for bot users.
87 pub flags: Option<u32>,
88}
89
90/// Platform information for a user.
91#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq, Deserialize, Serialize)]
92pub struct Platform {
93 /// User ID.
94 pub user_id: UserId,
95 /// Platform code (0 = desktop, 1 = mobile, 2 = web, etc.). Is None for
96 /// bot users.
97 pub platform: Option<u32>,
98}
99
100/// Used to keep the websocket connection alive.
101#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq, Deserialize, Serialize)]
102#[serde(transparent)]
103pub struct Heartbeat {
104 /// Random number generated by the client, to be mirrored by the server.
105 pub nonce: u64,
106}
107
108/// Heartbeat ACK, received by the client to show the server's receipt of a heartbeat.
109#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq, Deserialize, Serialize)]
110#[serde(transparent)]
111pub struct HeartbeatAck {
112 /// Random 64-bit number previously generated by the client, mirrored by the server.
113 #[serde(with = "json_safe_u64")]
114 pub nonce: u64,
115}
116
117/// Used to determine how often the client must send a heartbeat.
118#[derive(Clone, Copy, Debug, Deserialize, Serialize)]
119pub struct Hello {
120 /// Number of milliseconds to wait between sending heartbeat messages.
121 pub heartbeat_interval: f64,
122}
123
124/// Used to begin a voice websocket connection.
125#[derive(Clone, Debug, Eq, Hash, PartialEq, Deserialize, Serialize)]
126pub struct Identify {
127 /// GuildId which the target voice channel belongs to.
128 pub server_id: GuildId,
129 /// Authentication session received from Discord's main gateway as part of a
130 /// `"VOICE_STATE_UPDATE"` message.
131 pub session_id: String,
132 /// Authentication token received from Discord's main gateway as part of a
133 /// `"VOICE_SERVER_UPDATE"` message.
134 pub token: String,
135 /// UserId of the client who is connecting.
136 pub user_id: UserId,
137 /// Maximum DAVE protocol version supported by the client.
138 ///
139 /// Signals to Discord that the bot supports end-to-end encryption.
140 /// If omitted, the client does not support DAVE.
141 #[serde(skip_serializing_if = "Option::is_none")]
142 pub max_dave_protocol_version: Option<u16>,
143}
144
145/// RTP server's connection offer and supported encryption modes.
146#[derive(Clone, Debug, Eq, Hash, PartialEq, Deserialize, Serialize)]
147pub struct Ready {
148 /// IP address of the call's allocated RTP server.
149 pub ip: IpAddr,
150 /// Set of voice encryption modes offered by the server.
151 pub modes: Vec<String>,
152 /// Destination port on the call's allocated RTP server.
153 pub port: u16,
154 /// RTP synchronisation source assigned by the server to the client.
155 pub ssrc: u32,
156}
157
158/// Sent by the client after a disconnect to attempt to resume a session.
159#[derive(Clone, Debug, Eq, Hash, PartialEq, Deserialize, Serialize)]
160pub struct Resume {
161 /// GuildId which the target voice channel belongs to.
162 pub server_id: GuildId,
163 /// Authentication session received from Discord's main gateway as part of a
164 /// `"VOICE_STATE_UPDATE"` message.
165 pub session_id: String,
166 /// Authentication token received from Discord's main gateway as part of a
167 /// `"VOICE_SERVER_UPDATE"` message.
168 pub token: String,
169}
170
171/// Used to select the voice protocol and encryption mechanism.
172#[derive(Clone, Debug, Eq, Hash, PartialEq, Deserialize, Serialize)]
173pub struct SelectProtocol {
174 /// Client's response to encryption/connection negotiation.
175 pub data: ProtocolData,
176 /// Transport protocol.
177 ///
178 /// Currently, `"udp"` is the only known accepted value.
179 pub protocol: String,
180}
181
182/// Server's confirmation of a negotiated encryption scheme.
183#[derive(Clone, Debug, Eq, Hash, PartialEq, Deserialize, Serialize)]
184pub struct SessionDescription {
185 /// The negotiated encryption mode.
186 pub mode: String,
187 /// Key used for encryption of RTP payloads using the chosen mode.
188 pub secret_key: Vec<u8>,
189 /// The DAVE protocol version used.
190 pub dave_protocol_version: u16,
191}
192
193/// Used to indicate which users are speaking, or to inform Discord that the client is now
194/// speaking.
195#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq, Deserialize, Serialize)]
196pub struct Speaking {
197 /// Function currently unknown.
198 ///
199 /// Docs suggest setting to `Some(0)` when sending this message as a client.
200 pub delay: Option<u32>,
201 /// How/whether a user has started/stopped speaking.
202 pub speaking: SpeakingState,
203 /// RTP synchronisation source of the speaker.
204 pub ssrc: u32,
205 /// User ID of the speaker, included in messages *received from* the server.
206 ///
207 /// Used alongside the SSRC to map individual packets to their sender.
208 pub user_id: Option<UserId>,
209}
210
211/// DAVE protocol version field in the Identify payload.
212///
213/// Signals to Discord that the bot supports end-to-end encryption
214/// and which protocol version(s) it supports.
215#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq, Deserialize, Serialize)]
216#[serde(transparent)]
217pub struct MaxDaveProtocolVersion(pub u16);
218
219impl MaxDaveProtocolVersion {
220 /// Protocol version 1 - Current DAVE protocol version
221 pub const V1: Self = Self(1);
222}
223
224impl Default for MaxDaveProtocolVersion {
225 fn default() -> Self {
226 Self::V1
227 }
228}
229
230/// External sender package for DAVE MLS group creation.
231///
232/// Received from the server (Opcode 25) containing the voice gateway's
233/// credential and signature public key for the MLS group's external_senders extension.
234///
235/// **Note:** This opcode uses binary WebSocket frames, not JSON.
236/// Binary format: `[opcode: u8][external_sender: Vec<u8>]`
237#[derive(Clone, Debug, Eq, Hash, PartialEq, Deserialize, Serialize)]
238pub struct DaveMlsExternalSender {
239 /// Serialized ExternalSender containing signature_key and credential.
240 pub external_sender: Vec<u8>,
241}
242
243/// Key package for DAVE MLS group participation.
244///
245/// Sent to the server (Opcode 26) during the join handshake.
246/// The basic credential identity is the big-endian 64-bit user ID.
247///
248/// **Note:** This opcode uses binary WebSocket frames, not JSON.
249/// Binary format: `[opcode: u8][key_package: Vec<u8>]` (no sequence number)
250#[derive(Clone, Debug, Eq, Hash, PartialEq, Deserialize, Serialize)]
251pub struct DaveMlsKeyPackage {
252 /// Serialized MLSMessage containing the KeyPackage (see RFC 9420).
253 pub key_package: Vec<u8>,
254}
255
256/// Operation type for MLS proposals.
257#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq, Deserialize, Serialize)]
258#[serde(rename_all = "snake_case")]
259#[repr(u8)]
260pub enum DaveMlsProposalsOperationType {
261 /// Append proposals to the pending proposal list.
262 Append = 0,
263 /// Revoke previously sent proposals by their reference.
264 Revoke = 1,
265}
266
267/// Proposals for group member changes.
268///
269/// Received from the server (Opcode 27) for add/remove operations.
270/// Contains either proposals to append or proposal refs to revoke.
271///
272/// **Note:** This opcode uses binary WebSocket frames, not JSON.
273/// Binary format: `[opcode: u8][operation_type: u8][proposals: Vec<u8>]`
274#[derive(Clone, Debug, Eq, Hash, PartialEq, Deserialize, Serialize)]
275pub struct DaveMlsProposals {
276 /// The type of operation (append or revoke).
277 pub operation_type: DaveMlsProposalsOperationType,
278 /// Serialized proposal data.
279 /// For append: serialized MLSMessage proposal messages.
280 /// For revoke: serialized ProposalRef values.
281 pub proposals: Vec<u8>,
282}
283
284/// Commit with optional welcome message for group transitions.
285///
286/// Sent by the client (Opcode 28) after processing proposals.
287/// When at least one add proposal is handled, the welcome message MUST be included.
288///
289/// **Note:** This opcode uses binary WebSocket frames, not JSON.
290/// Binary format: `[opcode: u8][commit: Vec<u8>][welcome: Option<Vec<u8>>]` (no sequence number)
291#[derive(Clone, Debug, Eq, Hash, PartialEq, Deserialize, Serialize)]
292pub struct DaveMlsCommitWelcome {
293 /// Serialized MLS commit message (see RFC 9420 MLSMessage and Commit definitions).
294 pub commit: Vec<u8>,
295 /// Optional MLS Welcome message for new members (see RFC 9420 Welcome definition).
296 /// Required when the commit includes one or more add proposals.
297 #[serde(skip_serializing_if = "Option::is_none")]
298 pub welcome: Option<Vec<u8>>,
299}
300
301/// Welcome message for new members joining the group.
302///
303/// Received from the server (Opcode 30) as confirmation of successful join.
304/// Includes the transition ID for the group transition.
305///
306/// **Note:** This opcode uses binary WebSocket frames, not JSON.
307/// Binary format: `[opcode: u8][transition_id: u16][welcome: Vec<u8>]`
308#[derive(Clone, Debug, Eq, Hash, PartialEq, Deserialize, Serialize)]
309pub struct DaveMlsWelcome {
310 /// The transition ID for this group transition.
311 pub transition_id: u16,
312 /// Serialized MLS Welcome message (see RFC 9420 Welcome definition).
313 pub welcome: Vec<u8>,
314}
315
316/// Prepare epoch notification before group transition.
317///
318/// Received from the server (Opcode 24) to signal an upcoming epoch change.
319/// When `epoch` is 1, this indicates a new MLS group is to be created.
320#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq, Deserialize, Serialize)]
321pub struct DavePrepareEpoch {
322 /// The protocol version for the upcoming epoch.
323 pub protocol_version: u16,
324 /// The new epoch number after the transition.
325 pub epoch: u64,
326}
327
328/// Transition ready confirmation.
329///
330/// Sent by the client (Opcode 23) to confirm it's ready for a previously announced transition.
331/// The client sends this after processing a commit or preparing receive-side decryptors.
332#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq, Serialize, Deserialize)]
333pub struct DaveTransitionReady {
334 /// The transition ID the client is ready to execute.
335 pub transition_id: u16,
336 /// The protocol version for the transition.
337 pub protocol_version: u16,
338}
339
340/// Prepare protocol transition notification.
341///
342/// Received from the server (Opcode 21) to announce an upcoming protocol transition.
343#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq, Deserialize, Serialize)]
344pub struct DavePrepareTransition {
345 /// The protocol version for the transition.
346 pub protocol_version: u16,
347 /// The transition ID for this transition.
348 pub transition_id: u16,
349}
350
351/// Execute protocol transition notification.
352///
353/// Received from the server (Opcode 22) to execute a previously prepared transition.
354#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq, Deserialize, Serialize)]
355pub struct DaveExecuteTransition {
356 /// The transition ID for this transition.
357 pub transition_id: u16,
358}
359
360/// Announce commit for group transition.
361///
362/// Received from the server (Opcode 29) to broadcast an MLS commit for moving to the next epoch.
363/// The commit is one received from a group member via dave_mls_commit_welcome (Opcode 28).
364///
365/// **Note:** This opcode uses binary WebSocket frames, not JSON.
366/// Binary format: `[opcode: u8][transition_id: u16][commit_message: Vec<u8>]`
367#[derive(Clone, Debug, Eq, Hash, PartialEq, Deserialize, Serialize)]
368pub struct DaveMlsAnnounceCommitTransition {
369 /// The transition ID for this group epoch change.
370 pub transition_id: u16,
371 /// Serialized MLS commit message (see RFC 9420 MLSMessage and Commit definitions).
372 pub commit_message: Vec<u8>,
373}
374
375/// Invalid commit or welcome report.
376///
377/// Sent to the server (Opcode 31) to report an invalid commit or welcome message.
378/// This asks the voice gateway to remove and re-add the member to recover.
379#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq, Deserialize, Serialize)]
380pub struct DaveMlsInvalidCommitWelcome {
381 /// The transition ID in which the invalid Commit or Welcome was received.
382 pub transition_id: u16,
383}