You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
97 lines
2.6 KiB
Rust
97 lines
2.6 KiB
Rust
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<DiscordEvent>);
|
|
|
|
pub struct DiscordSocket {
|
|
sender: Sender<DiscordEvent>,
|
|
ws: WebSocketStream<
|
|
tokio_tungstenite::stream::Stream<
|
|
tokio::net::TcpStream,
|
|
tokio_tls::TlsStream<tokio::net::TcpStream>,
|
|
>,
|
|
>,
|
|
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::<GatewayEvent>(&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<TcpStream>".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));
|
|
}
|
|
}
|