use std::{
env,
path::{Path, PathBuf},
};
use dotenvy::dotenv;
use futures_util::stream::StreamExt;
use tempfile::tempdir;
use tgbot::{
api::Client,
handler::{LongPoll, UpdateHandler},
types::{Document, GetFile, MessageData, Update, UpdateType},
};
use tokio::{fs::File, io::AsyncWriteExt};
struct Handler {
client: Client,
tmpdir: PathBuf,
}
async fn handle_document(client: &Client, tmpdir: &Path, document: Document) {
log::info!(
"Got a document (Name: {:?}, MIME-Type: {:?}, Size: {:?})",
document.file_name,
document.mime_type,
document.file_size
);
let target_path = tmpdir.join(document.file_name.clone().unwrap_or_else(|| String::from("unknown")));
let file = client.execute(GetFile::new(document.file_id.as_str())).await.unwrap();
let source_path = file.file_path.unwrap();
log::info!("Downloading a document from {source_path:?}");
let mut stream = client.download_file(source_path).await.unwrap();
let mut file = File::create(target_path.clone()).await.unwrap();
while let Some(chunk) = stream.next().await {
let chunk = chunk.unwrap();
file.write_all(&chunk).await.unwrap();
}
log::info!("The document saved to {target_path:?}");
}
impl UpdateHandler for Handler {
async fn handle(&self, update: Update) {
log::info!("Got an update: {update:?}");
if let UpdateType::Message(message) = update.update_type
&& let MessageData::Document(document) = message.data
{
handle_document(&self.client, &self.tmpdir, document.data).await;
}
}
}
#[tokio::main]
async fn main() {
dotenv().ok();
env_logger::init();
let token = env::var("TGBOT_TOKEN").expect("TGBOT_TOKEN is not set");
let client = Client::new(token).expect("Failed to create API");
let tmpdir = tempdir().expect("Failed to create temporary directory");
LongPoll::new(
client.clone(),
Handler {
client,
tmpdir: tmpdir.path().to_path_buf(),
},
)
.run()
.await;
}