use std::env;
use std::io::{self, BufRead as _, Write as _};
use std::sync::Arc;
use grammers_client::{Client, SignInError};
use grammers_mtsender::SenderPool;
use grammers_session::storages::SqliteSession;
use simple_logger::SimpleLogger;
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 session = Arc::new(SqliteSession::open(SESSION_FILE).await?);
let SenderPool { runner, handle, .. } = SenderPool::new(Arc::clone(&session), api_id);
let client = Client::new(handle);
let _ = tokio::spawn(runner.run());
if !client.is_authorized().await? {
println!("Signing in...");
let phone = prompt("Enter your phone number (international format): ")?;
let token = client.request_login_code(&phone, env!("TG_HASH")).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!");
}
let mut dialogs = client.iter_dialogs();
println!("Showing up to {} dialogs:", dialogs.total().await?);
while let Some(dialog) = dialogs.next().await? {
let peer = dialog.peer();
println!("- {: >10} {}", peer.id(), peer.name().unwrap_or_default());
}
Ok(())
}
fn main() -> Result<()> {
runtime::Builder::new_current_thread()
.enable_all()
.build()
.unwrap()
.block_on(async_main())
}