use grammers_client::session::Session;
use grammers_client::{Client, Config, SignInError};
use simple_logger::SimpleLogger;
use std::env;
use std::io::{self, BufRead as _, Write as _};
use tokio::runtime;
type Result<T> = std::result::Result<T, Box<dyn std::error::Error>>;
const SESSION_FILE: &str = "dialogs.session";
fn prompt(message: &str) -> Result<String> {
let stdout = io::stdout();
let mut stdout = stdout.lock();
stdout.write_all(message.as_bytes())?;
stdout.flush()?;
let stdin = io::stdin();
let mut stdin = stdin.lock();
let mut line = String::new();
stdin.read_line(&mut line)?;
Ok(line)
}
async fn async_main() -> Result<()> {
SimpleLogger::new()
.with_level(log::LevelFilter::Debug)
.init()
.unwrap();
let api_id = env!("TG_ID").parse().expect("TG_ID invalid");
let api_hash = env!("TG_HASH").to_string();
println!("Connecting to Telegram...");
let client = Client::connect(Config {
session: Session::load_file_or_create(SESSION_FILE)?,
api_id,
api_hash: api_hash.clone(),
params: Default::default(),
})
.await?;
println!("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),
};
println!("Signed in!");
match client.session().save_to_file(SESSION_FILE) {
Ok(_) => {}
Err(e) => {
println!("NOTE: failed to save the session, will sign out when done: {e}");
sign_out = true;
}
}
}
let mut dialogs = client.iter_dialogs();
println!("Showing up to {} dialogs:", dialogs.total().await?);
while let Some(dialog) = dialogs.next().await? {
let chat = dialog.chat();
println!("- {: >10} {}", chat.id(), chat.name());
}
if sign_out {
drop(client.sign_out_disconnect().await);
}
Ok(())
}
fn main() -> Result<()> {
runtime::Builder::new_current_thread()
.enable_all()
.build()
.unwrap()
.block_on(async_main())
}