use std::ops::ControlFlow;
use std::time::Duration;
use grammers_client::session::Session;
use grammers_client::{Client, Config, ReconnectionPolicy, SignInError};
use log::{error, info};
use crate::prompt::prompt;
pub const SESSION_FILE: &str = "./data/telepAIr.session";
struct ReconectPolicy;
impl ReconnectionPolicy for ReconectPolicy {
fn should_retry(&self, attempts: usize) -> std::ops::ControlFlow<(), std::time::Duration> {
if attempts < 4 {
let duration = u64::pow(2, attempts as _);
ControlFlow::Continue(Duration::from_millis(duration))
} else {
ControlFlow::Break(())
}
}
}
pub async fn establish_telegram_connection(
api_id: i32,
api_hash: String,
) -> Result<(Client, bool), Box<dyn std::error::Error>> {
info!("Connecting to Telegram...");
let session = match Session::load_file_or_create(SESSION_FILE) {
Ok(session) => {
info!("Loaded our saved session");
Ok(session)
}
Err(e) => {
error!("Failed to load session, {e}");
Err(e)
}
}?;
let client = Client::connect(Config {
session,
api_id,
api_hash,
params: grammers_client::InitParams {
reconnection_policy: &ReconectPolicy,
..Default::default()
},
})
.await?;
info!("Telegram Connected!");
let mut sign_out = false;
if !client.is_authorized().await? {
println!("Signing in...");
let phone = prompt("Enter your phone number (international format): ")?;
let token = client.request_login_code(&phone).await?;
let code = prompt("Enter the code you received: ")?;
let signed_in = client.sign_in(&token, &code).await;
match signed_in {
Err(SignInError::PasswordRequired(password_token)) => {
let hint = password_token.hint().unwrap_or("None");
let prompt_message = format!("Enter the password (hint {}): ", &hint);
let password = prompt(prompt_message.as_str())?;
client
.check_password(password_token, password.trim())
.await?;
}
Ok(_) => (),
Err(e) => panic!("{}", e),
};
info!("Signed in!");
match client.session().save_to_file(SESSION_FILE) {
Ok(_) => {
info!("Saved our session")
}
Err(e) => {
println!("NOTE: failed to save the session, will sign out when done: {e}");
sign_out = true;
}
}
}
Ok((client, sign_out))
}