use futures_util::future::{select, Either};
use grammers_client::session::Session;
use grammers_client::{Client, Config, InitParams, Update};
use simple_logger::SimpleLogger;
use std::env;
use std::pin::pin;
use tokio::{runtime, task};
type Result = std::result::Result<(), Box<dyn std::error::Error>>;
const SESSION_FILE: &str = "echo.session";
async fn handle_update(client: Client, update: Update) -> Result {
match update {
Update::NewMessage(message) if !message.outgoing() => {
let chat = message.chat();
println!("Responding to {}", chat.name());
client.send_message(&chat, message.text()).await?;
}
_ => {}
}
Ok(())
}
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();
let token = env::args().nth(1).expect("token missing");
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: InitParams {
catch_up: true,
..Default::default()
},
})
.await?;
println!("Connected!");
if !client.is_authorized().await? {
println!("Signing in...");
client.bot_sign_in(&token).await?;
client.session().save_to_file(SESSION_FILE)?;
println!("Signed in!");
}
println!("Waiting for messages...");
loop {
let exit = pin!(async { tokio::signal::ctrl_c().await });
let upd = pin!(async { client.next_update().await });
let update = match select(exit, upd).await {
Either::Left(_) => break,
Either::Right((u, _)) => u?,
};
let handle = client.clone();
task::spawn(async move {
match handle_update(handle, update).await {
Ok(_) => {}
Err(e) => eprintln!("Error handling updates!: {e}"),
}
});
}
println!("Saving session file and exiting...");
client.session().save_to_file(SESSION_FILE)?;
Ok(())
}
fn main() -> Result {
runtime::Builder::new_current_thread()
.enable_all()
.build()
.unwrap()
.block_on(async_main())
}