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

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));
}
}