use ferogram::{Client, TransportKind};
const API_ID: i32 = 0; const API_HASH: &str = ""; const PHONE: &str = "";
const PEER: &str = "me";
const QUERY: &str = "hello";
const LIMIT: i32 = 20;
#[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() || PHONE.is_empty() {
eprintln!("Fill in API_ID, API_HASH and PHONE at the top of search_messages.rs");
std::process::exit(1);
}
println!("Connecting...");
let (client, _shutdown) = Client::builder()
.api_id(API_ID)
.api_hash(API_HASH)
.transport(TransportKind::Abridged)
.connect()
.await?;
if !client.is_authorized().await? {
login(&client).await?;
client.save_session().await?;
println!("Session saved.");
}
let me = client.get_me().await?;
let display = me
.first_name
.as_deref()
.unwrap_or(me.username.as_deref().unwrap_or("?"));
println!("Logged in as {display}\n");
println!(
"Searching {:?} in {PEER} (limit {LIMIT}):\n{}",
QUERY,
"-".repeat(60)
);
let results = client
.search(PEER, QUERY)
.limit(LIMIT)
.fetch(&client)
.await?;
if results.is_empty() {
println!("No messages found.");
return Ok(());
}
for msg in &results {
let ts = msg
.date_utc()
.map(|d| d.format("%Y-%m-%d %H:%M:%S").to_string())
.unwrap_or_else(|| format!("unix={}", msg.date()));
let body = msg.text().unwrap_or("").trim();
let snippet = &body[..body.floor_char_boundary(100)];
println!("[msg={:>8}] {ts} {snippet}", msg.id());
}
println!("{}\nFound {} result(s).", "-".repeat(60), results.len());
Ok(())
}
async fn login(client: &Client) -> Result<(), Box<dyn std::error::Error>> {
let name = client.interactive_sign_in(PHONE).await?;
println!("Signed in as {name}");
Ok(())
}