use crate::discord::api::Error; use crate::discord::dto::{GatewayEvent, GatewayOpcode, Identify, IdentifyProperties}; use futures::future::IntoFuture; use futures::SinkExt; use reqwest::Identity; use std::sync::mpsc::{channel, Receiver, Sender}; use tokio::net::TcpStream; use tokio::stream::StreamExt; use tokio_tungstenite::{connect_async, WebSocketStream}; use tungstenite::handshake::client::Request; use tungstenite::{Message, WebSocket}; pub enum DiscordEvent {} pub struct DiscordReceiver(pub Receiver); pub struct DiscordSocket { sender: Sender, ws: WebSocketStream< tokio_tungstenite::stream::Stream< tokio::net::TcpStream, tokio_tls::TlsStream, >, >, token: String, } pub async fn connect_discord_ws( url: String, auth: String, ) -> Result<(DiscordSocket, DiscordReceiver), Error> { let (s, r) = channel(); let connect = connect_async(Request { url: url::Url::parse(&url).unwrap(), extra_headers: Some(vec![("Authorization".into(), auth.clone().into())]), }) .await .unwrap(); let (stream, resp) = connect; let status = resp.code; if status != 101 { return Err(Error::Failed(status)); } let receiver = DiscordReceiver(r); let socket = DiscordSocket { sender: s, ws: stream, token: auth, }; Ok((socket, receiver)) } impl DiscordSocket { pub async fn start(&mut self) { while let Some(message) = self.ws.next().await { let msg = message.unwrap(); match msg { Message::Text(ok) => { let event = serde_json::from_str::(&ok); println!("event: {:?}", event) } _ => { println!("something else"); } } } } fn identify(&mut self) { let identify = Identify { token: self.token.clone(), properties: IdentifyProperties { os: "linux".to_string(), browser: "unredeemed".to_string(), device: "WebSocketStream".to_string(), }, }; let value = serde_json::to_value(identify).unwrap(); let event = GatewayEvent { opcode: GatewayOpcode::Identify, data: value, sequence_num: None, event_name: None, }; let data = serde_json::to_vec(&event).unwrap(); self.ws.send(Message::Binary(data)); } }