Merge branch 'main' into refactor/application-default
This commit is contained in:
commit
2a63b8ae97
|
@ -11,8 +11,10 @@ client = []
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
tokio = {version = "1.28.1", features = ["rt", "macros", "rt-multi-thread", "full"]}
|
tokio = {version = "1.28.1", features = ["rt", "macros", "rt-multi-thread", "full"]}
|
||||||
serde = {version = "1.0.162", features = ["derive"]}
|
serde = {version = "1.0.163", features = ["derive"]}
|
||||||
serde_json = { version = "1.0.96", features = ["raw_value"] }
|
serde_json = {version= "1.0.96", features = ["raw_value"]}
|
||||||
|
serde-aux = "4.2.0"
|
||||||
|
serde_with = "3.0.0"
|
||||||
serde_repr = "0.1.12"
|
serde_repr = "0.1.12"
|
||||||
reqwest = {version = "0.11.16", features = ["multipart"]}
|
reqwest = {version = "0.11.16", features = ["multipart"]}
|
||||||
url = "2.3.1"
|
url = "2.3.1"
|
||||||
|
@ -20,7 +22,7 @@ chrono = {version = "0.4.24", features = ["serde"]}
|
||||||
regex = "1.7.3"
|
regex = "1.7.3"
|
||||||
custom_error = "1.9.2"
|
custom_error = "1.9.2"
|
||||||
native-tls = "0.2.11"
|
native-tls = "0.2.11"
|
||||||
tokio-tungstenite = {version = "0.18.0", features = ["native-tls"]}
|
tokio-tungstenite = {version = "0.19.0", features = ["native-tls"]}
|
||||||
futures-util = "0.3.28"
|
futures-util = "0.3.28"
|
||||||
http = "0.2.9"
|
http = "0.2.9"
|
||||||
openssl = "0.10.52"
|
openssl = "0.10.52"
|
||||||
|
|
672
src/gateway.rs
672
src/gateway.rs
|
@ -40,11 +40,11 @@ pub struct GatewayHandle {
|
||||||
impl GatewayHandle {
|
impl GatewayHandle {
|
||||||
/// Sends json to the gateway with an opcode
|
/// Sends json to the gateway with an opcode
|
||||||
async fn send_json_event(&self, op: u8, to_send: serde_json::Value) {
|
async fn send_json_event(&self, op: u8, to_send: serde_json::Value) {
|
||||||
let gateway_payload = types::GatewayPayload {
|
|
||||||
|
let gateway_payload = types::GatewaySendPayload {
|
||||||
op,
|
op,
|
||||||
d: Some(to_send),
|
d: Some(to_send),
|
||||||
s: None,
|
s: None
|
||||||
t: None,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
let payload_json = serde_json::to_string(&gateway_payload).unwrap();
|
let payload_json = serde_json::to_string(&gateway_payload).unwrap();
|
||||||
|
@ -81,7 +81,7 @@ impl GatewayHandle {
|
||||||
self.send_json_event(3, to_send_value).await;
|
self.send_json_event(3, to_send_value).await;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Sends a Request Guild Members to the server
|
/// Sends a request guild members to the server
|
||||||
pub async fn send_request_guild_members(&self, to_send: types::GatewayRequestGuildMembers) {
|
pub async fn send_request_guild_members(&self, to_send: types::GatewayRequestGuildMembers) {
|
||||||
let to_send_value = serde_json::to_value(&to_send).unwrap();
|
let to_send_value = serde_json::to_value(&to_send).unwrap();
|
||||||
|
|
||||||
|
@ -90,14 +90,35 @@ impl GatewayHandle {
|
||||||
self.send_json_event(8, to_send_value).await;
|
self.send_json_event(8, to_send_value).await;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Sends a Request Guild Members to the server
|
/// Sends an update voice state to the server
|
||||||
pub async fn send_update_voice_state(&self, to_send: types::GatewayVoiceStateUpdate) {
|
pub async fn send_update_voice_state(&self, to_send: types::UpdateVoiceState) {
|
||||||
|
|
||||||
let to_send_value = serde_json::to_value(&to_send).unwrap();
|
let to_send_value = serde_json::to_value(&to_send).unwrap();
|
||||||
|
|
||||||
println!("GW: Sending Voice State Update..");
|
println!("GW: Sending Update Voice State..");
|
||||||
|
|
||||||
self.send_json_event(4, to_send_value).await;
|
self.send_json_event(4, to_send_value).await;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Sends a call sync to the server
|
||||||
|
pub async fn send_call_sync(&self, to_send: types::CallSync) {
|
||||||
|
|
||||||
|
let to_send_value = serde_json::to_value(&to_send).unwrap();
|
||||||
|
|
||||||
|
println!("GW: Sending Call Sync..");
|
||||||
|
|
||||||
|
self.send_json_event(13, to_send_value).await;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Sends a Lazy Request
|
||||||
|
pub async fn send_lazy_request(&self, to_send: types::LazyRequest) {
|
||||||
|
|
||||||
|
let to_send_value = serde_json::to_value(&to_send).unwrap();
|
||||||
|
|
||||||
|
println!("GW: Sending Lazy Request..");
|
||||||
|
|
||||||
|
self.send_json_event(14, to_send_value).await;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Gateway {
|
pub struct Gateway {
|
||||||
|
@ -120,6 +141,7 @@ impl Gateway {
|
||||||
let (ws_stream, _) = match connect_async_tls_with_config(
|
let (ws_stream, _) = match connect_async_tls_with_config(
|
||||||
&websocket_url,
|
&websocket_url,
|
||||||
None,
|
None,
|
||||||
|
false,
|
||||||
Some(Connector::NativeTls(
|
Some(Connector::NativeTls(
|
||||||
TlsConnector::builder().build().unwrap(),
|
TlsConnector::builder().build().unwrap(),
|
||||||
)),
|
)),
|
||||||
|
@ -145,8 +167,7 @@ impl Gateway {
|
||||||
// Wait for the first hello and then spawn both tasks so we avoid nested tasks
|
// Wait for the first hello and then spawn both tasks so we avoid nested tasks
|
||||||
// This automatically spawns the heartbeat task, but from the main thread
|
// This automatically spawns the heartbeat task, but from the main thread
|
||||||
let msg = ws_rx.next().await.unwrap().unwrap();
|
let msg = ws_rx.next().await.unwrap().unwrap();
|
||||||
let gateway_payload: types::GatewayPayload =
|
let gateway_payload: types::GatewayReceivePayload = serde_json::from_str(msg.to_text().unwrap()).unwrap();
|
||||||
serde_json::from_str(msg.to_text().unwrap()).unwrap();
|
|
||||||
|
|
||||||
if gateway_payload.op != 10 {
|
if gateway_payload.op != 10 {
|
||||||
println!("Recieved non hello on gateway init, what is happening?");
|
println!("Recieved non hello on gateway init, what is happening?");
|
||||||
|
@ -159,12 +180,8 @@ impl Gateway {
|
||||||
|
|
||||||
println!("GW: Received Hello");
|
println!("GW: Received Hello");
|
||||||
|
|
||||||
let gateway_hello: types::HelloData =
|
let gateway_hello: types::HelloData = serde_json::from_str(gateway_payload.d.unwrap().get()).unwrap();
|
||||||
serde_json::from_value(gateway_payload.d.unwrap()).unwrap();
|
gateway.heartbeat_handler = Some(HeartbeatHandler::new(gateway_hello.heartbeat_interval, shared_tx.clone()));
|
||||||
gateway.heartbeat_handler = Some(HeartbeatHandler::new(
|
|
||||||
gateway_hello.heartbeat_interval,
|
|
||||||
shared_tx.clone(),
|
|
||||||
));
|
|
||||||
|
|
||||||
// Now we can continously check for messages in a different task, since we aren't going to receive another hello
|
// Now we can continously check for messages in a different task, since we aren't going to receive another hello
|
||||||
task::spawn(async move {
|
task::spawn(async move {
|
||||||
|
@ -190,325 +207,306 @@ impl Gateway {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let msg_string = msg.to_string();
|
let gateway_payload: types::GatewayReceivePayload = serde_json::from_str(msg.to_text().unwrap()).unwrap();
|
||||||
|
|
||||||
let gateway_payload: types::GatewayPayload = serde_json::from_str(&msg_string).unwrap();
|
|
||||||
|
|
||||||
// See https://discord.com/developers/docs/topics/opcodes-and-status-codes#gateway-gateway-opcodes
|
// See https://discord.com/developers/docs/topics/opcodes-and-status-codes#gateway-gateway-opcodes
|
||||||
match gateway_payload.op {
|
match gateway_payload.op {
|
||||||
// Dispatch
|
// Dispatch
|
||||||
// An event was dispatched, we need to look at the gateway event name t
|
// An event was dispatched, we need to look at the gateway event name t
|
||||||
0 => {
|
0 => {
|
||||||
let gateway_payload_t = gateway_payload.t.unwrap();
|
let gateway_payload_t = gateway_payload.clone().t.unwrap();
|
||||||
|
|
||||||
println!("GW: Received {}..", gateway_payload_t);
|
println!("GW: Received {}..", gateway_payload_t);
|
||||||
|
|
||||||
|
//println!("Event data dump: {}", gateway_payload.d.clone().unwrap().get());
|
||||||
|
|
||||||
// See https://discord.com/developers/docs/topics/gateway-events#receive-events
|
// See https://discord.com/developers/docs/topics/gateway-events#receive-events
|
||||||
|
// "Some" of these are uncodumented
|
||||||
match gateway_payload_t.as_str() {
|
match gateway_payload_t.as_str() {
|
||||||
"READY" => {
|
"READY" => {
|
||||||
let _data: types::GatewayReady =
|
let new_data: types::GatewayReady = serde_json::from_str(gateway_payload.d.unwrap().get()).unwrap();
|
||||||
serde_json::from_value(gateway_payload.d.unwrap()).unwrap();
|
self.events.lock().await.session.ready.update_data(new_data).await;
|
||||||
|
},
|
||||||
|
"READY_SUPPLEMENTAL" => {
|
||||||
|
let new_data: types::GatewayReadySupplemental = serde_json::from_str(gateway_payload.d.unwrap().get()).unwrap();
|
||||||
|
self.events.lock().await.session.ready_supplimental.update_data(new_data).await;
|
||||||
}
|
}
|
||||||
"RESUMED" => {}
|
"RESUMED" => {}
|
||||||
"APPLICATION_COMMAND_PERMISSIONS_UPDATE" => {}
|
"APPLICATION_COMMAND_PERMISSIONS_UPDATE" => {
|
||||||
"AUTO_MODERATION_RULE_CREATE" => {}
|
let new_data: types::ApplicationCommandPermissionsUpdate = serde_json::from_str(gateway_payload.d.unwrap().get()).unwrap();
|
||||||
"AUTO_MODERATION_RULE_UPDATE" => {}
|
self.events.lock().await.application.command_permissions_update.update_data(new_data).await;
|
||||||
"AUTO_MODERATION_RULE_DELETE" => {}
|
}
|
||||||
"AUTO_MODERATION_ACTION_EXECUTION" => {}
|
"AUTO_MODERATION_RULE_CREATE" => {
|
||||||
|
let new_data: types::AutoModerationRuleCreate = serde_json::from_str(gateway_payload.d.unwrap().get()).unwrap();
|
||||||
|
self.events.lock().await.auto_moderation.rule_create.update_data(new_data).await;
|
||||||
|
}
|
||||||
|
"AUTO_MODERATION_RULE_UPDATE" => {
|
||||||
|
let new_data: types::AutoModerationRuleUpdate = serde_json::from_str(gateway_payload.d.unwrap().get()).unwrap();
|
||||||
|
self.events.lock().await.auto_moderation.rule_update.update_data(new_data).await;
|
||||||
|
}
|
||||||
|
"AUTO_MODERATION_RULE_DELETE" => {
|
||||||
|
let new_data: types::AutoModerationRuleDelete = serde_json::from_str(gateway_payload.d.unwrap().get()).unwrap();
|
||||||
|
self.events.lock().await.auto_moderation.rule_delete.update_data(new_data).await;
|
||||||
|
}
|
||||||
|
"AUTO_MODERATION_ACTION_EXECUTION" => {
|
||||||
|
let new_data: types::AutoModerationActionExecution = serde_json::from_str(gateway_payload.d.unwrap().get()).unwrap();
|
||||||
|
self.events.lock().await.auto_moderation.action_execution.update_data(new_data).await;
|
||||||
|
}
|
||||||
"CHANNEL_CREATE" => {
|
"CHANNEL_CREATE" => {
|
||||||
let channel: types::Channel =
|
let new_data: types::ChannelCreate = serde_json::from_str(gateway_payload.d.unwrap().get()).unwrap();
|
||||||
serde_json::from_value(gateway_payload.d.unwrap()).unwrap();
|
self.events.lock().await.channel.create.update_data(new_data).await;
|
||||||
let new_data = types::ChannelCreate { channel };
|
|
||||||
self.events
|
|
||||||
.lock()
|
|
||||||
.await
|
|
||||||
.channel
|
|
||||||
.create
|
|
||||||
.update_data(new_data)
|
|
||||||
.await;
|
|
||||||
}
|
}
|
||||||
"CHANNEL_UPDATE" => {
|
"CHANNEL_UPDATE" => {
|
||||||
let channel: types::Channel =
|
let new_data: types::ChannelUpdate = serde_json::from_str(gateway_payload.d.unwrap().get()).unwrap();
|
||||||
serde_json::from_value(gateway_payload.d.unwrap()).unwrap();
|
self.events.lock().await.channel.update.update_data(new_data).await;
|
||||||
let new_data = types::ChannelUpdate { channel };
|
}
|
||||||
self.events
|
"CHANNEL_UNREAD_UPDATE" => {
|
||||||
.lock()
|
let new_data: types::ChannelUnreadUpdate = serde_json::from_str(gateway_payload.d.unwrap().get()).unwrap();
|
||||||
.await
|
self.events.lock().await.channel.unread_update.update_data(new_data).await;
|
||||||
.channel
|
|
||||||
.update
|
|
||||||
.update_data(new_data)
|
|
||||||
.await;
|
|
||||||
}
|
}
|
||||||
"CHANNEL_DELETE" => {
|
"CHANNEL_DELETE" => {
|
||||||
let channel: types::Channel =
|
let new_data: types::ChannelDelete = serde_json::from_str(gateway_payload.d.unwrap().get()).unwrap();
|
||||||
serde_json::from_value(gateway_payload.d.unwrap()).unwrap();
|
self.events.lock().await.channel.delete.update_data(new_data).await;
|
||||||
let new_data = types::ChannelDelete { channel };
|
|
||||||
self.events
|
|
||||||
.lock()
|
|
||||||
.await
|
|
||||||
.channel
|
|
||||||
.delete
|
|
||||||
.update_data(new_data)
|
|
||||||
.await;
|
|
||||||
}
|
}
|
||||||
"CHANNEL_PINS_UPDATE" => {
|
"CHANNEL_PINS_UPDATE" => {
|
||||||
let new_data: types::ChannelPinsUpdate =
|
let new_data: types::ChannelPinsUpdate = serde_json::from_str(gateway_payload.d.unwrap().get()).unwrap();
|
||||||
serde_json::from_value(gateway_payload.d.unwrap()).unwrap();
|
self.events.lock().await.channel.pins_update.update_data(new_data).await;
|
||||||
self.events
|
}
|
||||||
.lock()
|
"CALL_CREATE" => {
|
||||||
.await
|
let new_data: types::CallCreate = serde_json::from_str(gateway_payload.d.unwrap().get()).unwrap();
|
||||||
.channel
|
self.events.lock().await.call.create.update_data(new_data).await;
|
||||||
.pins_update
|
},
|
||||||
.update_data(new_data)
|
"CALL_UPDATE" => {
|
||||||
.await;
|
let new_data: types::CallUpdate = serde_json::from_str(gateway_payload.d.unwrap().get()).unwrap();
|
||||||
|
self.events.lock().await.call.update.update_data(new_data).await;
|
||||||
|
}
|
||||||
|
"CALL_DELETE" => {
|
||||||
|
let new_data: types::CallDelete = serde_json::from_str(gateway_payload.d.unwrap().get()).unwrap();
|
||||||
|
self.events.lock().await.call.delete.update_data(new_data).await;
|
||||||
}
|
}
|
||||||
"THREAD_CREATE" => {
|
"THREAD_CREATE" => {
|
||||||
let thread: types::Channel =
|
let new_data: types::ThreadCreate = serde_json::from_str(gateway_payload.d.unwrap().get()).unwrap();
|
||||||
serde_json::from_value(gateway_payload.d.unwrap()).unwrap();
|
self.events.lock().await.thread.create.update_data(new_data).await;
|
||||||
let new_data = types::ThreadCreate { thread };
|
|
||||||
self.events
|
|
||||||
.lock()
|
|
||||||
.await
|
|
||||||
.thread
|
|
||||||
.create
|
|
||||||
.update_data(new_data)
|
|
||||||
.await;
|
|
||||||
}
|
}
|
||||||
"THREAD_UPDATE" => {
|
"THREAD_UPDATE" => {
|
||||||
let thread: types::Channel =
|
let new_data: types::ThreadUpdate = serde_json::from_str(gateway_payload.d.unwrap().get()).unwrap();
|
||||||
serde_json::from_value(gateway_payload.d.unwrap()).unwrap();
|
self.events.lock().await.thread.update.update_data(new_data).await;
|
||||||
let new_data = types::ThreadUpdate { thread };
|
|
||||||
self.events
|
|
||||||
.lock()
|
|
||||||
.await
|
|
||||||
.thread
|
|
||||||
.update
|
|
||||||
.update_data(new_data)
|
|
||||||
.await;
|
|
||||||
}
|
}
|
||||||
"THREAD_DELETE" => {
|
"THREAD_DELETE" => {
|
||||||
let thread: types::Channel =
|
let new_data: types::ThreadDelete = serde_json::from_str(gateway_payload.d.unwrap().get()).unwrap();
|
||||||
serde_json::from_value(gateway_payload.d.unwrap()).unwrap();
|
self.events.lock().await.thread.delete.update_data(new_data).await;
|
||||||
let new_data = types::ThreadDelete { thread };
|
|
||||||
self.events
|
|
||||||
.lock()
|
|
||||||
.await
|
|
||||||
.thread
|
|
||||||
.delete
|
|
||||||
.update_data(new_data)
|
|
||||||
.await;
|
|
||||||
}
|
}
|
||||||
"THREAD_LIST_SYNC" => {
|
"THREAD_LIST_SYNC" => {
|
||||||
let new_data: types::ThreadListSync =
|
let new_data: types::ThreadListSync = serde_json::from_str(gateway_payload.d.unwrap().get()).unwrap();
|
||||||
serde_json::from_value(gateway_payload.d.unwrap()).unwrap();
|
self.events.lock().await.thread.list_sync.update_data(new_data).await;
|
||||||
self.events
|
|
||||||
.lock()
|
|
||||||
.await
|
|
||||||
.thread
|
|
||||||
.list_sync
|
|
||||||
.update_data(new_data)
|
|
||||||
.await;
|
|
||||||
}
|
}
|
||||||
"THREAD_MEMBER_UPDATE" => {
|
"THREAD_MEMBER_UPDATE" => {
|
||||||
let new_data: types::ThreadMemberUpdate =
|
let new_data: types::ThreadMemberUpdate = serde_json::from_str(gateway_payload.d.unwrap().get()).unwrap();
|
||||||
serde_json::from_value(gateway_payload.d.unwrap()).unwrap();
|
self.events.lock().await.thread.member_update.update_data(new_data).await;
|
||||||
self.events
|
|
||||||
.lock()
|
|
||||||
.await
|
|
||||||
.thread
|
|
||||||
.member_update
|
|
||||||
.update_data(new_data)
|
|
||||||
.await;
|
|
||||||
}
|
}
|
||||||
"THREAD_MEMBERS_UPDATE" => {
|
"THREAD_MEMBERS_UPDATE" => {
|
||||||
let new_data: types::ThreadMembersUpdate =
|
let new_data: types::ThreadMembersUpdate = serde_json::from_str(gateway_payload.d.unwrap().get()).unwrap();
|
||||||
serde_json::from_value(gateway_payload.d.unwrap()).unwrap();
|
self.events.lock().await.thread.members_update.update_data(new_data).await;
|
||||||
self.events
|
|
||||||
.lock()
|
|
||||||
.await
|
|
||||||
.thread
|
|
||||||
.members_update
|
|
||||||
.update_data(new_data)
|
|
||||||
.await;
|
|
||||||
}
|
}
|
||||||
"GUILD_CREATE" => {
|
"GUILD_CREATE" => {
|
||||||
let new_data: types::GuildCreate =
|
let new_data: types::GuildCreate = serde_json::from_str(gateway_payload.d.unwrap().get()).unwrap();
|
||||||
serde_json::from_str(&msg_string).unwrap();
|
self.events.lock().await.guild.create.update_data(new_data).await;
|
||||||
self.events
|
}
|
||||||
.lock()
|
"GUILD_UPDATE" => {
|
||||||
.await
|
let new_data: types::GuildUpdate = serde_json::from_str(gateway_payload.d.unwrap().get()).unwrap();
|
||||||
.guild
|
self.events.lock().await.guild.update.update_data(new_data).await;
|
||||||
.create
|
|
||||||
.update_data(new_data)
|
|
||||||
.await;
|
|
||||||
}
|
}
|
||||||
"GUILD_UPDATE" => {}
|
|
||||||
"GUILD_DELETE" => {
|
"GUILD_DELETE" => {
|
||||||
let _new_data: types::UnavailableGuild =
|
let new_data: types::GuildDelete = serde_json::from_str(gateway_payload.d.unwrap().get()).unwrap();
|
||||||
serde_json::from_value(gateway_payload.d.unwrap()).unwrap();
|
self.events.lock().await.guild.delete.update_data(new_data).await;
|
||||||
|
}
|
||||||
|
"GUILD_AUDIT_LOG_ENTRY_CREATE" => {
|
||||||
|
let new_data: types::GuildAuditLogEntryCreate = serde_json::from_str(gateway_payload.d.unwrap().get()).unwrap();
|
||||||
|
self.events.lock().await.guild.audit_log_entry_create.update_data(new_data).await;
|
||||||
}
|
}
|
||||||
"GUILD_AUDIT_LOG_ENTRY_CREATE" => {}
|
|
||||||
"GUILD_BAN_ADD" => {
|
"GUILD_BAN_ADD" => {
|
||||||
let _new_data: types::GuildBanAdd =
|
let new_data: types::GuildBanAdd = serde_json::from_str(gateway_payload.d.unwrap().get()).unwrap();
|
||||||
serde_json::from_value(gateway_payload.d.unwrap()).unwrap();
|
self.events.lock().await.guild.ban_add.update_data(new_data).await;
|
||||||
}
|
}
|
||||||
"GUILD_BAN_REMOVE" => {
|
"GUILD_BAN_REMOVE" => {
|
||||||
let _new_data: types::GuildBanRemove =
|
let new_data: types::GuildBanRemove = serde_json::from_str(gateway_payload.d.unwrap().get()).unwrap();
|
||||||
serde_json::from_value(gateway_payload.d.unwrap()).unwrap();
|
self.events.lock().await.guild.ban_remove.update_data(new_data).await;
|
||||||
|
}
|
||||||
|
"GUILD_EMOJIS_UPDATE" => {
|
||||||
|
let new_data: types::GuildEmojisUpdate = serde_json::from_str(gateway_payload.d.unwrap().get()).unwrap();
|
||||||
|
self.events.lock().await.guild.emojis_update.update_data(new_data).await;
|
||||||
|
}
|
||||||
|
"GUILD_STICKERS_UPDATE" => {
|
||||||
|
let new_data: types::GuildStickersUpdate = serde_json::from_str(gateway_payload.d.unwrap().get()).unwrap();
|
||||||
|
self.events.lock().await.guild.stickers_update.update_data(new_data).await;
|
||||||
|
}
|
||||||
|
"GUILD_INTEGRATIONS_UPDATE" => {
|
||||||
|
let new_data: types::GuildIntegrationsUpdate = serde_json::from_str(gateway_payload.d.unwrap().get()).unwrap();
|
||||||
|
self.events.lock().await.guild.integrations_update.update_data(new_data).await;
|
||||||
|
}
|
||||||
|
"GUILD_MEMBER_ADD" => {
|
||||||
|
let new_data: types::GuildMemberAdd = serde_json::from_str(gateway_payload.d.unwrap().get()).unwrap();
|
||||||
|
self.events.lock().await.guild.member_add.update_data(new_data).await;
|
||||||
|
}
|
||||||
|
"GUILD_MEMBER_REMOVE" => {
|
||||||
|
let new_data: types::GuildMemberRemove = serde_json::from_str(gateway_payload.d.unwrap().get()).unwrap();
|
||||||
|
self.events.lock().await.guild.member_remove.update_data(new_data).await;
|
||||||
|
}
|
||||||
|
"GUILD_MEMBER_UPDATE" => {
|
||||||
|
let new_data: types::GuildMemberUpdate = serde_json::from_str(gateway_payload.d.unwrap().get()).unwrap();
|
||||||
|
self.events.lock().await.guild.member_update.update_data(new_data).await;
|
||||||
|
}
|
||||||
|
"GUILD_MEMBERS_CHUNK" => {
|
||||||
|
let new_data: types::GuildMembersChunk = serde_json::from_str(gateway_payload.d.unwrap().get()).unwrap();
|
||||||
|
self.events.lock().await.guild.members_chunk.update_data(new_data).await;
|
||||||
|
}
|
||||||
|
"GUILD_ROLE_CREATE" => {
|
||||||
|
let new_data: types::GuildRoleCreate = serde_json::from_str(gateway_payload.d.unwrap().get()).unwrap();
|
||||||
|
self.events.lock().await.guild.role_create.update_data(new_data).await;
|
||||||
|
}
|
||||||
|
"GUILD_ROLE_UPDATE" => {
|
||||||
|
let new_data: types::GuildRoleUpdate = serde_json::from_str(gateway_payload.d.unwrap().get()).unwrap();
|
||||||
|
self.events.lock().await.guild.role_update.update_data(new_data).await;
|
||||||
|
}
|
||||||
|
"GUILD_ROLE_DELETE" => {
|
||||||
|
let new_data: types::GuildRoleDelete = serde_json::from_str(gateway_payload.d.unwrap().get()).unwrap();
|
||||||
|
self.events.lock().await.guild.role_delete.update_data(new_data).await;
|
||||||
|
}
|
||||||
|
"GUILD_SCHEDULED_EVENT_CREATE" => {
|
||||||
|
let new_data: types::GuildScheduledEventCreate = serde_json::from_str(gateway_payload.d.unwrap().get()).unwrap();
|
||||||
|
self.events.lock().await.guild.role_scheduled_event_create.update_data(new_data).await;
|
||||||
|
}
|
||||||
|
"GUILD_SCHEDULED_EVENT_UPDATE" => {
|
||||||
|
let new_data: types::GuildScheduledEventUpdate = serde_json::from_str(gateway_payload.d.unwrap().get()).unwrap();
|
||||||
|
self.events.lock().await.guild.role_scheduled_event_update.update_data(new_data).await;
|
||||||
|
}
|
||||||
|
"GUILD_SCHEDULED_EVENT_DELETE" => {
|
||||||
|
let new_data: types::GuildScheduledEventDelete = serde_json::from_str(gateway_payload.d.unwrap().get()).unwrap();
|
||||||
|
self.events.lock().await.guild.role_scheduled_event_delete.update_data(new_data).await;
|
||||||
|
}
|
||||||
|
"GUILD_SCHEDULED_EVENT_USER_ADD" => {
|
||||||
|
let new_data: types::GuildScheduledEventUserAdd = serde_json::from_str(gateway_payload.d.unwrap().get()).unwrap();
|
||||||
|
self.events.lock().await.guild.role_scheduled_event_user_add.update_data(new_data).await;
|
||||||
|
}
|
||||||
|
"GUILD_SCHEDULED_EVENT_USER_REMOVE" => {
|
||||||
|
let new_data: types::GuildScheduledEventUserRemove = serde_json::from_str(gateway_payload.d.unwrap().get()).unwrap();
|
||||||
|
self.events.lock().await.guild.role_scheduled_event_user_remove.update_data(new_data).await;
|
||||||
|
}
|
||||||
|
"PASSIVE_UPDATE_V1" => {
|
||||||
|
let new_data: types::PassiveUpdateV1 = serde_json::from_str(gateway_payload.d.unwrap().get()).unwrap();
|
||||||
|
self.events.lock().await.guild.passive_update_v1.update_data(new_data).await;
|
||||||
|
}
|
||||||
|
"INTEGRATION_CREATE" => {
|
||||||
|
let new_data: types::IntegrationCreate = serde_json::from_str(gateway_payload.d.unwrap().get()).unwrap();
|
||||||
|
self.events.lock().await.integration.create.update_data(new_data).await;
|
||||||
|
}
|
||||||
|
"INTEGRATION_UPDATE" => {
|
||||||
|
let new_data: types::IntegrationUpdate = serde_json::from_str(gateway_payload.d.unwrap().get()).unwrap();
|
||||||
|
self.events.lock().await.integration.update.update_data(new_data).await;
|
||||||
|
}
|
||||||
|
"INTEGRATION_DELETE" => {
|
||||||
|
let new_data: types::IntegrationDelete = serde_json::from_str(gateway_payload.d.unwrap().get()).unwrap();
|
||||||
|
self.events.lock().await.integration.delete.update_data(new_data).await;
|
||||||
|
}
|
||||||
|
"INTERACTION_CREATE" => {
|
||||||
|
let new_data: types::InteractionCreate = serde_json::from_str(gateway_payload.d.unwrap().get()).unwrap();
|
||||||
|
self.events.lock().await.interaction.create.update_data(new_data).await;
|
||||||
|
}
|
||||||
|
"INVITE_CREATE" => {
|
||||||
|
let new_data: types::InviteCreate = serde_json::from_str(gateway_payload.d.unwrap().get()).unwrap();
|
||||||
|
self.events.lock().await.invite.create.update_data(new_data).await;
|
||||||
|
}
|
||||||
|
"INVITE_DELETE" => {
|
||||||
|
let new_data: types::InviteDelete = serde_json::from_str(gateway_payload.d.unwrap().get()).unwrap();
|
||||||
|
self.events.lock().await.invite.delete.update_data(new_data).await;
|
||||||
}
|
}
|
||||||
"GUILD_EMOJIS_UPDATE" => {}
|
|
||||||
"GUILD_STICKERS_UPDATE" => {}
|
|
||||||
"GUILD_INTEGRATIONS_UPDATE" => {}
|
|
||||||
"GUILD_MEMBER_ADD" => {}
|
|
||||||
"GUILD_MEMBER_REMOVE" => {}
|
|
||||||
"GUILD_MEMBER_UPDATE" => {}
|
|
||||||
"GUILD_MEMBERS_CHUNK" => {}
|
|
||||||
"GUILD_ROLE_CREATE" => {}
|
|
||||||
"GUILD_ROLE_UPDATE" => {}
|
|
||||||
"GUILD_ROLE_DELETE" => {}
|
|
||||||
"GUILD_SCHEDULED_EVENT_CREATE" => {}
|
|
||||||
"GUILD_SCHEDULED_EVENT_UPDATE" => {}
|
|
||||||
"GUILD_SCHEDULED_EVENT_DELETE" => {}
|
|
||||||
"GUILD_SCHEDULED_EVENT_USER_ADD" => {}
|
|
||||||
"GUILD_SCHEDULED_EVENT_USER_REMOVE" => {}
|
|
||||||
"INTEGRATION_CREATE" => {}
|
|
||||||
"INTEGRATION_UPDATE" => {}
|
|
||||||
"INTEGRATION_DELETE" => {}
|
|
||||||
"INTERACTION_CREATE" => {}
|
|
||||||
"INVITE_CREATE" => {}
|
|
||||||
"INVITE_DELETE" => {}
|
|
||||||
"MESSAGE_CREATE" => {
|
"MESSAGE_CREATE" => {
|
||||||
let new_data: types::MessageCreate =
|
let new_data: types::MessageCreate = serde_json::from_str(gateway_payload.d.unwrap().get()).unwrap();
|
||||||
serde_json::from_value(gateway_payload.d.unwrap()).unwrap();
|
self.events.lock().await.message.create.update_data(new_data).await;
|
||||||
self.events
|
|
||||||
.lock()
|
|
||||||
.await
|
|
||||||
.message
|
|
||||||
.create
|
|
||||||
.update_data(new_data)
|
|
||||||
.await;
|
|
||||||
}
|
}
|
||||||
"MESSAGE_UPDATE" => {
|
"MESSAGE_UPDATE" => {
|
||||||
let new_data: types::MessageUpdate =
|
let new_data: types::MessageUpdate = serde_json::from_str(gateway_payload.d.unwrap().get()).unwrap();
|
||||||
serde_json::from_value(gateway_payload.d.unwrap()).unwrap();
|
self.events.lock().await.message.update.update_data(new_data).await;
|
||||||
self.events
|
|
||||||
.lock()
|
|
||||||
.await
|
|
||||||
.message
|
|
||||||
.update
|
|
||||||
.update_data(new_data)
|
|
||||||
.await;
|
|
||||||
}
|
}
|
||||||
"MESSAGE_DELETE" => {
|
"MESSAGE_DELETE" => {
|
||||||
let new_data: types::MessageDelete =
|
let new_data: types::MessageDelete = serde_json::from_str(gateway_payload.d.unwrap().get()).unwrap();
|
||||||
serde_json::from_value(gateway_payload.d.unwrap()).unwrap();
|
self.events.lock().await.message.delete.update_data(new_data).await;
|
||||||
self.events
|
|
||||||
.lock()
|
|
||||||
.await
|
|
||||||
.message
|
|
||||||
.delete
|
|
||||||
.update_data(new_data)
|
|
||||||
.await;
|
|
||||||
}
|
}
|
||||||
"MESSAGE_DELETE_BULK" => {
|
"MESSAGE_DELETE_BULK" => {
|
||||||
let new_data: types::MessageDeleteBulk =
|
let new_data: types::MessageDeleteBulk = serde_json::from_str(gateway_payload.d.unwrap().get()).unwrap();
|
||||||
serde_json::from_value(gateway_payload.d.unwrap()).unwrap();
|
self.events.lock().await.message.delete_bulk.update_data(new_data).await;
|
||||||
self.events
|
|
||||||
.lock()
|
|
||||||
.await
|
|
||||||
.message
|
|
||||||
.delete_bulk
|
|
||||||
.update_data(new_data)
|
|
||||||
.await;
|
|
||||||
}
|
}
|
||||||
"MESSAGE_REACTION_ADD" => {
|
"MESSAGE_REACTION_ADD" => {
|
||||||
let new_data: types::MessageReactionAdd =
|
let new_data: types::MessageReactionAdd = serde_json::from_str(gateway_payload.d.unwrap().get()).unwrap();
|
||||||
serde_json::from_value(gateway_payload.d.unwrap()).unwrap();
|
self.events.lock().await.message.reaction_add.update_data(new_data).await;
|
||||||
self.events
|
|
||||||
.lock()
|
|
||||||
.await
|
|
||||||
.message
|
|
||||||
.reaction_add
|
|
||||||
.update_data(new_data)
|
|
||||||
.await;
|
|
||||||
}
|
}
|
||||||
"MESSAGE_REACTION_REMOVE" => {
|
"MESSAGE_REACTION_REMOVE" => {
|
||||||
let new_data: types::MessageReactionRemove =
|
let new_data: types::MessageReactionRemove = serde_json::from_str(gateway_payload.d.unwrap().get()).unwrap();
|
||||||
serde_json::from_value(gateway_payload.d.unwrap()).unwrap();
|
self.events.lock().await.message.reaction_remove.update_data(new_data).await;
|
||||||
self.events
|
|
||||||
.lock()
|
|
||||||
.await
|
|
||||||
.message
|
|
||||||
.reaction_remove
|
|
||||||
.update_data(new_data)
|
|
||||||
.await;
|
|
||||||
}
|
}
|
||||||
"MESSAGE_REACTION_REMOVE_ALL" => {
|
"MESSAGE_REACTION_REMOVE_ALL" => {
|
||||||
let new_data: types::MessageReactionRemoveAll =
|
let new_data: types::MessageReactionRemoveAll = serde_json::from_str(gateway_payload.d.unwrap().get()).unwrap();
|
||||||
serde_json::from_value(gateway_payload.d.unwrap()).unwrap();
|
self.events.lock().await.message.reaction_remove_all.update_data(new_data).await;
|
||||||
self.events
|
|
||||||
.lock()
|
|
||||||
.await
|
|
||||||
.message
|
|
||||||
.reaction_remove_all
|
|
||||||
.update_data(new_data)
|
|
||||||
.await;
|
|
||||||
}
|
}
|
||||||
"MESSAGE_REACTION_REMOVE_EMOJI" => {
|
"MESSAGE_REACTION_REMOVE_EMOJI" => {
|
||||||
let new_data: types::MessageReactionRemoveEmoji =
|
let new_data: types::MessageReactionRemoveEmoji= serde_json::from_str(gateway_payload.d.unwrap().get()).unwrap();
|
||||||
serde_json::from_value(gateway_payload.d.unwrap()).unwrap();
|
self.events.lock().await.message.reaction_remove_emoji.update_data(new_data).await;
|
||||||
self.events
|
},
|
||||||
.lock()
|
"MESSAGE_ACK" => {
|
||||||
.await
|
let new_data: types::MessageACK = serde_json::from_str(gateway_payload.d.unwrap().get()).unwrap();
|
||||||
.message
|
self.events.lock().await.message.ack.update_data(new_data).await;
|
||||||
.reaction_remove_emoji
|
|
||||||
.update_data(new_data)
|
|
||||||
.await;
|
|
||||||
}
|
}
|
||||||
"PRESENCE_UPDATE" => {
|
"PRESENCE_UPDATE" => {
|
||||||
let new_data: types::PresenceUpdate =
|
let new_data: types::PresenceUpdate = serde_json::from_str(gateway_payload.d.unwrap().get()).unwrap();
|
||||||
serde_json::from_value(gateway_payload.d.unwrap()).unwrap();
|
self.events.lock().await.user.presence_update.update_data(new_data).await;
|
||||||
self.events
|
}
|
||||||
.lock()
|
"RELATIONSHIP_ADD" => {
|
||||||
.await
|
let new_data: types::RelationshipAdd = serde_json::from_str(gateway_payload.d.unwrap().get()).unwrap();
|
||||||
.user
|
self.events.lock().await.relationship.add.update_data(new_data).await;
|
||||||
.presence_update
|
}
|
||||||
.update_data(new_data)
|
"RELATIONSHIP_REMOVE" => {
|
||||||
.await;
|
let new_data: types::RelationshipRemove = serde_json::from_str(gateway_payload.d.unwrap().get()).unwrap();
|
||||||
|
self.events.lock().await.relationship.remove.update_data(new_data).await;
|
||||||
|
}
|
||||||
|
"STAGE_INSTANCE_CREATE" => {
|
||||||
|
let new_data: types::StageInstanceCreate = serde_json::from_str(gateway_payload.d.unwrap().get()).unwrap();
|
||||||
|
self.events.lock().await.stage_instance.create.update_data(new_data).await;
|
||||||
|
}
|
||||||
|
"STAGE_INSTANCE_UPDATE" => {
|
||||||
|
let new_data: types::StageInstanceUpdate = serde_json::from_str(gateway_payload.d.unwrap().get()).unwrap();
|
||||||
|
self.events.lock().await.stage_instance.update.update_data(new_data).await;
|
||||||
|
}
|
||||||
|
"STAGE_INSTANCE_DELETE" => {
|
||||||
|
let new_data: types::StageInstanceDelete = serde_json::from_str(gateway_payload.d.unwrap().get()).unwrap();
|
||||||
|
self.events.lock().await.stage_instance.delete.update_data(new_data).await;
|
||||||
|
}
|
||||||
|
"SESSIONS_REPLACE" => {
|
||||||
|
let sessions: Vec<types::Session> = serde_json::from_str(gateway_payload.d.unwrap().get()).unwrap();
|
||||||
|
let new_data = types::SessionsReplace {sessions};
|
||||||
|
self.events.lock().await.session.replace.update_data(new_data).await;
|
||||||
}
|
}
|
||||||
"STAGE_INSTANCE_CREATE" => {}
|
|
||||||
"STAGE_INSTANCE_UPDATE" => {}
|
|
||||||
"STAGE_INSTANCE_DELETE" => {}
|
|
||||||
// Not documented in discord docs, I assume this isnt for bots / apps but is for users?
|
|
||||||
"SESSIONS_REPLACE" => {}
|
|
||||||
"TYPING_START" => {
|
"TYPING_START" => {
|
||||||
let new_data: types::TypingStartEvent =
|
let new_data: types::TypingStartEvent = serde_json::from_str(gateway_payload.d.unwrap().get()).unwrap();
|
||||||
serde_json::from_value(gateway_payload.d.unwrap()).unwrap();
|
self.events.lock().await.user.typing_start_event.update_data(new_data).await;
|
||||||
self.events
|
|
||||||
.lock()
|
|
||||||
.await
|
|
||||||
.user
|
|
||||||
.typing_start_event
|
|
||||||
.update_data(new_data)
|
|
||||||
.await;
|
|
||||||
}
|
}
|
||||||
"USER_UPDATE" => {
|
"USER_UPDATE" => {
|
||||||
let user: types::User =
|
let new_data: types::UserUpdate = serde_json::from_str(gateway_payload.d.unwrap().get()).unwrap();
|
||||||
serde_json::from_value(gateway_payload.d.unwrap()).unwrap();
|
self.events.lock().await.user.update.update_data(new_data).await;
|
||||||
let new_data = types::UserUpdate { user };
|
}
|
||||||
self.events
|
"VOICE_STATE_UPDATE" => {
|
||||||
.lock()
|
let new_data: types::VoiceStateUpdate = serde_json::from_str(gateway_payload.d.unwrap().get()).unwrap();
|
||||||
.await
|
self.events.lock().await.voice.state_update.update_data(new_data).await;
|
||||||
.user
|
}
|
||||||
.update
|
"VOICE_SERVER_UPDATE" => {
|
||||||
.update_data(new_data)
|
let new_data: types::VoiceServerUpdate = serde_json::from_str(gateway_payload.d.unwrap().get()).unwrap();
|
||||||
.await;
|
self.events.lock().await.voice.server_update.update_data(new_data).await;
|
||||||
|
}
|
||||||
|
"WEBHOOKS_UPDATE" => {
|
||||||
|
let new_data: types::WebhooksUpdate = serde_json::from_str(gateway_payload.d.unwrap().get()).unwrap();
|
||||||
|
self.events.lock().await.webhooks.update.update_data(new_data).await;
|
||||||
}
|
}
|
||||||
"VOICE_STATE_UPDATE" => {}
|
|
||||||
"VOICE_SERVER_UPDATE" => {}
|
|
||||||
"WEBHOOKS_UPDATE" => {}
|
|
||||||
_ => {
|
_ => {
|
||||||
panic!("Invalid gateway event ({})", &gateway_payload_t)
|
println!("Received unrecognised gateway event ({})! Please open an issue on the chorus github so we can implement it", &gateway_payload_t);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -533,15 +531,8 @@ impl Gateway {
|
||||||
11 => {
|
11 => {
|
||||||
println!("GW: Received Heartbeat ACK");
|
println!("GW: Received Heartbeat ACK");
|
||||||
}
|
}
|
||||||
2 | 3 | 4 | 6 | 8 => {
|
2 | 3 | 4 | 6 | 8 => {panic!("Received gateway op code that's meant to be sent, not received ({})", gateway_payload.op)}
|
||||||
panic!(
|
_ => {println!("Received unrecognised gateway op code ({})! Please open an issue on the chorus github so we can implement it", gateway_payload.op);}
|
||||||
"Received Gateway op code that's meant to be sent, not received ({})",
|
|
||||||
gateway_payload.op
|
|
||||||
)
|
|
||||||
}
|
|
||||||
_ => {
|
|
||||||
panic!("Received Invalid Gateway op code ({})", gateway_payload.op)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we have an active heartbeat thread and we received a seq number we should let it know
|
// If we have an active heartbeat thread and we received a seq number we should let it know
|
||||||
|
@ -727,15 +718,53 @@ mod events {
|
||||||
use super::*;
|
use super::*;
|
||||||
#[derive(Default, Debug)]
|
#[derive(Default, Debug)]
|
||||||
pub struct Events {
|
pub struct Events {
|
||||||
|
pub application: Application,
|
||||||
|
pub auto_moderation: AutoModeration,
|
||||||
|
pub session: Session,
|
||||||
pub message: Message,
|
pub message: Message,
|
||||||
pub user: User,
|
pub user: User,
|
||||||
|
pub relationship: Relationship,
|
||||||
pub channel: Channel,
|
pub channel: Channel,
|
||||||
pub thread: Thread,
|
pub thread: Thread,
|
||||||
pub guild: Guild,
|
pub guild: Guild,
|
||||||
|
pub invite: Invite,
|
||||||
|
pub integration: Integration,
|
||||||
|
pub interaction: Interaction,
|
||||||
|
pub stage_instance: StageInstance,
|
||||||
|
pub call: Call,
|
||||||
|
pub voice: Voice,
|
||||||
|
pub webhooks: Webhooks,
|
||||||
pub gateway_identify_payload: GatewayEvent<types::GatewayIdentifyPayload>,
|
pub gateway_identify_payload: GatewayEvent<types::GatewayIdentifyPayload>,
|
||||||
pub gateway_resume: GatewayEvent<types::GatewayResume>,
|
pub gateway_resume: GatewayEvent<types::GatewayResume>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Default, Debug)]
|
||||||
|
pub struct Application {
|
||||||
|
pub command_permissions_update: GatewayEvent<types::ApplicationCommandPermissionsUpdate>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Default, Debug)]
|
||||||
|
pub struct AutoModeration {
|
||||||
|
pub rule_create: GatewayEvent<types::AutoModerationRuleCreate>,
|
||||||
|
pub rule_update: GatewayEvent<types::AutoModerationRuleUpdate>,
|
||||||
|
pub rule_delete: GatewayEvent<types::AutoModerationRuleDelete>,
|
||||||
|
pub action_execution: GatewayEvent<types::AutoModerationActionExecution>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Default, Debug)]
|
||||||
|
pub struct Session {
|
||||||
|
pub ready: GatewayEvent<types::GatewayReady>,
|
||||||
|
pub ready_supplimental: GatewayEvent<types::GatewayReadySupplemental>,
|
||||||
|
pub replace: GatewayEvent<types::SessionsReplace>
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Default, Debug)]
|
||||||
|
pub struct StageInstance {
|
||||||
|
pub create: GatewayEvent<types::StageInstanceCreate>,
|
||||||
|
pub update: GatewayEvent<types::StageInstanceUpdate>,
|
||||||
|
pub delete: GatewayEvent<types::StageInstanceDelete>,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Default, Debug)]
|
#[derive(Default, Debug)]
|
||||||
pub struct Message {
|
pub struct Message {
|
||||||
pub create: GatewayEvent<types::MessageCreate>,
|
pub create: GatewayEvent<types::MessageCreate>,
|
||||||
|
@ -746,6 +775,7 @@ mod events {
|
||||||
pub reaction_remove: GatewayEvent<types::MessageReactionRemove>,
|
pub reaction_remove: GatewayEvent<types::MessageReactionRemove>,
|
||||||
pub reaction_remove_all: GatewayEvent<types::MessageReactionRemoveAll>,
|
pub reaction_remove_all: GatewayEvent<types::MessageReactionRemoveAll>,
|
||||||
pub reaction_remove_emoji: GatewayEvent<types::MessageReactionRemoveEmoji>,
|
pub reaction_remove_emoji: GatewayEvent<types::MessageReactionRemoveEmoji>,
|
||||||
|
pub ack: GatewayEvent<types::MessageACK>
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Default, Debug)]
|
#[derive(Default, Debug)]
|
||||||
|
@ -755,10 +785,17 @@ mod events {
|
||||||
pub typing_start_event: GatewayEvent<types::TypingStartEvent>,
|
pub typing_start_event: GatewayEvent<types::TypingStartEvent>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Default, Debug)]
|
||||||
|
pub struct Relationship {
|
||||||
|
pub add: GatewayEvent<types::RelationshipAdd>,
|
||||||
|
pub remove: GatewayEvent<types::RelationshipRemove>,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Default, Debug)]
|
#[derive(Default, Debug)]
|
||||||
pub struct Channel {
|
pub struct Channel {
|
||||||
pub create: GatewayEvent<types::ChannelCreate>,
|
pub create: GatewayEvent<types::ChannelCreate>,
|
||||||
pub update: GatewayEvent<types::ChannelUpdate>,
|
pub update: GatewayEvent<types::ChannelUpdate>,
|
||||||
|
pub unread_update: GatewayEvent<types::ChannelUnreadUpdate>,
|
||||||
pub delete: GatewayEvent<types::ChannelDelete>,
|
pub delete: GatewayEvent<types::ChannelDelete>,
|
||||||
pub pins_update: GatewayEvent<types::ChannelPinsUpdate>,
|
pub pins_update: GatewayEvent<types::ChannelPinsUpdate>,
|
||||||
}
|
}
|
||||||
|
@ -776,26 +813,63 @@ mod events {
|
||||||
#[derive(Default, Debug)]
|
#[derive(Default, Debug)]
|
||||||
pub struct Guild {
|
pub struct Guild {
|
||||||
pub create: GatewayEvent<types::GuildCreate>,
|
pub create: GatewayEvent<types::GuildCreate>,
|
||||||
/*pub update: GatewayEvent<ThreadCreate>,
|
pub update: GatewayEvent<types::GuildUpdate>,
|
||||||
pub delete: GatewayEvent<ThreadCreate>,
|
pub delete: GatewayEvent<types::GuildDelete>,
|
||||||
pub audit_log_entry_create: GatewayEvent<ThreadCreate>,
|
pub audit_log_entry_create: GatewayEvent<types::GuildAuditLogEntryCreate>,
|
||||||
pub ban_add: GatewayEvent<ThreadCreate>,
|
pub ban_add: GatewayEvent<types::GuildBanAdd>,
|
||||||
pub ban_remove: GatewayEvent<ThreadCreate>,
|
pub ban_remove: GatewayEvent<types::GuildBanRemove>,
|
||||||
pub emojis_update: GatewayEvent<ThreadCreate>,
|
pub emojis_update: GatewayEvent<types::GuildEmojisUpdate>,
|
||||||
pub stickers_update: GatewayEvent<ThreadCreate>,
|
pub stickers_update: GatewayEvent<types::GuildStickersUpdate>,
|
||||||
pub integrations_update: GatewayEvent<ThreadCreate>,
|
pub integrations_update: GatewayEvent<types::GuildIntegrationsUpdate>,
|
||||||
pub member_add: GatewayEvent<ThreadCreate>,
|
pub member_add: GatewayEvent<types::GuildMemberAdd>,
|
||||||
pub member_remove: GatewayEvent<ThreadCreate>,
|
pub member_remove: GatewayEvent<types::GuildMemberRemove>,
|
||||||
pub member_update: GatewayEvent<ThreadCreate>,
|
pub member_update: GatewayEvent<types::GuildMemberUpdate>,
|
||||||
pub members_chunk: GatewayEvent<ThreadCreate>,
|
pub members_chunk: GatewayEvent<types::GuildMembersChunk>,
|
||||||
pub role_create: GatewayEvent<ThreadCreate>,
|
pub role_create: GatewayEvent<types::GuildRoleCreate>,
|
||||||
pub role_update: GatewayEvent<ThreadCreate>,
|
pub role_update: GatewayEvent<types::GuildRoleUpdate>,
|
||||||
pub role_delete: GatewayEvent<ThreadCreate>,
|
pub role_delete: GatewayEvent<types::GuildRoleDelete>,
|
||||||
pub role_scheduled_event_create: GatewayEvent<ThreadCreate>,
|
pub role_scheduled_event_create: GatewayEvent<types::GuildScheduledEventCreate>,
|
||||||
pub role_scheduled_event_update: GatewayEvent<ThreadCreate>,
|
pub role_scheduled_event_update: GatewayEvent<types::GuildScheduledEventUpdate>,
|
||||||
pub role_scheduled_event_delete: GatewayEvent<ThreadCreate>,
|
pub role_scheduled_event_delete: GatewayEvent<types::GuildScheduledEventDelete>,
|
||||||
pub role_scheduled_event_user_add: GatewayEvent<ThreadCreate>,
|
pub role_scheduled_event_user_add: GatewayEvent<types::GuildScheduledEventUserAdd>,
|
||||||
pub role_scheduled_event_user_remove: GatewayEvent<ThreadCreate>,*/
|
pub role_scheduled_event_user_remove: GatewayEvent<types::GuildScheduledEventUserRemove>,
|
||||||
|
pub passive_update_v1: GatewayEvent<types::PassiveUpdateV1>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Default, Debug)]
|
||||||
|
pub struct Invite {
|
||||||
|
pub create: GatewayEvent<types::InviteCreate>,
|
||||||
|
pub delete: GatewayEvent<types::InviteDelete>
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Default, Debug)]
|
||||||
|
pub struct Integration {
|
||||||
|
pub create: GatewayEvent<types::IntegrationCreate>,
|
||||||
|
pub update: GatewayEvent<types::IntegrationUpdate>,
|
||||||
|
pub delete: GatewayEvent<types::IntegrationDelete>
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Default, Debug)]
|
||||||
|
pub struct Interaction {
|
||||||
|
pub create: GatewayEvent<types::InteractionCreate>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Default, Debug)]
|
||||||
|
pub struct Call {
|
||||||
|
pub create: GatewayEvent<types::CallCreate>,
|
||||||
|
pub update: GatewayEvent<types::CallUpdate>,
|
||||||
|
pub delete: GatewayEvent<types::CallDelete>
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Default, Debug)]
|
||||||
|
pub struct Voice {
|
||||||
|
pub state_update: GatewayEvent<types::VoiceStateUpdate>,
|
||||||
|
pub server_update: GatewayEvent<types::VoiceServerUpdate>
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Default, Debug)]
|
||||||
|
pub struct Webhooks {
|
||||||
|
pub update: GatewayEvent<types::WebhooksUpdate>,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -165,3 +165,33 @@ pub struct ApplicationCommandInteractionDataOption {
|
||||||
pub value: Value,
|
pub value: Value,
|
||||||
pub options: Vec<ApplicationCommandInteractionDataOption>,
|
pub options: Vec<ApplicationCommandInteractionDataOption>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Default, Clone, PartialEq, Serialize, Deserialize)]
|
||||||
|
/// See https://discord.com/developers/docs/interactions/application-commands#application-command-permissions-object-guild-application-command-permissions-structure
|
||||||
|
pub struct GuildApplicationCommandPermissions {
|
||||||
|
pub id: Snowflake,
|
||||||
|
pub application_id: Snowflake,
|
||||||
|
pub guild_id: Snowflake,
|
||||||
|
pub permissions: Vec<ApplicationCommandPermission>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Default, Clone, PartialEq, Serialize, Deserialize)]
|
||||||
|
/// See https://discord.com/developers/docs/interactions/application-commands#application-command-permissions-object-application-command-permissions-structure
|
||||||
|
pub struct ApplicationCommandPermission {
|
||||||
|
pub id: Snowflake,
|
||||||
|
#[serde(rename = "type")]
|
||||||
|
pub permission_type: ApplicationCommandPermissionType,
|
||||||
|
/// true to allow, false, to disallow
|
||||||
|
pub permission: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize_repr, Deserialize_repr, Debug, Default, Clone, PartialEq)]
|
||||||
|
#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
|
||||||
|
#[repr(u8)]
|
||||||
|
/// See https://discord.com/developers/docs/interactions/application-commands#application-command-permissions-object-application-command-permission-type
|
||||||
|
pub enum ApplicationCommandPermissionType {
|
||||||
|
#[default]
|
||||||
|
Role = 1,
|
||||||
|
User = 2,
|
||||||
|
Channel = 3
|
||||||
|
}
|
|
@ -0,0 +1,25 @@
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
use crate::types::utils::Snowflake;
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, Debug, Default, Clone)]
|
||||||
|
/// See https://discord.com/developers/docs/resources/audit-log#audit-log-entry-object
|
||||||
|
pub struct AuditLogEntry {
|
||||||
|
pub target_id: Option<String>,
|
||||||
|
pub changes: Option<Vec<AuditLogChange>>,
|
||||||
|
pub user_id: Option<String>,
|
||||||
|
pub id: Snowflake,
|
||||||
|
// to:do implement an enum for these types
|
||||||
|
pub action_type: u8,
|
||||||
|
// to:do add better options type
|
||||||
|
pub options: Option<serde_json::Value>,
|
||||||
|
pub reason: Option<String>
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, Debug, Default, Clone)]
|
||||||
|
/// See https://discord.com/developers/docs/resources/audit-log#audit-log-change-object
|
||||||
|
pub struct AuditLogChange {
|
||||||
|
pub new_value: Option<serde_json::Value>,
|
||||||
|
pub old_value: Option<serde_json::Value>,
|
||||||
|
pub key: String
|
||||||
|
}
|
|
@ -0,0 +1,135 @@
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
use serde_repr::{Serialize_repr, Deserialize_repr};
|
||||||
|
|
||||||
|
use crate::types::utils::Snowflake;
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, Debug, Default, Clone)]
|
||||||
|
/// See https://discord.com/developers/docs/resources/auto-moderation#auto-moderation-rule-object
|
||||||
|
pub struct AutoModerationRule {
|
||||||
|
pub id: Snowflake,
|
||||||
|
pub guild_id: Snowflake,
|
||||||
|
pub name: String,
|
||||||
|
pub creator_id: Snowflake,
|
||||||
|
pub event_type: AutoModerationRuleEventType,
|
||||||
|
pub trigger_type: AutoModerationRuleTriggerType,
|
||||||
|
pub trigger_metadata: AutoModerationRuleTriggerMetadata,
|
||||||
|
pub actions: Vec<AutoModerationAction>,
|
||||||
|
pub enabled: bool,
|
||||||
|
pub exempt_roles: Vec<Snowflake>,
|
||||||
|
pub exempt_channels: Vec<Snowflake>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize_repr, Deserialize_repr, Debug, Clone, Default)]
|
||||||
|
#[repr(u8)]
|
||||||
|
#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
|
||||||
|
/// See https://discord.com/developers/docs/resources/auto-moderation#auto-moderation-rule-object-event-types
|
||||||
|
pub enum AutoModerationRuleEventType {
|
||||||
|
#[default]
|
||||||
|
MessageSend = 1
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize_repr, Deserialize_repr, Debug, Clone, Default)]
|
||||||
|
#[repr(u8)]
|
||||||
|
#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
|
||||||
|
/// See https://discord.com/developers/docs/resources/auto-moderation#auto-moderation-rule-object-trigger-types
|
||||||
|
pub enum AutoModerationRuleTriggerType {
|
||||||
|
#[default]
|
||||||
|
Keyword = 1,
|
||||||
|
Spam = 3,
|
||||||
|
KeywordPreset = 4,
|
||||||
|
MentionSpam = 5
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, Debug, Clone, Default)]
|
||||||
|
#[serde(untagged)]
|
||||||
|
/// See https://discord.com/developers/docs/resources/auto-moderation#auto-moderation-rule-object-trigger-metadata
|
||||||
|
pub enum AutoModerationRuleTriggerMetadata {
|
||||||
|
ForKeyword(AutoModerationRuleTriggerMetadataForKeyword),
|
||||||
|
ForKeywordPreset(AutoModerationRuleTriggerMetadataForKeywordPreset),
|
||||||
|
ForMentionSpam(AutoModerationRuleTriggerMetadataForMentionSpam),
|
||||||
|
#[default]
|
||||||
|
None
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, Debug, Clone, Default)]
|
||||||
|
/// See https://discord.com/developers/docs/resources/auto-moderation#auto-moderation-rule-object-trigger-metadata
|
||||||
|
pub struct AutoModerationRuleTriggerMetadataForKeyword {
|
||||||
|
pub keyword_filter: Vec<String>,
|
||||||
|
pub regex_patterns: Vec<String>,
|
||||||
|
pub allow_list: Vec<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, Debug, Clone, Default)]
|
||||||
|
/// See https://discord.com/developers/docs/resources/auto-moderation#auto-moderation-rule-object-trigger-metadata
|
||||||
|
pub struct AutoModerationRuleTriggerMetadataForKeywordPreset {
|
||||||
|
pub presets: Vec<AutoModerationRuleKeywordPresetType>,
|
||||||
|
pub allow_list: Vec<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, Debug, Clone, Default)]
|
||||||
|
/// See https://discord.com/developers/docs/resources/auto-moderation#auto-moderation-rule-object-trigger-metadata
|
||||||
|
pub struct AutoModerationRuleTriggerMetadataForMentionSpam {
|
||||||
|
/// Max 50
|
||||||
|
pub mention_total_limit: u8,
|
||||||
|
pub mention_raid_protection_enabled: bool
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize_repr, Deserialize_repr, Debug, Clone, Default)]
|
||||||
|
#[repr(u8)]
|
||||||
|
#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
|
||||||
|
/// See https://discord.com/developers/docs/resources/auto-moderation#auto-moderation-rule-object-keyword-preset-types
|
||||||
|
pub enum AutoModerationRuleKeywordPresetType {
|
||||||
|
#[default]
|
||||||
|
Profanity = 1,
|
||||||
|
SexualContent = 2,
|
||||||
|
Slurs = 3
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, Debug, Clone, Default)]
|
||||||
|
/// See https://discord.com/developers/docs/resources/auto-moderation#auto-moderation-action-object
|
||||||
|
pub struct AutoModerationAction {
|
||||||
|
#[serde(rename = "type")]
|
||||||
|
pub action_type: AutoModerationActionType,
|
||||||
|
pub metadata: Option<AutoModerationActionMetadata>
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize_repr, Deserialize_repr, Debug, Clone, Default)]
|
||||||
|
#[repr(u8)]
|
||||||
|
#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
|
||||||
|
/// See https://discord.com/developers/docs/resources/auto-moderation#auto-moderation-action-object-action-types
|
||||||
|
pub enum AutoModerationActionType {
|
||||||
|
#[default]
|
||||||
|
BlockMessage = 1,
|
||||||
|
SendAlertMessage = 2,
|
||||||
|
Timeout = 3
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, Debug, Clone, Default)]
|
||||||
|
#[serde(untagged)]
|
||||||
|
/// See https://discord.com/developers/docs/resources/auto-moderation#auto-moderation-action-object-action-metadata
|
||||||
|
pub enum AutoModerationActionMetadata {
|
||||||
|
ForBlockMessage(AutoModerationActionMetadataForBlockMessage),
|
||||||
|
ForSendAlertMessage(AutoModerationActionMetadataForSendAlertMessage),
|
||||||
|
ForTimeout(AutoModerationActionMetadataForTimeout),
|
||||||
|
#[default]
|
||||||
|
None
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, Debug, Clone, Default)]
|
||||||
|
/// See https://discord.com/developers/docs/resources/auto-moderation#auto-moderation-action-object-action-metadata
|
||||||
|
pub struct AutoModerationActionMetadataForBlockMessage {
|
||||||
|
pub custom_message: Option<String>
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, Debug, Clone, Default)]
|
||||||
|
/// See https://discord.com/developers/docs/resources/auto-moderation#auto-moderation-action-object-action-metadata
|
||||||
|
pub struct AutoModerationActionMetadataForSendAlertMessage {
|
||||||
|
pub channel_id: Snowflake
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, Debug, Clone, Default)]
|
||||||
|
/// See https://discord.com/developers/docs/resources/auto-moderation#auto-moderation-action-object-action-metadata
|
||||||
|
pub struct AutoModerationActionMetadataForTimeout {
|
||||||
|
/// Max 2419200
|
||||||
|
pub duration_seconds: u32,
|
||||||
|
}
|
|
@ -1,5 +1,6 @@
|
||||||
use chrono::Utc;
|
use chrono::Utc;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
use serde_aux::prelude::{deserialize_number_from_string, deserialize_option_number_from_string, deserialize_string_from_number};
|
||||||
use serde_repr::{Deserialize_repr, Serialize_repr};
|
use serde_repr::{Deserialize_repr, Serialize_repr};
|
||||||
|
|
||||||
use crate::types::{
|
use crate::types::{
|
||||||
|
@ -66,9 +67,13 @@ pub struct Channel {
|
||||||
|
|
||||||
#[derive(Debug, Deserialize, Serialize, Clone, PartialEq, Eq)]
|
#[derive(Debug, Deserialize, Serialize, Clone, PartialEq, Eq)]
|
||||||
pub struct Tag {
|
pub struct Tag {
|
||||||
|
#[serde(default)]
|
||||||
|
#[serde(deserialize_with = "deserialize_number_from_string")]
|
||||||
pub id: u64,
|
pub id: u64,
|
||||||
pub name: String,
|
pub name: String,
|
||||||
pub moderated: bool,
|
pub moderated: bool,
|
||||||
|
#[serde(default)]
|
||||||
|
#[serde(deserialize_with = "deserialize_option_number_from_string")]
|
||||||
pub emoji_id: Option<u64>,
|
pub emoji_id: Option<u64>,
|
||||||
pub emoji_name: Option<String>,
|
pub emoji_name: Option<String>,
|
||||||
}
|
}
|
||||||
|
@ -77,8 +82,13 @@ pub struct Tag {
|
||||||
pub struct PermissionOverwrite {
|
pub struct PermissionOverwrite {
|
||||||
pub id: String,
|
pub id: String,
|
||||||
#[serde(rename = "type")]
|
#[serde(rename = "type")]
|
||||||
pub overwrite_type: u8,
|
#[serde(deserialize_with = "deserialize_string_from_number")]
|
||||||
|
pub overwrite_type: String,
|
||||||
|
#[serde(default)]
|
||||||
|
#[serde(deserialize_with = "deserialize_string_from_number")]
|
||||||
pub allow: String,
|
pub allow: String,
|
||||||
|
#[serde(default)]
|
||||||
|
#[serde(deserialize_with = "deserialize_string_from_number")]
|
||||||
pub deny: String,
|
pub deny: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -103,7 +113,9 @@ pub struct ThreadMember {
|
||||||
|
|
||||||
#[derive(Debug, Deserialize, Serialize, Clone, PartialEq, Eq)]
|
#[derive(Debug, Deserialize, Serialize, Clone, PartialEq, Eq)]
|
||||||
pub struct DefaultReaction {
|
pub struct DefaultReaction {
|
||||||
pub emoji_id: Option<String>,
|
#[serde(default)]
|
||||||
|
#[serde(deserialize_with = "deserialize_option_number_from_string")]
|
||||||
|
pub emoji_id: Option<u64>,
|
||||||
pub emoji_name: Option<String>,
|
pub emoji_name: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
use serde_aux::prelude::deserialize_option_number_from_string;
|
||||||
|
|
||||||
use crate::types::entities::User;
|
use crate::types::entities::User;
|
||||||
use crate::types::{Guild, Snowflake};
|
use crate::types::{Guild, Snowflake};
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
use chrono::{DateTime, Utc};
|
use chrono::{DateTime, Utc};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
use serde_repr::{Serialize_repr, Deserialize_repr};
|
||||||
|
|
||||||
use crate::types::{
|
use crate::types::{
|
||||||
entities::{Channel, Emoji, GuildTemplate, RoleObject, Sticker, User, VoiceState, Webhook},
|
entities::{Channel, Emoji, GuildTemplate, RoleObject, Sticker, User, VoiceState, Webhook},
|
||||||
|
@ -12,7 +13,7 @@ use crate::types::{
|
||||||
#[cfg_attr(feature = "sqlx", derive(sqlx::FromRow))]
|
#[cfg_attr(feature = "sqlx", derive(sqlx::FromRow))]
|
||||||
pub struct Guild {
|
pub struct Guild {
|
||||||
pub id: Snowflake,
|
pub id: Snowflake,
|
||||||
pub name: String,
|
pub name: Option<String>,
|
||||||
pub icon: Option<String>,
|
pub icon: Option<String>,
|
||||||
pub icon_hash: Option<String>,
|
pub icon_hash: Option<String>,
|
||||||
pub splash: Option<String>,
|
pub splash: Option<String>,
|
||||||
|
@ -33,7 +34,7 @@ pub struct Guild {
|
||||||
#[cfg_attr(feature = "sqlx", sqlx(skip))]
|
#[cfg_attr(feature = "sqlx", sqlx(skip))]
|
||||||
pub emojis: Vec<Emoji>,
|
pub emojis: Vec<Emoji>,
|
||||||
#[cfg_attr(feature = "sqlx", sqlx(skip))]
|
#[cfg_attr(feature = "sqlx", sqlx(skip))]
|
||||||
pub features: Vec<String>,
|
pub features: Option<Vec<String>>,
|
||||||
pub application_id: Option<String>,
|
pub application_id: Option<String>,
|
||||||
pub system_channel_id: Option<Snowflake>,
|
pub system_channel_id: Option<Snowflake>,
|
||||||
pub system_channel_flags: Option<u8>,
|
pub system_channel_flags: Option<u8>,
|
||||||
|
@ -56,7 +57,7 @@ pub struct Guild {
|
||||||
pub welcome_screen: Option<sqlx::types::Json<WelcomeScreenObject>>,
|
pub welcome_screen: Option<sqlx::types::Json<WelcomeScreenObject>>,
|
||||||
#[cfg(not(feature = "sqlx"))]
|
#[cfg(not(feature = "sqlx"))]
|
||||||
pub welcome_screen: Option<WelcomeScreenObject>,
|
pub welcome_screen: Option<WelcomeScreenObject>,
|
||||||
pub nsfw_level: u8,
|
pub nsfw_level: Option<u8>,
|
||||||
#[cfg_attr(feature = "sqlx", sqlx(skip))]
|
#[cfg_attr(feature = "sqlx", sqlx(skip))]
|
||||||
pub stickers: Option<Vec<Sticker>>,
|
pub stickers: Option<Vec<Sticker>>,
|
||||||
pub premium_progress_bar_enabled: Option<bool>,
|
pub premium_progress_bar_enabled: Option<bool>,
|
||||||
|
@ -120,3 +121,59 @@ pub struct UnavailableGuild {
|
||||||
pub struct GuildCreateResponse {
|
pub struct GuildCreateResponse {
|
||||||
pub id: String,
|
pub id: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, Debug, Default, Clone)]
|
||||||
|
/// See https://discord.com/developers/docs/resources/guild-scheduled-event#guild-scheduled-event-object
|
||||||
|
pub struct GuildScheduledEvent {
|
||||||
|
pub id: String,
|
||||||
|
pub guild_id: String,
|
||||||
|
pub channel_id: Option<String>,
|
||||||
|
pub creator_id: Option<String>,
|
||||||
|
pub name: String,
|
||||||
|
pub description: String,
|
||||||
|
pub scheduled_start_time: DateTime<Utc>,
|
||||||
|
pub scheduled_end_time: Option<DateTime<Utc>>,
|
||||||
|
pub privacy_level: GuildScheduledEventPrivacyLevel,
|
||||||
|
pub status: GuildScheduledEventStatus,
|
||||||
|
pub entity_type: GuildScheduledEventEntityType,
|
||||||
|
pub entity_id: Option<String>,
|
||||||
|
pub entity_metadata: Option<GuildScheduledEventEntityMetadata>,
|
||||||
|
pub creator: Option<User>,
|
||||||
|
pub user_count: Option<u64>,
|
||||||
|
pub image: Option<String>
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize_repr, Deserialize_repr, Debug, Default, Clone)]
|
||||||
|
#[repr(u8)]
|
||||||
|
/// See https://discord.com/developers/docs/resources/guild-scheduled-event#guild-scheduled-event-object-guild-scheduled-event-privacy-level
|
||||||
|
pub enum GuildScheduledEventPrivacyLevel {
|
||||||
|
#[default]
|
||||||
|
GuildOnly = 2,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize_repr, Deserialize_repr, Debug, Default, Clone)]
|
||||||
|
#[repr(u8)]
|
||||||
|
/// See https://discord.com/developers/docs/resources/guild-scheduled-event#guild-scheduled-event-object-guild-scheduled-event-status
|
||||||
|
pub enum GuildScheduledEventStatus {
|
||||||
|
#[default]
|
||||||
|
Scheduled = 1,
|
||||||
|
Active = 2,
|
||||||
|
Completed = 3,
|
||||||
|
Canceled = 4
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize_repr, Deserialize_repr, Debug, Default, Clone)]
|
||||||
|
#[repr(u8)]
|
||||||
|
/// See https://discord.com/developers/docs/resources/guild-scheduled-event#guild-scheduled-event-object-guild-scheduled-event-entity-types
|
||||||
|
pub enum GuildScheduledEventEntityType {
|
||||||
|
#[default]
|
||||||
|
StageInstance = 1,
|
||||||
|
Voice = 2,
|
||||||
|
External = 3,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, Debug, Default, Clone)]
|
||||||
|
/// See https://discord.com/developers/docs/resources/guild-scheduled-event#guild-scheduled-event-object-guild-scheduled-event-entity-metadata
|
||||||
|
pub struct GuildScheduledEventEntityMetadata {
|
||||||
|
pub location: Option<String>
|
||||||
|
}
|
|
@ -2,7 +2,7 @@ use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
use crate::types::entities::User;
|
use crate::types::entities::User;
|
||||||
|
|
||||||
#[derive(Debug, Deserialize, Serialize, Clone, PartialEq, Eq)]
|
#[derive(Debug, Deserialize, Default, Serialize, Clone, PartialEq, Eq)]
|
||||||
pub struct GuildMember {
|
pub struct GuildMember {
|
||||||
pub user: Option<User>,
|
pub user: Option<User>,
|
||||||
pub nick: Option<String>,
|
pub nick: Option<String>,
|
||||||
|
@ -12,7 +12,7 @@ pub struct GuildMember {
|
||||||
pub premium_since: Option<String>,
|
pub premium_since: Option<String>,
|
||||||
pub deaf: bool,
|
pub deaf: bool,
|
||||||
pub mute: bool,
|
pub mute: bool,
|
||||||
pub flags: i32,
|
pub flags: Option<i32>,
|
||||||
pub pending: Option<bool>,
|
pub pending: Option<bool>,
|
||||||
pub permissions: Option<String>,
|
pub permissions: Option<String>,
|
||||||
pub communication_disabled_until: Option<String>,
|
pub communication_disabled_until: Option<String>,
|
||||||
|
|
|
@ -21,7 +21,7 @@ pub struct Message {
|
||||||
pub tts: bool,
|
pub tts: bool,
|
||||||
pub mention_everyone: bool,
|
pub mention_everyone: bool,
|
||||||
#[cfg_attr(feature = "sqlx", sqlx(skip))]
|
#[cfg_attr(feature = "sqlx", sqlx(skip))]
|
||||||
pub mentions: Vec<User>,
|
pub mentions: Option<Vec<User>>,
|
||||||
#[cfg_attr(feature = "sqlx", sqlx(skip))]
|
#[cfg_attr(feature = "sqlx", sqlx(skip))]
|
||||||
pub mention_roles: Vec<Snowflake>,
|
pub mention_roles: Vec<Snowflake>,
|
||||||
#[cfg_attr(feature = "sqlx", sqlx(skip))]
|
#[cfg_attr(feature = "sqlx", sqlx(skip))]
|
||||||
|
|
|
@ -16,6 +16,10 @@ mod user;
|
||||||
mod user_settings;
|
mod user_settings;
|
||||||
mod voice_state;
|
mod voice_state;
|
||||||
mod webhook;
|
mod webhook;
|
||||||
|
mod audit_log;
|
||||||
|
mod relationship;
|
||||||
|
mod auto_moderation;
|
||||||
|
mod stage_instance;
|
||||||
|
|
||||||
pub use application::*;
|
pub use application::*;
|
||||||
pub use attachment::*;
|
pub use attachment::*;
|
||||||
|
@ -35,3 +39,7 @@ pub use user::*;
|
||||||
pub use user_settings::*;
|
pub use user_settings::*;
|
||||||
pub use voice_state::*;
|
pub use voice_state::*;
|
||||||
pub use webhook::*;
|
pub use webhook::*;
|
||||||
|
pub use audit_log::*;
|
||||||
|
pub use relationship::*;
|
||||||
|
pub use auto_moderation::*;
|
||||||
|
pub use stage_instance::*;
|
|
@ -0,0 +1,27 @@
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
use serde_repr::{Serialize_repr, Deserialize_repr};
|
||||||
|
|
||||||
|
use crate::types::Snowflake;
|
||||||
|
|
||||||
|
use super::PublicUser;
|
||||||
|
|
||||||
|
#[derive(Debug, Deserialize, Serialize, Clone, Default)]
|
||||||
|
/// See https://docs.spacebar.chat/routes/#get-/users/@me/relationships/
|
||||||
|
pub struct Relationship {
|
||||||
|
pub id: Snowflake,
|
||||||
|
#[serde(rename = "type")]
|
||||||
|
pub relationship_type: RelationshipType,
|
||||||
|
pub nickname: Option<String>,
|
||||||
|
pub user: PublicUser
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize_repr, Deserialize_repr, Debug, Clone, Default)]
|
||||||
|
#[repr(u8)]
|
||||||
|
/// See https://github.com/spacebarchat/server/blob/60394d8c43904ff17935d6edbbfb09ecd479570a/src/util/entities/Relationship.ts#L30
|
||||||
|
pub enum RelationshipType {
|
||||||
|
Outgoing = 4,
|
||||||
|
Incoming = 3,
|
||||||
|
Blocked = 2,
|
||||||
|
#[default]
|
||||||
|
Friends = 1,
|
||||||
|
}
|
|
@ -1,4 +1,5 @@
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
use serde_aux::prelude::{deserialize_string_from_number, deserialize_option_number_from_string};
|
||||||
|
|
||||||
use crate::types::utils::Snowflake;
|
use crate::types::utils::Snowflake;
|
||||||
|
|
||||||
|
@ -13,11 +14,12 @@ pub struct RoleObject {
|
||||||
pub icon: Option<String>,
|
pub icon: Option<String>,
|
||||||
pub unicode_emoji: Option<String>,
|
pub unicode_emoji: Option<String>,
|
||||||
pub position: u16,
|
pub position: u16,
|
||||||
|
#[serde(default)]
|
||||||
|
#[serde(deserialize_with = "deserialize_string_from_number")]
|
||||||
pub permissions: String,
|
pub permissions: String,
|
||||||
pub managed: bool,
|
pub managed: bool,
|
||||||
pub mentionable: bool,
|
pub mentionable: bool,
|
||||||
// to:do add role tags https://discord.com/developers/docs/topics/permissions#role-object-role-tags-structure
|
pub tags: Option<RoleTags>
|
||||||
//pub tags: Option<RoleTags>
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||||
|
@ -27,3 +29,21 @@ pub struct RoleSubscriptionData {
|
||||||
pub total_months_subscribed: u32,
|
pub total_months_subscribed: u32,
|
||||||
pub is_renewal: bool,
|
pub is_renewal: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, Debug, Default, Clone, Eq, PartialEq)]
|
||||||
|
/// See https://discord.com/developers/docs/topics/permissions#role-object-role-tags-structure
|
||||||
|
pub struct RoleTags {
|
||||||
|
#[serde(default)]
|
||||||
|
#[serde(deserialize_with = "deserialize_option_number_from_string")]
|
||||||
|
pub bot_id: Option<usize>,
|
||||||
|
#[serde(default)]
|
||||||
|
#[serde(deserialize_with = "deserialize_option_number_from_string")]
|
||||||
|
pub integration_id: Option<usize>,
|
||||||
|
#[serde(default)]
|
||||||
|
#[serde(deserialize_with = "deserialize_option_number_from_string")]
|
||||||
|
pub subscription_listing_id: Option<usize>,
|
||||||
|
// These use the bad bool format, "Tags with type null represent booleans. They will be present and set to null if they are "true", and will be not present if they are "false"."
|
||||||
|
// premium_subscriber: bool,
|
||||||
|
// available_for_purchase: bool,
|
||||||
|
// guild_connections: bool,
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,29 @@
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
use serde_repr::{Serialize_repr, Deserialize_repr};
|
||||||
|
|
||||||
|
use crate::types::Snowflake;
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, Debug, Default, Clone)]
|
||||||
|
/// See https://discord.com/developers/docs/resources/stage-instance
|
||||||
|
pub struct StageInstance {
|
||||||
|
pub id: Snowflake,
|
||||||
|
pub guild_id: Snowflake,
|
||||||
|
pub channel_id: Snowflake,
|
||||||
|
/// 1 - 120 chars
|
||||||
|
pub topic: String,
|
||||||
|
pub privacy_level: StageInstancePrivacyLevel,
|
||||||
|
/// deprecated, apparently
|
||||||
|
pub discoverable_disabled: Option<bool>,
|
||||||
|
pub guild_scheduled_event_id: Option<Snowflake>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize_repr, Deserialize_repr, Debug, Clone, Default)]
|
||||||
|
#[repr(u8)]
|
||||||
|
#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
|
||||||
|
/// See https://discord.com/developers/docs/resources/stage-instance#stage-instance-object-privacy-level
|
||||||
|
pub enum StageInstancePrivacyLevel {
|
||||||
|
/// deprecated, apparently
|
||||||
|
Public = 1,
|
||||||
|
#[default]
|
||||||
|
GuildOnly = 2
|
||||||
|
}
|
|
@ -1,10 +1,12 @@
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
use serde_aux::prelude::{deserialize_option_number_from_string};
|
||||||
|
|
||||||
use crate::types::{entities::User, utils::Snowflake};
|
use crate::types::{entities::User, utils::Snowflake};
|
||||||
|
|
||||||
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
|
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
|
||||||
#[cfg_attr(feature = "sqlx", derive(sqlx::FromRow))]
|
#[cfg_attr(feature = "sqlx", derive(sqlx::FromRow))]
|
||||||
pub struct Sticker {
|
pub struct Sticker {
|
||||||
|
#[serde(default)]
|
||||||
pub id: Snowflake,
|
pub id: Snowflake,
|
||||||
pub pack_id: Option<Snowflake>,
|
pub pack_id: Option<Snowflake>,
|
||||||
pub name: String,
|
pub name: String,
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
use chrono::{DateTime, Utc};
|
use chrono::{DateTime, Utc};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
use serde_aux::prelude::deserialize_option_number_from_string;
|
||||||
use serde_json::{Map, Value};
|
use serde_json::{Map, Value};
|
||||||
|
|
||||||
use crate::types::{
|
use crate::types::{
|
||||||
|
@ -27,7 +28,7 @@ pub struct User {
|
||||||
pub username: String,
|
pub username: String,
|
||||||
pub discriminator: String,
|
pub discriminator: String,
|
||||||
pub avatar: Option<String>,
|
pub avatar: Option<String>,
|
||||||
pub bot: bool,
|
pub bot: Option<bool>,
|
||||||
pub system: Option<bool>,
|
pub system: Option<bool>,
|
||||||
pub mfa_enabled: Option<bool>,
|
pub mfa_enabled: Option<bool>,
|
||||||
pub accent_color: Option<u8>,
|
pub accent_color: Option<u8>,
|
||||||
|
@ -35,7 +36,11 @@ pub struct User {
|
||||||
pub locale: Option<String>,
|
pub locale: Option<String>,
|
||||||
pub verified: Option<bool>,
|
pub verified: Option<bool>,
|
||||||
pub email: Option<String>,
|
pub email: Option<String>,
|
||||||
pub flags: String,
|
/// This field comes as either a string or a number as a string
|
||||||
|
/// So we need to account for that
|
||||||
|
#[serde(default)]
|
||||||
|
#[serde(deserialize_with = "deserialize_option_number_from_string")]
|
||||||
|
flags: Option<i32>,
|
||||||
pub premium_since: Option<DateTime<Utc>>,
|
pub premium_since: Option<DateTime<Utc>>,
|
||||||
pub premium_type: u8,
|
pub premium_type: u8,
|
||||||
pub pronouns: Option<String>,
|
pub pronouns: Option<String>,
|
||||||
|
@ -47,11 +52,11 @@ pub struct User {
|
||||||
pub nsfw_allowed: bool,
|
pub nsfw_allowed: bool,
|
||||||
pub premium: bool,
|
pub premium: bool,
|
||||||
pub purchased_flags: i32,
|
pub purchased_flags: i32,
|
||||||
pub premium_usage_flags: i32,
|
pub premium_usage_flags: Option<i32>,
|
||||||
pub disabled: Option<bool>,
|
pub disabled: Option<bool>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
#[derive(Debug, Default, Clone, PartialEq, Serialize, Deserialize)]
|
||||||
pub struct PublicUser {
|
pub struct PublicUser {
|
||||||
pub id: Snowflake,
|
pub id: Snowflake,
|
||||||
pub username: String,
|
pub username: String,
|
||||||
|
@ -61,7 +66,7 @@ pub struct PublicUser {
|
||||||
pub banner: Option<String>,
|
pub banner: Option<String>,
|
||||||
pub theme_colors: Option<Vec<u8>>,
|
pub theme_colors: Option<Vec<u8>>,
|
||||||
pub pronouns: Option<String>,
|
pub pronouns: Option<String>,
|
||||||
pub bot: bool,
|
pub bot: Option<bool>,
|
||||||
pub bio: String,
|
pub bio: String,
|
||||||
pub premium_type: u8,
|
pub premium_type: u8,
|
||||||
pub premium_since: Option<DateTime<Utc>>,
|
pub premium_since: Option<DateTime<Utc>>,
|
||||||
|
|
|
@ -10,11 +10,13 @@ use crate::types::{
|
||||||
#[derive(Serialize, Deserialize, Debug, Default, Clone, PartialEq)]
|
#[derive(Serialize, Deserialize, Debug, Default, Clone, PartialEq)]
|
||||||
#[cfg_attr(feature = "sqlx", derive(sqlx::FromRow))]
|
#[cfg_attr(feature = "sqlx", derive(sqlx::FromRow))]
|
||||||
pub struct VoiceState {
|
pub struct VoiceState {
|
||||||
pub guild_id: Snowflake,
|
pub guild_id: Option<Snowflake>,
|
||||||
|
pub guild: Option<Guild>,
|
||||||
pub channel_id: Snowflake,
|
pub channel_id: Snowflake,
|
||||||
pub user_id: Snowflake,
|
pub user_id: Snowflake,
|
||||||
pub member: Option<GuildMember>,
|
pub member: Option<GuildMember>,
|
||||||
pub session_id: Snowflake,
|
pub session_id: Snowflake,
|
||||||
|
pub token: Option<String>,
|
||||||
pub deaf: bool,
|
pub deaf: bool,
|
||||||
pub mute: bool,
|
pub mute: bool,
|
||||||
pub self_deaf: bool,
|
pub self_deaf: bool,
|
||||||
|
@ -23,4 +25,5 @@ pub struct VoiceState {
|
||||||
pub self_video: bool,
|
pub self_video: bool,
|
||||||
pub suppress: bool,
|
pub suppress: bool,
|
||||||
pub request_to_speak_timestamp: Option<DateTime<Utc>>,
|
pub request_to_speak_timestamp: Option<DateTime<Utc>>,
|
||||||
|
pub id: Option<Snowflake>,
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,12 @@
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
use crate::types::{WebSocketEvent, GuildApplicationCommandPermissions};
|
||||||
|
|
||||||
|
#[derive(Debug, Deserialize, Serialize, Default)]
|
||||||
|
/// See https://discord.com/developers/docs/topics/gateway-events#application-command-permissions-update
|
||||||
|
pub struct ApplicationCommandPermissionsUpdate {
|
||||||
|
#[serde(flatten)]
|
||||||
|
pub permissions: GuildApplicationCommandPermissions,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl WebSocketEvent for ApplicationCommandPermissionsUpdate {}
|
|
@ -0,0 +1,48 @@
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
use crate::types::{WebSocketEvent, AutoModerationRule, Snowflake, AutoModerationAction, AutoModerationRuleTriggerType};
|
||||||
|
|
||||||
|
#[derive(Debug, Deserialize, Serialize, Default)]
|
||||||
|
/// See https://discord.com/developers/docs/topics/gateway-events#auto-moderation-rule-create
|
||||||
|
pub struct AutoModerationRuleCreate {
|
||||||
|
#[serde(flatten)]
|
||||||
|
pub rule: AutoModerationRule,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl WebSocketEvent for AutoModerationRuleCreate {}
|
||||||
|
|
||||||
|
#[derive(Debug, Deserialize, Serialize, Default)]
|
||||||
|
/// See https://discord.com/developers/docs/topics/gateway-events#auto-moderation-rule-update
|
||||||
|
pub struct AutoModerationRuleUpdate {
|
||||||
|
#[serde(flatten)]
|
||||||
|
pub rule: AutoModerationRule,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl WebSocketEvent for AutoModerationRuleUpdate {}
|
||||||
|
|
||||||
|
#[derive(Debug, Deserialize, Serialize, Default)]
|
||||||
|
/// See https://discord.com/developers/docs/topics/gateway-events#auto-moderation-rule-delete
|
||||||
|
pub struct AutoModerationRuleDelete {
|
||||||
|
#[serde(flatten)]
|
||||||
|
pub rule: AutoModerationRule,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl WebSocketEvent for AutoModerationRuleDelete {}
|
||||||
|
|
||||||
|
#[derive(Debug, Deserialize, Serialize, Default)]
|
||||||
|
/// See https://discord.com/developers/docs/topics/gateway-events#auto-moderation-action-execution
|
||||||
|
pub struct AutoModerationActionExecution {
|
||||||
|
pub guild_id: Snowflake,
|
||||||
|
pub action: AutoModerationAction,
|
||||||
|
pub rule_id: Snowflake,
|
||||||
|
pub rule_trigger_type: AutoModerationRuleTriggerType,
|
||||||
|
pub user_id: Snowflake,
|
||||||
|
pub channel_id: Option<Snowflake>,
|
||||||
|
pub message_id: Option<Snowflake>,
|
||||||
|
pub alert_system_message_id: Option<Snowflake>,
|
||||||
|
pub content: Option<String>,
|
||||||
|
pub matched_keyword: Option<String>,
|
||||||
|
pub matched_content: Option<String>
|
||||||
|
}
|
||||||
|
|
||||||
|
impl WebSocketEvent for AutoModerationActionExecution {}
|
|
@ -0,0 +1,51 @@
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
use crate::types::{VoiceState, WebSocketEvent};
|
||||||
|
|
||||||
|
#[derive(Debug, Deserialize, Serialize, Default)]
|
||||||
|
/// Officially Undocumented
|
||||||
|
/// Is sent to a client by the server to signify a new being created
|
||||||
|
/// {"t":"CALL_CREATE","s":2,"op":0,"d":{"voice_states":[],"ringing":[],"region":"milan","message_id":"1107187514906775613","embedded_activities":[],"channel_id":"837609115475771392"}}
|
||||||
|
pub struct CallCreate {
|
||||||
|
pub voice_states: Vec<VoiceState>,
|
||||||
|
/// Seems like a vec of channel ids
|
||||||
|
pub ringing: Vec<String>,
|
||||||
|
pub region: String, // milan
|
||||||
|
pub message_id: String,
|
||||||
|
/// What is this?
|
||||||
|
pub embedded_activities: Vec<serde_json::Value>,
|
||||||
|
pub channel_id: String,
|
||||||
|
}
|
||||||
|
impl WebSocketEvent for CallCreate {}
|
||||||
|
|
||||||
|
#[derive(Debug, Deserialize, Serialize, Default)]
|
||||||
|
/// Officially Undocumented
|
||||||
|
/// Updates the status of calls
|
||||||
|
/// {"t":"CALL_UPDATE","s":5,"op":0,"d":{"ringing":["837606544539254834"],"region":"milan","message_id":"1107191540234846308","guild_id":null,"channel_id":"837609115475771392"}}
|
||||||
|
pub struct CallUpdate {
|
||||||
|
/// Seems like a vec of channel ids
|
||||||
|
pub ringing: Vec<String>,
|
||||||
|
pub region: String, // milan
|
||||||
|
pub message_id: String,
|
||||||
|
pub guild_id: Option<String>,
|
||||||
|
pub channel_id: String,
|
||||||
|
}
|
||||||
|
impl WebSocketEvent for CallUpdate {}
|
||||||
|
|
||||||
|
#[derive(Debug, Deserialize, Serialize, Default)]
|
||||||
|
/// Officially Undocumented
|
||||||
|
/// Deletes a ringing call
|
||||||
|
/// {"t":"CALL_DELETE","s":8,"op":0,"d":{"channel_id":"837609115475771392"}}
|
||||||
|
pub struct CallDelete {
|
||||||
|
pub channel_id: String,
|
||||||
|
}
|
||||||
|
impl WebSocketEvent for CallDelete {}
|
||||||
|
|
||||||
|
#[derive(Debug, Deserialize, Serialize, Default)]
|
||||||
|
/// Officially Undocumented
|
||||||
|
/// See https://unofficial-discord-docs.vercel.app/gateway/op13
|
||||||
|
/// {"op":13,"d":{"channel_id":"837609115475771392"}}
|
||||||
|
pub struct CallSync {
|
||||||
|
pub channel_id: String,
|
||||||
|
}
|
||||||
|
impl WebSocketEvent for CallSync {}
|
|
@ -15,8 +15,8 @@ impl WebSocketEvent for ChannelPinsUpdate {}
|
||||||
|
|
||||||
#[derive(Debug, Default, Deserialize, Serialize)]
|
#[derive(Debug, Default, Deserialize, Serialize)]
|
||||||
/// See https://discord.com/developers/docs/topics/gateway-events#channel-create
|
/// See https://discord.com/developers/docs/topics/gateway-events#channel-create
|
||||||
/// Not directly serialized, as the inner payload is a channel object
|
|
||||||
pub struct ChannelCreate {
|
pub struct ChannelCreate {
|
||||||
|
#[serde(flatten)]
|
||||||
pub channel: Channel,
|
pub channel: Channel,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -24,17 +24,37 @@ impl WebSocketEvent for ChannelCreate {}
|
||||||
|
|
||||||
#[derive(Debug, Default, Deserialize, Serialize)]
|
#[derive(Debug, Default, Deserialize, Serialize)]
|
||||||
/// See https://discord.com/developers/docs/topics/gateway-events#channel-update
|
/// See https://discord.com/developers/docs/topics/gateway-events#channel-update
|
||||||
/// Not directly serialized, as the inner payload is a channel object
|
|
||||||
pub struct ChannelUpdate {
|
pub struct ChannelUpdate {
|
||||||
|
#[serde(flatten)]
|
||||||
pub channel: Channel,
|
pub channel: Channel,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl WebSocketEvent for ChannelUpdate {}
|
impl WebSocketEvent for ChannelUpdate {}
|
||||||
|
|
||||||
|
#[derive(Debug, Default, Deserialize, Serialize)]
|
||||||
|
/// Officially undocumented.
|
||||||
|
/// Sends updates to client about a new message with its id
|
||||||
|
/// {"channel_unread_updates": [{"id": "816412869766938648", "last_message_id": "1085892012085104680"}}
|
||||||
|
pub struct ChannelUnreadUpdate {
|
||||||
|
pub channel_unread_updates: Vec<ChannelUnreadUpdateObject>,
|
||||||
|
pub guild_id: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Default, Deserialize, Serialize)]
|
||||||
|
/// Contains very few fields from [Channel]
|
||||||
|
/// See also [ChannelUnreadUpdates]
|
||||||
|
pub struct ChannelUnreadUpdateObject {
|
||||||
|
pub id: String,
|
||||||
|
pub last_message_id: String,
|
||||||
|
pub last_pin_timestamp: Option<String>
|
||||||
|
}
|
||||||
|
|
||||||
|
impl WebSocketEvent for ChannelUnreadUpdate {}
|
||||||
|
|
||||||
#[derive(Debug, Default, Deserialize, Serialize)]
|
#[derive(Debug, Default, Deserialize, Serialize)]
|
||||||
/// See https://discord.com/developers/docs/topics/gateway-events#channel-delete
|
/// See https://discord.com/developers/docs/topics/gateway-events#channel-delete
|
||||||
/// Not directly serialized, as the inner payload is a channel object
|
|
||||||
pub struct ChannelDelete {
|
pub struct ChannelDelete {
|
||||||
|
#[serde(flatten)]
|
||||||
pub channel: Channel,
|
pub channel: Channel,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,15 +1,21 @@
|
||||||
use crate::types::entities::{Guild, UnavailableGuild, User};
|
use crate::types::entities::{Guild, UnavailableGuild, User};
|
||||||
use crate::types::events::WebSocketEvent;
|
use crate::types::events::WebSocketEvent;
|
||||||
|
use crate::types::{AuditLogEntry, Emoji, GuildMember, GuildScheduledEvent, RoleObject, Sticker};
|
||||||
|
use chrono::{DateTime, Utc};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
use super::PresenceUpdate;
|
||||||
|
|
||||||
#[derive(Debug, Deserialize, Serialize, Default)]
|
#[derive(Debug, Deserialize, Serialize, Default)]
|
||||||
/// See https://discord.com/developers/docs/topics/gateway-events#guild-create
|
/// See https://discord.com/developers/docs/topics/gateway-events#guild-create
|
||||||
/// This one is particularly painful, it can be a Guild object with extra field or an unavailbile guild object
|
/// This one is particularly painful, it can be a Guild object with an extra field or an unavailable guild object
|
||||||
pub struct GuildCreate {
|
pub struct GuildCreate {
|
||||||
|
#[serde(flatten)]
|
||||||
pub d: GuildCreateDataOption,
|
pub d: GuildCreateDataOption,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Deserialize, Serialize)]
|
#[derive(Debug, Deserialize, Serialize)]
|
||||||
|
#[serde(untagged)]
|
||||||
pub enum GuildCreateDataOption {
|
pub enum GuildCreateDataOption {
|
||||||
UnavailableGuild(UnavailableGuild),
|
UnavailableGuild(UnavailableGuild),
|
||||||
Guild(Guild),
|
Guild(Guild),
|
||||||
|
@ -39,3 +45,181 @@ pub struct GuildBanRemove {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl WebSocketEvent for GuildBanRemove {}
|
impl WebSocketEvent for GuildBanRemove {}
|
||||||
|
|
||||||
|
#[derive(Debug, Default, Deserialize, Serialize)]
|
||||||
|
/// See https://discord.com/developers/docs/topics/gateway-events#guild-update
|
||||||
|
pub struct GuildUpdate {
|
||||||
|
#[serde(flatten)]
|
||||||
|
pub guild: Guild,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl WebSocketEvent for GuildUpdate {}
|
||||||
|
|
||||||
|
#[derive(Debug, Default, Deserialize, Serialize)]
|
||||||
|
/// See https://discord.com/developers/docs/topics/gateway-events#guild-delete
|
||||||
|
pub struct GuildDelete {
|
||||||
|
#[serde(flatten)]
|
||||||
|
pub guild: UnavailableGuild,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl WebSocketEvent for GuildDelete {}
|
||||||
|
|
||||||
|
#[derive(Debug, Default, Deserialize, Serialize)]
|
||||||
|
/// See https://discord.com/developers/docs/topics/gateway-events#guild-audit-log-entry-create
|
||||||
|
pub struct GuildAuditLogEntryCreate {
|
||||||
|
#[serde(flatten)]
|
||||||
|
pub entry: AuditLogEntry,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl WebSocketEvent for GuildAuditLogEntryCreate {}
|
||||||
|
|
||||||
|
#[derive(Debug, Default, Deserialize, Serialize)]
|
||||||
|
/// See https://discord.com/developers/docs/topics/gateway-events#guild-emojis-update
|
||||||
|
pub struct GuildEmojisUpdate {
|
||||||
|
pub guild_id: String,
|
||||||
|
pub emojis: Vec<Emoji>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl WebSocketEvent for GuildEmojisUpdate {}
|
||||||
|
|
||||||
|
#[derive(Debug, Default, Deserialize, Serialize)]
|
||||||
|
/// See https://discord.com/developers/docs/topics/gateway-events#guild-stickers-update
|
||||||
|
pub struct GuildStickersUpdate {
|
||||||
|
pub guild_id: String,
|
||||||
|
pub stickers: Vec<Sticker>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl WebSocketEvent for GuildStickersUpdate {}
|
||||||
|
|
||||||
|
#[derive(Debug, Default, Deserialize, Serialize)]
|
||||||
|
/// See https://discord.com/developers/docs/topics/gateway-events#guild-integrations-update
|
||||||
|
pub struct GuildIntegrationsUpdate {
|
||||||
|
pub guild_id: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl WebSocketEvent for GuildIntegrationsUpdate {}
|
||||||
|
|
||||||
|
#[derive(Debug, Default, Deserialize, Serialize)]
|
||||||
|
/// See https://discord.com/developers/docs/topics/gateway-events#guild-member-add
|
||||||
|
pub struct GuildMemberAdd {
|
||||||
|
#[serde(flatten)]
|
||||||
|
pub member: GuildMember,
|
||||||
|
pub guild_id: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl WebSocketEvent for GuildMemberAdd {}
|
||||||
|
|
||||||
|
#[derive(Debug, Default, Deserialize, Serialize)]
|
||||||
|
/// See https://discord.com/developers/docs/topics/gateway-events#guild-member-remove
|
||||||
|
pub struct GuildMemberRemove {
|
||||||
|
pub guild_id: String,
|
||||||
|
pub user: User,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl WebSocketEvent for GuildMemberRemove {}
|
||||||
|
|
||||||
|
#[derive(Debug, Default, Deserialize, Serialize)]
|
||||||
|
/// See https://discord.com/developers/docs/topics/gateway-events#guild-member-update
|
||||||
|
pub struct GuildMemberUpdate {
|
||||||
|
pub guild_id: String,
|
||||||
|
pub roles: Vec<String>,
|
||||||
|
pub user: User,
|
||||||
|
pub nick: Option<String>,
|
||||||
|
pub avatar: Option<String>,
|
||||||
|
pub joined_at: Option<DateTime<Utc>>,
|
||||||
|
pub premium_since: Option<DateTime<Utc>>,
|
||||||
|
pub deaf: Option<bool>,
|
||||||
|
pub mute: Option<bool>,
|
||||||
|
pub pending: Option<bool>,
|
||||||
|
pub communication_disabled_until: Option<DateTime<Utc>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl WebSocketEvent for GuildMemberUpdate {}
|
||||||
|
|
||||||
|
#[derive(Debug, Default, Deserialize, Serialize)]
|
||||||
|
/// See https://discord.com/developers/docs/topics/gateway-events#guild-members-chunk
|
||||||
|
pub struct GuildMembersChunk {
|
||||||
|
pub guild_id: String,
|
||||||
|
pub members: Vec<GuildMember>,
|
||||||
|
pub chunk_index: u16,
|
||||||
|
pub chunk_count: u16,
|
||||||
|
pub not_found: Option<Vec<String>>,
|
||||||
|
pub presences: Option<PresenceUpdate>,
|
||||||
|
pub nonce: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl WebSocketEvent for GuildMembersChunk {}
|
||||||
|
|
||||||
|
#[derive(Debug, Default, Deserialize, Serialize)]
|
||||||
|
/// See https://discord.com/developers/docs/topics/gateway-events#guild-role-create
|
||||||
|
pub struct GuildRoleCreate {
|
||||||
|
pub guild_id: String,
|
||||||
|
pub role: RoleObject,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl WebSocketEvent for GuildRoleCreate {}
|
||||||
|
|
||||||
|
#[derive(Debug, Default, Deserialize, Serialize)]
|
||||||
|
/// See https://discord.com/developers/docs/topics/gateway-events#guild-role-update
|
||||||
|
pub struct GuildRoleUpdate {
|
||||||
|
pub guild_id: String,
|
||||||
|
pub role: RoleObject,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl WebSocketEvent for GuildRoleUpdate {}
|
||||||
|
|
||||||
|
#[derive(Debug, Default, Deserialize, Serialize)]
|
||||||
|
/// See https://discord.com/developers/docs/topics/gateway-events#guild-role-delete
|
||||||
|
pub struct GuildRoleDelete {
|
||||||
|
pub guild_id: String,
|
||||||
|
pub role_id: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl WebSocketEvent for GuildRoleDelete {}
|
||||||
|
|
||||||
|
#[derive(Debug, Default, Deserialize, Serialize)]
|
||||||
|
/// See https://discord.com/developers/docs/topics/gateway-events#guild-scheduled-event-create
|
||||||
|
pub struct GuildScheduledEventCreate {
|
||||||
|
#[serde(flatten)]
|
||||||
|
pub event: GuildScheduledEvent,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl WebSocketEvent for GuildScheduledEventCreate {}
|
||||||
|
|
||||||
|
#[derive(Debug, Default, Deserialize, Serialize)]
|
||||||
|
/// See https://discord.com/developers/docs/topics/gateway-events#guild-scheduled-event-update
|
||||||
|
pub struct GuildScheduledEventUpdate {
|
||||||
|
#[serde(flatten)]
|
||||||
|
pub event: GuildScheduledEvent,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl WebSocketEvent for GuildScheduledEventUpdate {}
|
||||||
|
|
||||||
|
#[derive(Debug, Default, Deserialize, Serialize)]
|
||||||
|
/// See https://discord.com/developers/docs/topics/gateway-events#guild-scheduled-event-delete
|
||||||
|
pub struct GuildScheduledEventDelete {
|
||||||
|
#[serde(flatten)]
|
||||||
|
pub event: GuildScheduledEvent,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl WebSocketEvent for GuildScheduledEventDelete {}
|
||||||
|
|
||||||
|
#[derive(Debug, Default, Deserialize, Serialize)]
|
||||||
|
/// See https://discord.com/developers/docs/topics/gateway-events#guild-scheduled-event-user-add
|
||||||
|
pub struct GuildScheduledEventUserAdd {
|
||||||
|
pub guild_scheduled_event_id: String,
|
||||||
|
pub user_id: String,
|
||||||
|
pub guild_id: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl WebSocketEvent for GuildScheduledEventUserAdd {}
|
||||||
|
|
||||||
|
#[derive(Debug, Default, Deserialize, Serialize)]
|
||||||
|
/// See https://discord.com/developers/docs/topics/gateway-events#guild-scheduled-event-user-remove
|
||||||
|
pub struct GuildScheduledEventUserRemove {
|
||||||
|
pub guild_scheduled_event_id: String,
|
||||||
|
pub user_id: String,
|
||||||
|
pub guild_id: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl WebSocketEvent for GuildScheduledEventUserRemove {}
|
||||||
|
|
|
@ -1,22 +1,168 @@
|
||||||
use crate::types::events::{PresenceUpdate, WebSocketEvent};
|
use crate::types::events::{PresenceUpdate, WebSocketEvent};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
use serde_with::serde_as;
|
||||||
|
|
||||||
#[derive(Debug, Deserialize, Serialize, Default)]
|
#[derive(Debug, Deserialize, Serialize)]
|
||||||
pub struct GatewayIdentifyPayload {
|
pub struct GatewayIdentifyPayload {
|
||||||
pub token: String,
|
pub token: String,
|
||||||
pub properties: GatewayIdentifyConnectionProps,
|
pub properties: GatewayIdentifyConnectionProps,
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
pub compress: Option<bool>,
|
pub compress: Option<bool>,
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
pub large_threshold: Option<i16>, //default: 50
|
pub large_threshold: Option<i16>, //default: 50
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
pub shard: Option<Vec<(i32, i32)>>,
|
pub shard: Option<Vec<(i32, i32)>>,
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
pub presence: Option<PresenceUpdate>,
|
pub presence: Option<PresenceUpdate>,
|
||||||
pub intents: i32,
|
// What is the difference between these two?
|
||||||
|
// Intents is documented, capabilities is used in users
|
||||||
|
// I wonder if these are interchangeable...
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub intents: Option<i32>,
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub capabilities: Option<i32>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for GatewayIdentifyPayload {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self::common()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl GatewayIdentifyPayload {
|
||||||
|
/// Uses the most common, 25% data along with client capabilities
|
||||||
|
///
|
||||||
|
/// Basically pretends to be an official client on Windows 10, with Chrome 113.0.0.0
|
||||||
|
pub fn common() -> Self {
|
||||||
|
Self {
|
||||||
|
token: "".to_string(),
|
||||||
|
properties: GatewayIdentifyConnectionProps::default(),
|
||||||
|
compress: Some(false),
|
||||||
|
large_threshold: None,
|
||||||
|
shard: None,
|
||||||
|
presence: None,
|
||||||
|
intents: None,
|
||||||
|
capabilities: Some(8189),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl GatewayIdentifyPayload {
|
||||||
|
/// Creates an identify payload with the same default capabilities as the official client
|
||||||
|
pub fn default_w_client_capabilities() -> Self {
|
||||||
|
let mut def = Self::default();
|
||||||
|
def.capabilities = Some(8189); // Default capabilities for a client
|
||||||
|
def
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Creates an identify payload with all possible capabilities
|
||||||
|
pub fn default_w_all_capabilities() -> Self {
|
||||||
|
let mut def = Self::default();
|
||||||
|
def.capabilities = Some(i32::MAX); // Since discord uses bitwise for capabilities, this has almost every bit as 1, so all capabilities
|
||||||
|
def
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl WebSocketEvent for GatewayIdentifyPayload {}
|
impl WebSocketEvent for GatewayIdentifyPayload {}
|
||||||
|
|
||||||
#[derive(Debug, Deserialize, Serialize, Default)]
|
#[derive(Debug, Deserialize, Serialize)]
|
||||||
|
#[serde_as]
|
||||||
pub struct GatewayIdentifyConnectionProps {
|
pub struct GatewayIdentifyConnectionProps {
|
||||||
|
/// Almost always sent
|
||||||
|
///
|
||||||
|
/// ex: "Linux", "Windows", "Mac OS X"
|
||||||
|
///
|
||||||
|
/// ex (mobile): "Windows Mobile", "iOS", "Android", "BlackBerry"
|
||||||
pub os: String,
|
pub os: String,
|
||||||
|
/// Almost always sent
|
||||||
|
///
|
||||||
|
/// ex: "Firefox", "Chrome", "Opera Mini", "Opera", "Blackberry", "Facebook Mobile", "Chrome iOS", "Mobile Safari", "Safari", "Android Chrome", "Android Mobile", "Edge", "Konqueror", "Internet Explorer", "Mozilla", "Discord Client"
|
||||||
pub browser: String,
|
pub browser: String,
|
||||||
pub device: String,
|
/// Sometimes not sent, acceptable to be ""
|
||||||
|
///
|
||||||
|
/// Speculation:
|
||||||
|
/// Only sent for mobile devices
|
||||||
|
///
|
||||||
|
/// ex: "BlackBerry", "Windows Phone", "Android", "iPhone", "iPad", ""
|
||||||
|
#[serde_as(as = "NoneAsEmptyString")]
|
||||||
|
pub device: Option<String>,
|
||||||
|
/// Almost always sent, most commonly en-US
|
||||||
|
///
|
||||||
|
/// ex: "en-US"
|
||||||
|
pub system_locale: String,
|
||||||
|
/// Almost always sent
|
||||||
|
///
|
||||||
|
/// ex: any user agent, most common is "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.0.0 Safari/537.36"
|
||||||
|
pub browser_user_agent: String,
|
||||||
|
/// Almost always sent
|
||||||
|
///
|
||||||
|
/// ex: "113.0.0.0"
|
||||||
|
pub browser_version: String,
|
||||||
|
/// Sometimes not sent, acceptable to be ""
|
||||||
|
///
|
||||||
|
/// ex: "10" (For os = "Windows")
|
||||||
|
#[serde_as(as = "NoneAsEmptyString")]
|
||||||
|
pub os_version: Option<String>,
|
||||||
|
/// Sometimes not sent, acceptable to be ""
|
||||||
|
#[serde_as(as = "NoneAsEmptyString")]
|
||||||
|
pub referrer: Option<String>,
|
||||||
|
/// Sometimes not sent, acceptable to be ""
|
||||||
|
#[serde_as(as = "NoneAsEmptyString")]
|
||||||
|
pub referring_domain: Option<String>,
|
||||||
|
/// Sometimes not sent, acceptable to be ""
|
||||||
|
#[serde_as(as = "NoneAsEmptyString")]
|
||||||
|
pub referrer_current: Option<String>,
|
||||||
|
/// Almost always sent, most commonly "stable"
|
||||||
|
pub release_channel: String,
|
||||||
|
/// Almost always sent, identifiable if default is 0, should be around 199933
|
||||||
|
pub client_build_number: u64,
|
||||||
|
//pub client_event_source: Option<?>
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for GatewayIdentifyConnectionProps {
|
||||||
|
/// Uses the most common, 25% data
|
||||||
|
fn default() -> Self {
|
||||||
|
Self::common()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl GatewayIdentifyConnectionProps {
|
||||||
|
/// Returns a minimal, least data possible default
|
||||||
|
fn minimal() -> Self {
|
||||||
|
Self {
|
||||||
|
os: String::new(),
|
||||||
|
browser: String::new(),
|
||||||
|
device: None,
|
||||||
|
system_locale: String::from("en-US"),
|
||||||
|
browser_user_agent: String::new(),
|
||||||
|
browser_version: String::new(),
|
||||||
|
os_version: None,
|
||||||
|
referrer: None,
|
||||||
|
referring_domain: None,
|
||||||
|
referrer_current: None,
|
||||||
|
release_channel: String::from("stable"),
|
||||||
|
client_build_number: 199933,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the most common connection props so we can't be tracked
|
||||||
|
pub fn common() -> Self {
|
||||||
|
let mut default = Self::minimal();
|
||||||
|
|
||||||
|
// See https://www.useragents.me/#most-common-desktop-useragents
|
||||||
|
// 25% of the web
|
||||||
|
//default.browser_user_agent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.0.0 Safari/537.36".to_string();
|
||||||
|
default.browser = String::from("Chrome");
|
||||||
|
default.browser_version = String::from("113.0.0.0");
|
||||||
|
|
||||||
|
default.system_locale = String::from("en-US");
|
||||||
|
|
||||||
|
default.os = String::from("Windows");
|
||||||
|
default.os_version = Some(String::from("10"));
|
||||||
|
|
||||||
|
default.client_build_number = 199933;
|
||||||
|
default.release_channel = String::from("stable");
|
||||||
|
|
||||||
|
return default;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,33 @@
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
use crate::types::{Integration, WebSocketEvent};
|
||||||
|
|
||||||
|
#[derive(Debug, Default, Deserialize, Serialize)]
|
||||||
|
/// See https://discord.com/developers/docs/topics/gateway-events#integration-create
|
||||||
|
pub struct IntegrationCreate {
|
||||||
|
#[serde(flatten)]
|
||||||
|
pub integration: Integration,
|
||||||
|
pub guild_id: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl WebSocketEvent for IntegrationCreate {}
|
||||||
|
|
||||||
|
#[derive(Debug, Default, Deserialize, Serialize)]
|
||||||
|
/// See https://discord.com/developers/docs/topics/gateway-events#integration-update
|
||||||
|
pub struct IntegrationUpdate {
|
||||||
|
#[serde(flatten)]
|
||||||
|
pub integration: Integration,
|
||||||
|
pub guild_id: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl WebSocketEvent for IntegrationUpdate {}
|
||||||
|
|
||||||
|
#[derive(Debug, Default, Deserialize, Serialize)]
|
||||||
|
/// See https://discord.com/developers/docs/topics/gateway-events#integration-delete
|
||||||
|
pub struct IntegrationDelete {
|
||||||
|
pub id: String,
|
||||||
|
pub guild_id: String,
|
||||||
|
pub application_id: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl WebSocketEvent for IntegrationDelete {}
|
|
@ -0,0 +1,12 @@
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
use crate::types::{Interaction, WebSocketEvent};
|
||||||
|
|
||||||
|
#[derive(Debug, Default, Deserialize, Serialize)]
|
||||||
|
/// See https://discord.com/developers/docs/topics/gateway-events#interaction-create
|
||||||
|
pub struct InteractionCreate {
|
||||||
|
#[serde(flatten)]
|
||||||
|
pub interaction: Interaction,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl WebSocketEvent for InteractionCreate {}
|
|
@ -0,0 +1,22 @@
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
use crate::types::{GuildInvite, WebSocketEvent};
|
||||||
|
|
||||||
|
#[derive(Debug, Default, Deserialize, Serialize)]
|
||||||
|
/// See https://discord.com/developers/docs/topics/gateway-events#invite-create
|
||||||
|
pub struct InviteCreate {
|
||||||
|
#[serde(flatten)]
|
||||||
|
pub invite: GuildInvite
|
||||||
|
}
|
||||||
|
|
||||||
|
impl WebSocketEvent for InviteCreate {}
|
||||||
|
|
||||||
|
#[derive(Debug, Default, Deserialize, Serialize)]
|
||||||
|
/// See https://discord.com/developers/docs/topics/gateway-events#invite-delete
|
||||||
|
pub struct InviteDelete {
|
||||||
|
pub channel_id: String,
|
||||||
|
pub guild_id: Option<String>,
|
||||||
|
pub code: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl WebSocketEvent for InviteDelete {}
|
|
@ -0,0 +1,27 @@
|
||||||
|
use std::collections::HashMap;
|
||||||
|
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
use super::WebSocketEvent;
|
||||||
|
|
||||||
|
#[derive(Debug, Deserialize, Serialize, Default)]
|
||||||
|
/// Officially Undocumented
|
||||||
|
///
|
||||||
|
/// Sent to the server to signify lazy loading of a guild;
|
||||||
|
/// Sent by the official client when switching to a guild or channel;
|
||||||
|
/// After this, you should recieve message updates
|
||||||
|
///
|
||||||
|
/// See https://luna.gitlab.io/discord-unofficial-docs/lazy_guilds.html#op-14-lazy-request
|
||||||
|
///
|
||||||
|
/// {"op":14,"d":{"guild_id":"848582562217590824","typing":true,"activities":true,"threads":true}}
|
||||||
|
pub struct LazyRequest {
|
||||||
|
pub guild_id: String,
|
||||||
|
pub typing: bool,
|
||||||
|
pub activities: bool,
|
||||||
|
pub threads: bool,
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub members: Option<bool>,
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub channels: Option<HashMap<String, Vec<Vec<u64>>>>
|
||||||
|
}
|
||||||
|
impl WebSocketEvent for LazyRequest {}
|
|
@ -1,3 +1,4 @@
|
||||||
|
use chrono::{DateTime, Utc};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
use crate::types::{
|
use crate::types::{
|
||||||
|
@ -19,12 +20,43 @@ pub struct TypingStartEvent {
|
||||||
impl WebSocketEvent for TypingStartEvent {}
|
impl WebSocketEvent for TypingStartEvent {}
|
||||||
|
|
||||||
#[derive(Debug, Serialize, Deserialize, Default)]
|
#[derive(Debug, Serialize, Deserialize, Default)]
|
||||||
|
/// See https://discord.com/developers/docs/topics/gateway-events#message-create
|
||||||
pub struct MessageCreate {
|
pub struct MessageCreate {
|
||||||
#[serde(flatten)]
|
#[serde(flatten)]
|
||||||
message: Message,
|
message: Message,
|
||||||
guild_id: Option<Snowflake>,
|
guild_id: Option<String>,
|
||||||
member: Option<GuildMember>,
|
member: Option<GuildMember>,
|
||||||
mentions: Vec<(User, GuildMember)>, // Not sure if this is correct: https://discord.com/developers/docs/topics/gateway-events#message-create
|
mentions: Option<Vec<MessageCreateUser>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize, Deserialize, Default)]
|
||||||
|
/// See https://discord.com/developers/docs/topics/gateway-events#message-create-message-create-extra-fields
|
||||||
|
pub struct MessageCreateUser {
|
||||||
|
pub id: String,
|
||||||
|
username: String,
|
||||||
|
discriminator: String,
|
||||||
|
avatar: Option<String>,
|
||||||
|
bot: Option<bool>,
|
||||||
|
system: Option<bool>,
|
||||||
|
mfa_enabled: Option<bool>,
|
||||||
|
accent_color: Option<String>,
|
||||||
|
locale: Option<String>,
|
||||||
|
verified: Option<bool>,
|
||||||
|
email: Option<String>,
|
||||||
|
premium_since: Option<String>,
|
||||||
|
premium_type: Option<i8>,
|
||||||
|
pronouns: Option<String>,
|
||||||
|
public_flags: Option<i32>,
|
||||||
|
banner: Option<String>,
|
||||||
|
bio: Option<String>,
|
||||||
|
theme_colors: Option<Vec<i32>>,
|
||||||
|
phone: Option<String>,
|
||||||
|
nsfw_allowed: Option<bool>,
|
||||||
|
premium: Option<bool>,
|
||||||
|
purchased_flags: Option<i32>,
|
||||||
|
premium_usage_flags: Option<i32>,
|
||||||
|
disabled: Option<bool>,
|
||||||
|
member: GuildMember
|
||||||
}
|
}
|
||||||
|
|
||||||
impl WebSocketEvent for MessageCreate {}
|
impl WebSocketEvent for MessageCreate {}
|
||||||
|
@ -35,7 +67,7 @@ pub struct MessageUpdate {
|
||||||
message: Message,
|
message: Message,
|
||||||
guild_id: Option<String>,
|
guild_id: Option<String>,
|
||||||
member: Option<GuildMember>,
|
member: Option<GuildMember>,
|
||||||
mentions: Vec<(User, GuildMember)>, // Not sure if this is correct: https://discord.com/developers/docs/topics/gateway-events#message-create
|
mentions: Option<Vec<(User, GuildMember)>>, // Not sure if this is correct: https://discord.com/developers/docs/topics/gateway-events#message-create
|
||||||
}
|
}
|
||||||
|
|
||||||
impl WebSocketEvent for MessageUpdate {}
|
impl WebSocketEvent for MessageUpdate {}
|
||||||
|
@ -99,3 +131,23 @@ pub struct MessageReactionRemoveEmoji {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl WebSocketEvent for MessageReactionRemoveEmoji {}
|
impl WebSocketEvent for MessageReactionRemoveEmoji {}
|
||||||
|
|
||||||
|
#[derive(Debug, Deserialize, Serialize, Default)]
|
||||||
|
/// Officially Undocumented
|
||||||
|
///
|
||||||
|
/// Not documented anywhere unofficially
|
||||||
|
///
|
||||||
|
/// Apparently "Message ACK refers to marking a message as read for Discord's API." (https://github.com/Rapptz/discord.py/issues/1851)
|
||||||
|
/// I suspect this is sent and recieved from the gateway to let clients on other devices know the user has read a message
|
||||||
|
///
|
||||||
|
/// {"t":"MESSAGE_ACK","s":3,"op":0,"d":{"version":52,"message_id":"1107236673638633472","last_viewed":null,"flags":null,"channel_id":"967363950217936897"}}
|
||||||
|
pub struct MessageACK {
|
||||||
|
/// ?
|
||||||
|
pub version: u16,
|
||||||
|
pub message_id: String,
|
||||||
|
pub last_viewed: Option<DateTime<Utc>>,
|
||||||
|
/// What flags?
|
||||||
|
pub flags: Option<serde_json::Value>,
|
||||||
|
pub channel_id: String,
|
||||||
|
}
|
||||||
|
impl WebSocketEvent for MessageACK {}
|
|
@ -12,7 +12,19 @@ mod request_members;
|
||||||
mod resume;
|
mod resume;
|
||||||
mod thread;
|
mod thread;
|
||||||
mod user;
|
mod user;
|
||||||
mod voice_status;
|
mod voice;
|
||||||
|
mod session;
|
||||||
|
mod webhooks;
|
||||||
|
mod passive_update;
|
||||||
|
mod integration;
|
||||||
|
mod invite;
|
||||||
|
mod call;
|
||||||
|
mod lazy_request;
|
||||||
|
mod relationship;
|
||||||
|
mod auto_moderation;
|
||||||
|
mod stage_instance;
|
||||||
|
mod interaction;
|
||||||
|
mod application;
|
||||||
|
|
||||||
pub use channel::*;
|
pub use channel::*;
|
||||||
pub use guild::*;
|
pub use guild::*;
|
||||||
|
@ -26,16 +38,49 @@ pub use request_members::*;
|
||||||
pub use resume::*;
|
pub use resume::*;
|
||||||
pub use thread::*;
|
pub use thread::*;
|
||||||
pub use user::*;
|
pub use user::*;
|
||||||
pub use voice_status::*;
|
pub use voice::*;
|
||||||
|
pub use session::*;
|
||||||
|
pub use webhooks::*;
|
||||||
|
pub use passive_update::*;
|
||||||
|
pub use integration::*;
|
||||||
|
pub use invite::*;
|
||||||
|
pub use call::*;
|
||||||
|
pub use lazy_request::*;
|
||||||
|
pub use relationship::*;
|
||||||
|
pub use auto_moderation::*;
|
||||||
|
pub use stage_instance::*;
|
||||||
|
pub use interaction::*;
|
||||||
|
pub use application::*;
|
||||||
|
|
||||||
pub trait WebSocketEvent {}
|
pub trait WebSocketEvent {}
|
||||||
|
|
||||||
#[derive(Debug, Default, Deserialize, Serialize)]
|
#[derive(Debug, Default, Serialize, Clone)]
|
||||||
pub struct GatewayPayload {
|
/// The payload used for sending events to the gateway
|
||||||
|
///
|
||||||
|
/// Similar to [GatewayReceivePayload], except we send a [Value] for d whilst we receive a [serde_json::value::RawValue]
|
||||||
|
/// Also, we never need to send the event name
|
||||||
|
pub struct GatewaySendPayload {
|
||||||
pub op: u8,
|
pub op: u8,
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
pub d: Option<serde_json::Value>,
|
pub d: Option<serde_json::Value>,
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub s: Option<u64>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl WebSocketEvent for GatewaySendPayload {}
|
||||||
|
|
||||||
|
#[derive(Debug, Default, Deserialize, Clone)]
|
||||||
|
/// The payload used for receiving events from the gateway
|
||||||
|
///
|
||||||
|
/// Similar to [GatewaySendPayload], except we send a [Value] for d whilst we receive a [serde_json::value::RawValue]
|
||||||
|
/// Also, we never need to sent the event name
|
||||||
|
|
||||||
|
pub struct GatewayReceivePayload<'a> {
|
||||||
|
pub op: u8,
|
||||||
|
#[serde(borrow)]
|
||||||
|
pub d: Option<&'a serde_json::value::RawValue>,
|
||||||
pub s: Option<u64>,
|
pub s: Option<u64>,
|
||||||
pub t: Option<String>,
|
pub t: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl WebSocketEvent for GatewayPayload {}
|
impl<'a> WebSocketEvent for GatewayReceivePayload<'a> {}
|
||||||
|
|
|
@ -0,0 +1,17 @@
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
use crate::types::{VoiceState, GuildMember};
|
||||||
|
use super::{ChannelUnreadUpdateObject, WebSocketEvent};
|
||||||
|
|
||||||
|
#[derive(Debug, Deserialize, Serialize, Default)]
|
||||||
|
/// Officially Undocumented
|
||||||
|
///
|
||||||
|
/// Seems to be passively set to update the client on guild details (though, why not just send the update events?)
|
||||||
|
pub struct PassiveUpdateV1 {
|
||||||
|
pub voice_states: Vec<VoiceState>,
|
||||||
|
pub members: Vec<GuildMember>,
|
||||||
|
pub guild_id: String,
|
||||||
|
pub channels: Vec<ChannelUnreadUpdateObject>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl WebSocketEvent for PassiveUpdateV1 {}
|
|
@ -1,4 +1,4 @@
|
||||||
use crate::types::entities::User;
|
use crate::types::PublicUser;
|
||||||
use crate::types::events::WebSocketEvent;
|
use crate::types::events::WebSocketEvent;
|
||||||
use crate::types::interfaces::Activity;
|
use crate::types::interfaces::Activity;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
@ -6,8 +6,8 @@ use serde::{Deserialize, Serialize};
|
||||||
#[derive(Debug, Deserialize, Serialize, Default, Clone)]
|
#[derive(Debug, Deserialize, Serialize, Default, Clone)]
|
||||||
/// See https://discord.com/developers/docs/topics/gateway-events#presence-update-presence-update-event-fields
|
/// See https://discord.com/developers/docs/topics/gateway-events#presence-update-presence-update-event-fields
|
||||||
pub struct PresenceUpdate {
|
pub struct PresenceUpdate {
|
||||||
pub user: User,
|
pub user: PublicUser,
|
||||||
pub guild_id: String,
|
pub guild_id: Option<String>,
|
||||||
pub status: String,
|
pub status: String,
|
||||||
pub activities: Vec<Activity>,
|
pub activities: Vec<Activity>,
|
||||||
pub client_status: ClientStatusObject,
|
pub client_status: ClientStatusObject,
|
||||||
|
|
|
@ -1,15 +1,77 @@
|
||||||
use crate::types::entities::{UnavailableGuild, User};
|
use crate::types::entities::{UnavailableGuild, User, Guild};
|
||||||
use crate::types::events::WebSocketEvent;
|
use crate::types::events::{WebSocketEvent, Session};
|
||||||
|
use crate::types::interfaces::ClientStatusObject;
|
||||||
|
use crate::types::{PresenceUpdate, GuildMember, Activity, VoiceState};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
#[derive(Debug, Deserialize, Serialize, Default)]
|
#[derive(Debug, Deserialize, Serialize, Default)]
|
||||||
|
/// Sort of documented, though most fields are left out
|
||||||
|
/// For a full example see https://gist.github.com/kozabrada123/a347002b1fb8825a5727e40746d4e199
|
||||||
|
/// to:do add all undocumented fields
|
||||||
pub struct GatewayReady {
|
pub struct GatewayReady {
|
||||||
|
pub analytics_token: Option<String>,
|
||||||
|
pub auth_session_id_hash: Option<String>,
|
||||||
|
pub country_code: Option<String>,
|
||||||
|
|
||||||
pub v: u8,
|
pub v: u8,
|
||||||
pub user: User,
|
pub user: User,
|
||||||
pub guilds: Vec<UnavailableGuild>,
|
/// For bots these are [UnavailableGuild]s, for users they are [Guild]
|
||||||
|
pub guilds: Vec<Guild>,
|
||||||
|
pub presences: Option<Vec<PresenceUpdate>>,
|
||||||
|
pub sessions: Option<Vec<Session>>,
|
||||||
pub session_id: String,
|
pub session_id: String,
|
||||||
|
pub session_type: Option<String>,
|
||||||
pub resume_gateway_url: Option<String>,
|
pub resume_gateway_url: Option<String>,
|
||||||
pub shard: Option<(u64, u64)>,
|
pub shard: Option<(u64, u64)>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl WebSocketEvent for GatewayReady {}
|
impl WebSocketEvent for GatewayReady {}
|
||||||
|
|
||||||
|
#[derive(Debug, Deserialize, Serialize, Default)]
|
||||||
|
/// Officially Undocumented
|
||||||
|
/// Sent after the READY event when a client is a user
|
||||||
|
/// {"t":"READY_SUPPLEMENTAL","s":2,"op":0,"d":{"merged_presences":{"guilds":[[{"user_id":"463640391196082177","status":"online","game":null,"client_status":{"web":"online"},"activities":[]}]],"friends":[{"user_id":"463640391196082177","status":"online","last_modified":1684053508443,"client_status":{"web":"online"},"activities":[]}]},"merged_members":[[{"user_id":"463640391196082177","roles":[],"premium_since":null,"pending":false,"nick":"pog","mute":false,"joined_at":"2021-05-30T15:24:08.763000+00:00","flags":0,"deaf":false,"communication_disabled_until":null,"avatar":null}]],"lazy_private_channels":[],"guilds":[{"voice_states":[],"id":"848582562217590824","embedded_activities":[]}],"disclose":["pomelo"]}}
|
||||||
|
pub struct GatewayReadySupplemental {
|
||||||
|
pub merged_presences: MergedPresences,
|
||||||
|
pub merged_members: Vec<Vec<GuildMember>>,
|
||||||
|
// ?
|
||||||
|
pub lazy_private_channels: Vec<serde_json::Value>,
|
||||||
|
pub guilds: Vec<SupplimentalGuild>,
|
||||||
|
// ? pomelo
|
||||||
|
pub disclose: Vec<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl WebSocketEvent for GatewayReadySupplemental {}
|
||||||
|
|
||||||
|
#[derive(Debug, Deserialize, Serialize, Default)]
|
||||||
|
pub struct MergedPresences {
|
||||||
|
pub guilds: Vec<Vec<MergedPresenceGuild>>,
|
||||||
|
pub friends: Vec<MergedPresenceFriend>
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Deserialize, Serialize, Default)]
|
||||||
|
pub struct MergedPresenceFriend {
|
||||||
|
pub user_id: String,
|
||||||
|
pub status: String,
|
||||||
|
/// Looks like ms??
|
||||||
|
pub last_modified: u128,
|
||||||
|
pub client_status: ClientStatusObject,
|
||||||
|
pub activities: Vec<Activity>
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Deserialize, Serialize, Default)]
|
||||||
|
pub struct MergedPresenceGuild {
|
||||||
|
pub user_id: String,
|
||||||
|
pub status: String,
|
||||||
|
// ?
|
||||||
|
pub game: Option<serde_json::Value>,
|
||||||
|
pub client_status: ClientStatusObject,
|
||||||
|
pub activities: Vec<Activity>
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Deserialize, Serialize, Default)]
|
||||||
|
pub struct SupplimentalGuild {
|
||||||
|
pub voice_states: Option<Vec<VoiceState>>,
|
||||||
|
pub id: String,
|
||||||
|
pub embedded_activities: Vec<serde_json::Value>
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,22 @@
|
||||||
|
use crate::types::{events::WebSocketEvent, Relationship, Snowflake, RelationshipType};
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
#[derive(Debug, Deserialize, Serialize, Default)]
|
||||||
|
/// See https://github.com/spacebarchat/server/issues/204
|
||||||
|
pub struct RelationshipAdd {
|
||||||
|
#[serde(flatten)]
|
||||||
|
pub relationship: Relationship,
|
||||||
|
pub should_notify: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl WebSocketEvent for RelationshipAdd {}
|
||||||
|
|
||||||
|
#[derive(Debug, Deserialize, Serialize, Default)]
|
||||||
|
/// See https://github.com/spacebarchat/server/issues/203
|
||||||
|
pub struct RelationshipRemove {
|
||||||
|
pub id: Snowflake,
|
||||||
|
#[serde(rename = "type")]
|
||||||
|
pub relationship_type: RelationshipType,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl WebSocketEvent for RelationshipRemove {}
|
|
@ -7,7 +7,7 @@ pub struct GatewayRequestGuildMembers {
|
||||||
pub guild_id: String,
|
pub guild_id: String,
|
||||||
pub query: Option<String>,
|
pub query: Option<String>,
|
||||||
pub limit: u64,
|
pub limit: u64,
|
||||||
pub presence: Option<bool>,
|
pub presences: Option<bool>,
|
||||||
pub user_ids: Option<String>,
|
pub user_ids: Option<String>,
|
||||||
pub nonce: Option<String>,
|
pub nonce: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,32 @@
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
use crate::types::{Activity, WebSocketEvent};
|
||||||
|
|
||||||
|
#[derive(Debug, Deserialize, Serialize, Default)]
|
||||||
|
/// Officially Undocumented
|
||||||
|
/// Seems like it sends active session info to users on connect
|
||||||
|
/// [{"activities":[],"client_info":{"client":"web","os":"other","version":0},"session_id":"ab5941b50d818b1f8d93b4b1b581b192","status":"online"}]
|
||||||
|
pub struct SessionsReplace {
|
||||||
|
pub sessions: Vec<Session>
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Deserialize, Serialize, Default)]
|
||||||
|
/// Session info for the current user
|
||||||
|
pub struct Session {
|
||||||
|
pub activities: Vec<Activity>,
|
||||||
|
pub client_info: ClientInfo,
|
||||||
|
pub session_id: String,
|
||||||
|
pub status: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Deserialize, Serialize, Default)]
|
||||||
|
/// Another Client info object
|
||||||
|
/// {"client":"web","os":"other","version":0}
|
||||||
|
// Note: I don't think this one exists yet? Though I might've made a mistake and this might be a duplicate
|
||||||
|
pub struct ClientInfo {
|
||||||
|
pub client: String,
|
||||||
|
pub os: String,
|
||||||
|
pub version: u8
|
||||||
|
}
|
||||||
|
|
||||||
|
impl WebSocketEvent for SessionsReplace {}
|
|
@ -0,0 +1,30 @@
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
use crate::types::{WebSocketEvent, StageInstance};
|
||||||
|
|
||||||
|
#[derive(Debug, Deserialize, Serialize, Default)]
|
||||||
|
/// See https://discord.com/developers/docs/topics/gateway-events#stage-instance-create
|
||||||
|
pub struct StageInstanceCreate {
|
||||||
|
#[serde(flatten)]
|
||||||
|
pub stage_instance: StageInstance,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl WebSocketEvent for StageInstanceCreate {}
|
||||||
|
|
||||||
|
#[derive(Debug, Deserialize, Serialize, Default)]
|
||||||
|
/// See https://discord.com/developers/docs/topics/gateway-events#stage-instance-update
|
||||||
|
pub struct StageInstanceUpdate {
|
||||||
|
#[serde(flatten)]
|
||||||
|
pub stage_instance: StageInstance,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl WebSocketEvent for StageInstanceUpdate {}
|
||||||
|
|
||||||
|
#[derive(Debug, Deserialize, Serialize, Default)]
|
||||||
|
/// See https://discord.com/developers/docs/topics/gateway-events#stage-instance-delete
|
||||||
|
pub struct StageInstanceDelete {
|
||||||
|
#[serde(flatten)]
|
||||||
|
pub stage_instance: StageInstance,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl WebSocketEvent for StageInstanceDelete {}
|
|
@ -4,8 +4,8 @@ use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
#[derive(Debug, Default, Deserialize, Serialize)]
|
#[derive(Debug, Default, Deserialize, Serialize)]
|
||||||
/// See https://discord.com/developers/docs/topics/gateway-events#thread-create
|
/// See https://discord.com/developers/docs/topics/gateway-events#thread-create
|
||||||
/// Not directly serialized, as the inner payload is a channel object
|
|
||||||
pub struct ThreadCreate {
|
pub struct ThreadCreate {
|
||||||
|
#[serde(flatten)]
|
||||||
pub thread: Channel,
|
pub thread: Channel,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -13,8 +13,8 @@ impl WebSocketEvent for ThreadCreate {}
|
||||||
|
|
||||||
#[derive(Debug, Default, Deserialize, Serialize)]
|
#[derive(Debug, Default, Deserialize, Serialize)]
|
||||||
/// See https://discord.com/developers/docs/topics/gateway-events#thread-update
|
/// See https://discord.com/developers/docs/topics/gateway-events#thread-update
|
||||||
/// Not directly serialized, as the inner payload is a channel object
|
|
||||||
pub struct ThreadUpdate {
|
pub struct ThreadUpdate {
|
||||||
|
#[serde(flatten)]
|
||||||
pub thread: Channel,
|
pub thread: Channel,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -22,8 +22,8 @@ impl WebSocketEvent for ThreadUpdate {}
|
||||||
|
|
||||||
#[derive(Debug, Default, Deserialize, Serialize)]
|
#[derive(Debug, Default, Deserialize, Serialize)]
|
||||||
/// See https://discord.com/developers/docs/topics/gateway-events#thread-delete
|
/// See https://discord.com/developers/docs/topics/gateway-events#thread-delete
|
||||||
/// Not directly serialized, as the inner payload is a channel object
|
|
||||||
pub struct ThreadDelete {
|
pub struct ThreadDelete {
|
||||||
|
#[serde(flatten)]
|
||||||
pub thread: Channel,
|
pub thread: Channel,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -43,29 +43,12 @@ impl WebSocketEvent for ThreadListSync {}
|
||||||
#[derive(Debug, Default, Deserialize, Serialize)]
|
#[derive(Debug, Default, Deserialize, Serialize)]
|
||||||
/// See https://discord.com/developers/docs/topics/gateway-events#thread-member-update
|
/// See https://discord.com/developers/docs/topics/gateway-events#thread-member-update
|
||||||
/// The inner payload is a thread member object with an extra field.
|
/// The inner payload is a thread member object with an extra field.
|
||||||
/// The extra field is a bit painful, because we can't just serialize a thread member object
|
|
||||||
pub struct ThreadMemberUpdate {
|
pub struct ThreadMemberUpdate {
|
||||||
pub id: Option<u64>,
|
#[serde(flatten)]
|
||||||
pub user_id: Option<u64>,
|
pub member: ThreadMember,
|
||||||
pub join_timestamp: Option<String>,
|
|
||||||
pub flags: Option<u64>,
|
|
||||||
pub member: Option<GuildMember>,
|
|
||||||
pub guild_id: String,
|
pub guild_id: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ThreadMemberUpdate {
|
|
||||||
/// Convert self to a thread member, losing the added guild_id field
|
|
||||||
pub fn to_thread_member(self) -> ThreadMember {
|
|
||||||
ThreadMember {
|
|
||||||
id: self.id,
|
|
||||||
user_id: self.user_id,
|
|
||||||
join_timestamp: self.join_timestamp.clone(),
|
|
||||||
flags: self.flags,
|
|
||||||
member: self.member,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl WebSocketEvent for ThreadMemberUpdate {}
|
impl WebSocketEvent for ThreadMemberUpdate {}
|
||||||
|
|
||||||
#[derive(Debug, Default, Deserialize, Serialize)]
|
#[derive(Debug, Default, Deserialize, Serialize)]
|
||||||
|
|
|
@ -4,8 +4,8 @@ use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
#[derive(Debug, Default, Deserialize, Serialize)]
|
#[derive(Debug, Default, Deserialize, Serialize)]
|
||||||
/// See https://discord.com/developers/docs/topics/gateway-events#user-update
|
/// See https://discord.com/developers/docs/topics/gateway-events#user-update
|
||||||
/// Not directly serialized, as the inner payload is the user object
|
|
||||||
pub struct UserUpdate {
|
pub struct UserUpdate {
|
||||||
|
#[serde(flatten)]
|
||||||
pub user: User,
|
pub user: User,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,40 @@
|
||||||
|
use crate::types::{events::WebSocketEvent, VoiceState};
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
#[derive(Debug, Deserialize, Serialize, Default)]
|
||||||
|
/// See https://discord.com/developers/docs/topics/gateway-events#update-voice-state
|
||||||
|
///
|
||||||
|
/// Sent to the server
|
||||||
|
///
|
||||||
|
/// Not to be confused with [VoiceStateUpdate]
|
||||||
|
pub struct UpdateVoiceState {
|
||||||
|
pub guild_id: Option<String>,
|
||||||
|
pub channel_id: Option<String>,
|
||||||
|
pub self_mute: bool,
|
||||||
|
pub self_deaf: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl WebSocketEvent for UpdateVoiceState {}
|
||||||
|
|
||||||
|
#[derive(Debug, Deserialize, Serialize, Default)]
|
||||||
|
/// See https://discord.com/developers/docs/topics/gateway-events#voice-state-update
|
||||||
|
///
|
||||||
|
/// Received from the server
|
||||||
|
///
|
||||||
|
/// Not to be confused with [UpdateVoiceState]
|
||||||
|
pub struct VoiceStateUpdate {
|
||||||
|
#[serde(flatten)]
|
||||||
|
pub state: VoiceState
|
||||||
|
}
|
||||||
|
|
||||||
|
impl WebSocketEvent for VoiceStateUpdate {}
|
||||||
|
|
||||||
|
#[derive(Debug, Deserialize, Serialize, Default)]
|
||||||
|
/// See https://discord.com/developers/docs/topics/gateway-events#voice-server-update
|
||||||
|
pub struct VoiceServerUpdate {
|
||||||
|
pub token: String,
|
||||||
|
pub guild_id: String,
|
||||||
|
pub endpoint: Option<String>
|
||||||
|
}
|
||||||
|
|
||||||
|
impl WebSocketEvent for VoiceServerUpdate {}
|
|
@ -1,13 +0,0 @@
|
||||||
use crate::types::events::WebSocketEvent;
|
|
||||||
use serde::{Deserialize, Serialize};
|
|
||||||
|
|
||||||
#[derive(Debug, Deserialize, Serialize, Default)]
|
|
||||||
/// See https://discord.com/developers/docs/topics/gateway-events#update-voice-state-gateway-voice-state-update-structure
|
|
||||||
pub struct GatewayVoiceStateUpdate {
|
|
||||||
pub guild_id: String,
|
|
||||||
pub channel_id: Option<String>,
|
|
||||||
pub self_mute: bool,
|
|
||||||
pub self_deaf: bool,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl WebSocketEvent for GatewayVoiceStateUpdate {}
|
|
|
@ -0,0 +1,12 @@
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
use super::WebSocketEvent;
|
||||||
|
|
||||||
|
#[derive(Debug, Deserialize, Serialize, Default)]
|
||||||
|
/// See https://discord.com/developers/docs/topics/gateway-events#webhooks-update
|
||||||
|
pub struct WebhooksUpdate {
|
||||||
|
pub guild_id: String,
|
||||||
|
pub channel_id: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl WebSocketEvent for WebhooksUpdate {}
|
|
@ -3,7 +3,7 @@ use crate::types::utils::Snowflake;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use serde_json::Value;
|
use serde_json::Value;
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
#[derive(Debug, Default, Clone, PartialEq, Serialize, Deserialize)]
|
||||||
pub struct Interaction {
|
pub struct Interaction {
|
||||||
pub id: Snowflake,
|
pub id: Snowflake,
|
||||||
pub r#type: InteractionType,
|
pub r#type: InteractionType,
|
||||||
|
@ -15,8 +15,9 @@ pub struct Interaction {
|
||||||
pub version: i32,
|
pub version: i32,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
#[derive(Debug, Default, Clone, PartialEq, Serialize, Deserialize)]
|
||||||
pub enum InteractionType {
|
pub enum InteractionType {
|
||||||
|
#[default]
|
||||||
SelfCommand = 0,
|
SelfCommand = 0,
|
||||||
Ping = 1,
|
Ping = 1,
|
||||||
ApplicationCommand = 2,
|
ApplicationCommand = 2,
|
||||||
|
|
Loading…
Reference in New Issue