Error observer (also merge perpetual/gateway-dev) (#425)
* Add Webrtc Identify & Ready * Test error observer * Minor updates * More derives * Even more derives * Small types update * e
This commit is contained in:
parent
8c45355620
commit
141dc32819
|
@ -2,6 +2,8 @@
|
|||
use custom_error::custom_error;
|
||||
use reqwest::Error;
|
||||
|
||||
use crate::types::WebSocketEvent;
|
||||
|
||||
custom_error! {
|
||||
#[derive(PartialEq, Eq)]
|
||||
pub RegistrationError
|
||||
|
@ -54,9 +56,10 @@ custom_error! {
|
|||
/// Supposed to be sent as numbers, though they are sent as string most of the time?
|
||||
///
|
||||
/// Also includes errors when initiating a connection and unexpected opcodes
|
||||
#[derive(PartialEq, Eq)]
|
||||
#[derive(PartialEq, Eq, Default, Clone)]
|
||||
pub GatewayError
|
||||
// Errors we have received from the gateway
|
||||
#[default]
|
||||
Unknown = "We're not sure what went wrong. Try reconnecting?",
|
||||
UnknownOpcode = "You sent an invalid Gateway opcode or an invalid payload for an opcode",
|
||||
Decode = "Gateway server couldn't decode payload",
|
||||
|
@ -79,3 +82,5 @@ custom_error! {
|
|||
// Other misc errors
|
||||
UnexpectedOpcodeReceived{opcode: u8} = "Received an opcode we weren't expecting to receive: {opcode}",
|
||||
}
|
||||
|
||||
impl WebSocketEvent for GatewayError {}
|
||||
|
|
|
@ -479,13 +479,15 @@ impl Gateway {
|
|||
return;
|
||||
}
|
||||
|
||||
// Todo: handle errors in a good way, maybe observers like events?
|
||||
if msg.is_error() {
|
||||
warn!("GW: Received error, connection will close..");
|
||||
let error = msg.error().unwrap();
|
||||
|
||||
let _error = msg.error();
|
||||
warn!("GW: Received error {:?}, connection will close..", error);
|
||||
|
||||
self.close().await;
|
||||
|
||||
self.events.lock().await.error.notify(error).await;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -935,6 +937,7 @@ mod events {
|
|||
pub webhooks: Webhooks,
|
||||
pub gateway_identify_payload: GatewayEvent<types::GatewayIdentifyPayload>,
|
||||
pub gateway_resume: GatewayEvent<types::GatewayResume>,
|
||||
pub error: GatewayEvent<GatewayError>,
|
||||
}
|
||||
|
||||
#[derive(Default, Debug)]
|
||||
|
|
|
@ -21,7 +21,7 @@ pub struct CallCreate {
|
|||
|
||||
impl WebSocketEvent for CallCreate {}
|
||||
|
||||
#[derive(Debug, Deserialize, Serialize, Default, Clone)]
|
||||
#[derive(Debug, Deserialize, Serialize, Default, Clone, PartialEq, Eq)]
|
||||
/// Officially Undocumented;
|
||||
/// Updates the client on which calls are ringing, along with a specific call?;
|
||||
///
|
||||
|
@ -38,7 +38,7 @@ pub struct CallUpdate {
|
|||
|
||||
impl WebSocketEvent for CallUpdate {}
|
||||
|
||||
#[derive(Debug, Deserialize, Serialize, Default, Clone)]
|
||||
#[derive(Debug, Deserialize, Serialize, Default, Clone, PartialEq, Eq)]
|
||||
/// Officially Undocumented;
|
||||
/// Deletes a ringing call;
|
||||
/// Ex: {"t":"CALL_DELETE","s":8,"op":0,"d":{"channel_id":"837609115475771392"}}
|
||||
|
@ -48,7 +48,7 @@ pub struct CallDelete {
|
|||
|
||||
impl WebSocketEvent for CallDelete {}
|
||||
|
||||
#[derive(Debug, Deserialize, Serialize, Default, Clone)]
|
||||
#[derive(Debug, Deserialize, Serialize, Default, Clone, PartialEq, Eq)]
|
||||
/// Officially Undocumented;
|
||||
/// See <https://unofficial-discord-docs.vercel.app/gateway/op13>;
|
||||
///
|
||||
|
|
|
@ -2,7 +2,7 @@ use crate::types::WebSocketEvent;
|
|||
use serde::{Deserialize, Serialize};
|
||||
|
||||
/// Received on gateway init, tells the client how often to send heartbeats;
|
||||
#[derive(Debug, Default, Deserialize, Serialize)]
|
||||
#[derive(Debug, Default, Deserialize, Serialize, Clone, PartialEq, Eq)]
|
||||
pub struct GatewayHello {
|
||||
pub op: i32,
|
||||
pub d: HelloData,
|
||||
|
@ -10,7 +10,7 @@ pub struct GatewayHello {
|
|||
|
||||
impl WebSocketEvent for GatewayHello {}
|
||||
|
||||
#[derive(Debug, Default, Deserialize, Serialize, Clone)]
|
||||
#[derive(Debug, Default, Deserialize, Serialize, Clone, PartialEq, Eq, Copy)]
|
||||
/// Contains info on how often the client should send heartbeats to the server;
|
||||
pub struct HelloData {
|
||||
/// How often a client should send heartbeats, in milliseconds
|
||||
|
|
|
@ -2,7 +2,7 @@ use crate::types::events::{PresenceUpdate, WebSocketEvent};
|
|||
use serde::{Deserialize, Serialize};
|
||||
use serde_with::serde_as;
|
||||
|
||||
#[derive(Debug, Deserialize, Serialize)]
|
||||
#[derive(Debug, Deserialize, Serialize, Clone, PartialEq)]
|
||||
pub struct GatewayIdentifyPayload {
|
||||
pub token: String,
|
||||
pub properties: GatewayIdentifyConnectionProps,
|
||||
|
@ -68,7 +68,7 @@ impl GatewayIdentifyPayload {
|
|||
|
||||
impl WebSocketEvent for GatewayIdentifyPayload {}
|
||||
|
||||
#[derive(Debug, Deserialize, Serialize, Clone)]
|
||||
#[derive(Debug, Deserialize, Serialize, Clone, PartialEq, Eq)]
|
||||
#[serde_as]
|
||||
pub struct GatewayIdentifyConnectionProps {
|
||||
/// Almost always sent
|
||||
|
@ -144,7 +144,7 @@ impl GatewayIdentifyConnectionProps {
|
|||
referring_domain: None,
|
||||
referrer_current: None,
|
||||
release_channel: String::from("stable"),
|
||||
client_build_number: 199933,
|
||||
client_build_number: 0,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -159,7 +159,7 @@ impl GatewayIdentifyConnectionProps {
|
|||
system_locale: String::from("en-US"),
|
||||
os: String::from("Windows"),
|
||||
os_version: Some(String::from("10")),
|
||||
client_build_number: 199933,
|
||||
client_build_number: 222963,
|
||||
release_channel: String::from("stable"),
|
||||
..Self::minimal()
|
||||
}
|
||||
|
|
|
@ -5,6 +5,8 @@ use std::collections::HashMap;
|
|||
use serde::de::DeserializeOwned;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use serde_json::{from_str, from_value, to_value, Value};
|
||||
|
||||
pub use application::*;
|
||||
pub use auto_moderation::*;
|
||||
pub use call::*;
|
||||
|
@ -24,13 +26,13 @@ pub use ready::*;
|
|||
pub use relationship::*;
|
||||
pub use request_members::*;
|
||||
pub use resume::*;
|
||||
use serde_json::{from_str, from_value, to_value, Value};
|
||||
pub use session::*;
|
||||
pub use stage_instance::*;
|
||||
pub use thread::*;
|
||||
pub use user::*;
|
||||
pub use voice::*;
|
||||
pub use webhooks::*;
|
||||
pub use webrtc::*;
|
||||
|
||||
use crate::gateway::Updateable;
|
||||
|
||||
|
@ -62,6 +64,8 @@ mod user;
|
|||
mod voice;
|
||||
mod webhooks;
|
||||
|
||||
mod webrtc;
|
||||
|
||||
pub trait WebSocketEvent {}
|
||||
|
||||
#[derive(Debug, Default, Serialize, Clone)]
|
||||
|
|
|
@ -14,7 +14,7 @@ pub struct UpdatePresence {
|
|||
pub afk: bool,
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize, Serialize, Default, Clone)]
|
||||
#[derive(Debug, Deserialize, Serialize, Default, Clone, PartialEq)]
|
||||
/// Received to tell the client that a user updated their presence / status
|
||||
/// See <https://discord.com/developers/docs/topics/gateway-events#presence-update-presence-update-event-fields>
|
||||
pub struct PresenceUpdate {
|
||||
|
|
|
@ -4,7 +4,7 @@ use crate::types::entities::PublicUser;
|
|||
use crate::types::events::WebSocketEvent;
|
||||
use crate::types::utils::Snowflake;
|
||||
|
||||
#[derive(Debug, Default, Deserialize, Serialize, Clone)]
|
||||
#[derive(Debug, Default, Deserialize, Serialize, Clone, PartialEq, Eq)]
|
||||
/// See <https://discord.com/developers/docs/topics/gateway-events#user-update>;
|
||||
/// Sent to indicate updates to a user object; (name changes, discriminator changes, etc);
|
||||
pub struct UserUpdate {
|
||||
|
@ -14,7 +14,7 @@ pub struct UserUpdate {
|
|||
|
||||
impl WebSocketEvent for UserUpdate {}
|
||||
|
||||
#[derive(Debug, Default, Deserialize, Serialize, Clone)]
|
||||
#[derive(Debug, Default, Deserialize, Serialize, Clone, PartialEq, Eq)]
|
||||
/// Undocumented;
|
||||
///
|
||||
/// Possibly an update for muted guild / channel settings for the current user;
|
||||
|
@ -39,7 +39,7 @@ pub struct UserGuildSettingsUpdate {
|
|||
|
||||
impl WebSocketEvent for UserGuildSettingsUpdate {}
|
||||
|
||||
#[derive(Debug, Default, Deserialize, Serialize, Clone)]
|
||||
#[derive(Debug, Default, Deserialize, Serialize, Clone, PartialEq, Eq)]
|
||||
/// Undocumented;
|
||||
///
|
||||
/// Received in [UserGuildSettingsUpdate];
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use crate::types::{events::WebSocketEvent, Snowflake, VoiceState};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Debug, Deserialize, Serialize, Default)]
|
||||
#[derive(Debug, Deserialize, Serialize, Default, Clone, Copy, PartialEq, Eq)]
|
||||
///
|
||||
/// Sent to the server to indicate an update of the voice state (leave voice channel, join voice channel, mute, deafen);
|
||||
///
|
||||
|
@ -28,7 +28,7 @@ pub struct VoiceStateUpdate {
|
|||
|
||||
impl WebSocketEvent for VoiceStateUpdate {}
|
||||
|
||||
#[derive(Debug, Deserialize, Serialize, Default, Clone)]
|
||||
#[derive(Debug, Deserialize, Serialize, Default, Clone, PartialEq, Eq)]
|
||||
/// See <https://discord.com/developers/docs/topics/gateway-events#voice-server-update>;
|
||||
///
|
||||
/// Received to indicate which voice endpoint, token and guild_id to use;
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
use crate::types::{Snowflake, WebSocketEvent};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Debug, Deserialize, Serialize, Default, Clone, PartialEq, Eq)]
|
||||
/// The identify payload for the webrtc stream;
|
||||
/// Contains info to begin a webrtc connection;
|
||||
/// See https://discord.com/developers/docs/topics/voice-connections#establishing-a-voice-websocket-connection-example-voice-identify-payload;
|
||||
pub struct VoiceIdentify {
|
||||
server_id: Snowflake,
|
||||
user_id: Snowflake,
|
||||
session_id: String,
|
||||
token: String,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
/// Undocumented field, but is also in discord client comms
|
||||
video: Option<bool>,
|
||||
}
|
||||
|
||||
impl WebSocketEvent for VoiceIdentify {}
|
|
@ -0,0 +1,5 @@
|
|||
pub use identify::*;
|
||||
pub use ready::*;
|
||||
|
||||
mod identify;
|
||||
mod ready;
|
|
@ -0,0 +1,29 @@
|
|||
use std::net::Ipv4Addr;
|
||||
|
||||
use crate::types::WebSocketEvent;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Debug, Deserialize, Serialize, Clone, PartialEq, Eq)]
|
||||
/// The ready event for the webrtc stream;
|
||||
/// Used to give info after the identify event;
|
||||
/// See https://discord.com/developers/docs/topics/voice-connections#establishing-a-voice-websocket-connection-example-voice-ready-payload;
|
||||
pub struct VoiceReady {
|
||||
ssrc: i32,
|
||||
ip: Ipv4Addr,
|
||||
port: u32,
|
||||
modes: Vec<String>,
|
||||
// Heartbeat interval is also sent, but is "an erroneous field and should be ignored. The correct heartbeat_interval value comes from the Hello payload."
|
||||
}
|
||||
|
||||
impl Default for VoiceReady {
|
||||
fn default() -> Self {
|
||||
VoiceReady {
|
||||
ssrc: 1,
|
||||
ip: Ipv4Addr::UNSPECIFIED,
|
||||
port: 0,
|
||||
modes: Vec::new(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl WebSocketEvent for VoiceReady {}
|
|
@ -2,7 +2,7 @@ use serde::{Deserialize, Serialize};
|
|||
|
||||
use crate::types::{entities::Emoji, Snowflake};
|
||||
|
||||
#[derive(Debug, Deserialize, Serialize, Clone)]
|
||||
#[derive(Debug, Deserialize, Serialize, Clone, PartialEq)]
|
||||
pub struct Activity {
|
||||
name: String,
|
||||
#[serde(rename = "type")]
|
||||
|
@ -22,19 +22,19 @@ pub struct Activity {
|
|||
buttons: Option<Vec<ActivityButton>>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize, Serialize, Clone)]
|
||||
#[derive(Debug, Deserialize, Serialize, Clone, Copy, PartialEq, Eq)]
|
||||
struct ActivityTimestamps {
|
||||
start: Option<i64>,
|
||||
end: Option<i64>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize, Serialize, Clone)]
|
||||
#[derive(Debug, Deserialize, Serialize, Clone, PartialEq, Eq)]
|
||||
struct ActivityParty {
|
||||
id: Option<String>,
|
||||
size: Option<Vec<(i32, i32)>>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize, Serialize, Clone)]
|
||||
#[derive(Debug, Deserialize, Serialize, Clone, PartialEq, Eq)]
|
||||
struct ActivityAssets {
|
||||
large_image: Option<String>,
|
||||
large_text: Option<String>,
|
||||
|
@ -42,7 +42,7 @@ struct ActivityAssets {
|
|||
small_text: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize, Serialize, Clone)]
|
||||
#[derive(Debug, Deserialize, Serialize, Clone, PartialEq, Eq)]
|
||||
struct ActivitySecrets {
|
||||
join: Option<String>,
|
||||
spectate: Option<String>,
|
||||
|
@ -50,7 +50,7 @@ struct ActivitySecrets {
|
|||
match_string: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize, Serialize, Clone)]
|
||||
#[derive(Debug, Deserialize, Serialize, Clone, PartialEq, Eq)]
|
||||
struct ActivityButton {
|
||||
label: String,
|
||||
url: String,
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Debug, Deserialize, Serialize, Default, Clone)]
|
||||
#[derive(Debug, Deserialize, Serialize, Default, Clone, PartialEq, Eq)]
|
||||
/// See <https://discord.com/developers/docs/topics/gateway-events#client-status-object>
|
||||
pub struct ClientStatusObject {
|
||||
pub desktop: Option<String>,
|
||||
|
|
|
@ -4,7 +4,7 @@ use serde::{Deserialize, Serialize};
|
|||
|
||||
use crate::types::Snowflake;
|
||||
|
||||
#[derive(Debug, Deserialize, Serialize)]
|
||||
#[derive(Debug, Deserialize, Serialize, Clone, PartialEq, Eq)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
/// A schema used to modify a user.
|
||||
pub struct UserModifySchema {
|
||||
|
@ -29,7 +29,7 @@ pub struct UserModifySchema {
|
|||
///
|
||||
/// # Reference:
|
||||
/// Read: <https://discord-userdoccers.vercel.app/resources/channel#json-params>
|
||||
#[derive(Debug, Deserialize, Serialize)]
|
||||
#[derive(Debug, Deserialize, Serialize, Clone, PartialEq, Eq)]
|
||||
pub struct PrivateChannelCreateSchema {
|
||||
pub recipients: Option<Vec<Snowflake>>,
|
||||
pub access_tokens: Option<Vec<String>>,
|
||||
|
|
Loading…
Reference in New Issue