use std::time::Duration;
use rumqttc::{
MqttOptions,
Protocol,
Transport,
};
use tracing::debug;
use crate::state::State;
const DEFAULT_TOPICS: [&str; 4] = [
"/t_ms",
"/thread_typing",
"/orca_presence",
"/notify_disconnect",
];
const CONNECT_TOPICS: [&str; 22] = [
"/legacy_web",
"/ls_req",
"/ls_resp",
"/t_ms",
"/rtc_multi",
"/thread_typing",
"/orca_typing_notifications",
"/orca_presence",
"/br_sr",
"/friend_request",
"/friending_state_change",
"/friend_requests_seen",
"/sr_res",
"/webrtc",
"/onevc",
"/notify_disconnect",
"/mercury",
"/inbox",
"/messaging_events",
"/orca_message_notifications",
"/pp",
"/webrtc_response",
];
pub(super) fn default_topics() -> &'static [&'static str] {
&DEFAULT_TOPICS
}
pub(super) fn build_connect_options(state: &State, online: bool, session_id: u64) -> MqttOptions {
let websocket_url = format!(
"wss://edge-chat.facebook.com/chat?region={}&sid={}&cid={}",
state.region, session_id, state.mqtt_client_id
);
let username = serde_json::json!({
"u": state.user_id,
"s": session_id,
"chat_on": online,
"fg": online,
"d": state.mqtt_client_id,
"aid": state.mqtt_app_id,
"st": CONNECT_TOPICS,
"pm": [],
"cp": 3,
"ecp": 10,
"ct": "websocket",
"mqtt_sid": "",
"dc": "",
"no_auto_fg": true,
"gas": serde_json::Value::Null,
"pack": [],
"p": serde_json::Value::Null,
"aids": serde_json::Value::Null,
"a": state.user_agent,
});
debug!(
session_id,
online,
region = state.region,
mqtt_client_id = state.mqtt_client_id,
mqtt_app_id = state.mqtt_app_id,
ls_app_id = state.ls_app_id,
ls_version_id = state.ls_version_id,
websocket_url,
"built messenger mqtt connect options"
);
let mut options = MqttOptions::new("mqttwsclient", websocket_url, 443);
options.set_protocol(Protocol::V3);
options.set_clean_session(true);
options.set_keep_alive(Duration::from_secs(60));
options.set_transport(Transport::wss_with_default_config());
options.set_credentials(username.to_string(), String::new());
let cookie = state.cookie_header.clone();
let user_agent = state.user_agent.clone();
options.set_request_modifier(move |mut request| {
let cookie = cookie.clone();
let user_agent = user_agent.clone();
async move {
if let Ok(value) = cookie.parse() {
request.headers_mut().insert("Cookie", value);
}
if let Ok(value) = user_agent.parse() {
request.headers_mut().insert("User-Agent", value);
}
if let Ok(value) = "https://www.facebook.com".parse() {
request.headers_mut().insert("Origin", value);
}
if let Ok(value) = "edge-chat.facebook.com".parse() {
request.headers_mut().insert("Host", value);
}
request
}
});
options
}