use current_platform::{COMPILED_ON, CURRENT_PLATFORM};
use db::Database;
use dotenv::dotenv;
use handlers::fabric;
use log::{self, error, info};
use simple_logger::SimpleLogger;
use std::collections::HashMap;
use tokio::{self, runtime};
pub mod db;
pub mod handlers;
pub mod prompt;
pub mod telegram_client;
pub mod updater;
type Result<T> = std::result::Result<T, Box<dyn std::error::Error>>;
async fn async_main() -> Result<()> {
println!(
"TelepAIr v{} running on {} - Compiled on {}.",
env!("CARGO_PKG_VERSION"),
CURRENT_PLATFORM,
COMPILED_ON
);
dotenv().ok();
SimpleLogger::new()
.with_level(log::LevelFilter::Info)
.init()
.unwrap();
let mut db = Database::new();
db.save();
info!("db loaded: ");
let api_id = db.get_api_id();
let api_hash = db.get_api_hash();
info!("Starting telepAIr with {} {}", api_id, api_hash);
let (client, sign_out) =
telegram_client::establish_telegram_connection(api_id, api_hash.to_string()).await?;
fabric::fabric_setup().await?;
fabric::execute_fabric_command(&["--updatepatterns"]).await?;
let me = client.get_me().await?;
let username = me.username().unwrap();
let mut dialogs = client.iter_dialogs();
info!(
"{} ({}) has {} chats",
username,
me.id(),
dialogs.total().await?
);
let mut dialogs = client.iter_dialogs();
let mut chat_map = HashMap::new();
while let Some(dialog) = dialogs.next().await? {
let chat = dialog.chat();
info!("{: >10} - {}", chat.id(), chat.name());
chat_map.insert(chat.id(), chat.name().to_owned());
if me.id() == chat.id() {
info!("Found ME chat - {}", chat.id());
if !db.chat_id_exists(&chat.id()) {
db.add_chat_id(chat.id());
}
client
.send_message(
chat,
format!(
"Hello {}, I am here to serve. `/help` to get started.",
username
),
)
.await?;
}
}
if sign_out {
drop(client.sign_out_disconnect().await);
} else {
tokio::select!(
_ = tokio::signal::ctrl_c() => {
info!("Got SIGINT; quitting early gracefully");
info!("Saving Session");
match client.session().save_to_file(telegram_client::SESSION_FILE) {
Ok(_) => {
info!("Saved our session")
}
Err(e) => {
error!("NOTE: failed to save the sessio {e}");
}
}
let _ = client.sign_out_disconnect().await;
}
r = handlers::update_handler::handle_updates(client.clone(), chat_map, &mut db) => {
match r {
Ok(_) => info!("Got disconnected from Telegram gracefully"),
Err(e) =>{
match client.session().save_to_file(telegram_client::SESSION_FILE) {
Ok(_) => {
info!("Saved our session")
}
Err(e) => {
error!("NOTE: failed to save the sessio {e}");
}
};
error!("Error during update handling: {}", e)
},
}
}
);
}
Ok(())
}
fn main() -> Result<()> {
match updater::update() {
Ok(_) => {}
Err(e) => error!("Auto updater failed {}", e),
};
runtime::Builder::new_current_thread()
.enable_all()
.build()
.unwrap()
.block_on(async_main())
}