use ferogram::{Client, update::Update};
const API_ID: i32 = 0; const API_HASH: &str = "";
#[tokio::main]
async fn main() {
if let Err(e) = run().await {
eprintln!("error: {e}");
std::process::exit(1);
}
}
async fn run() -> Result<(), Box<dyn std::error::Error>> {
if API_ID == 0 || API_HASH.is_empty() {
eprintln!("Fill in API_ID and API_HASH at the top of download_media.rs");
std::process::exit(1);
}
let downloads = std::path::Path::new("downloads");
tokio::fs::create_dir_all(downloads).await?;
let (client, _shutdown) = Client::quick_connect("download.session", API_ID, API_HASH).await?;
let me = client.get_me().await?;
println!(
"Logged in as {} ({})",
me.first_name.as_deref().unwrap_or("?"),
me.id
);
println!("Saving media to ./downloads/ ...");
let mut stream = client.stream_updates();
while let Some(upd) = stream.next().await {
if let Update::NewMessage(msg) = upd {
if msg.outgoing() {
continue;
}
let has_photo = msg.photo().is_some();
let has_doc = msg.document().is_some();
if !has_photo && !has_doc {
continue;
}
let msg_id = msg.id();
let file_name = if has_photo {
format!("photo_{msg_id}.jpg")
} else {
let doc = msg.document().unwrap();
doc.file_name()
.map(|n| n.to_string())
.unwrap_or_else(|| format!("file_{msg_id}"))
};
let dest = downloads.join(&file_name);
let dest_str = dest.to_string_lossy().into_owned();
match msg
.download(&mut tokio::fs::File::create(&dest).await.unwrap())
.await
{
Ok(bytes) => {
println!("Saved: {dest_str} ({} KB)", bytes / 1024);
}
Err(e) => {
println!("Error downloading msg {msg_id}: {e}");
}
}
}
}
Ok(())
}