use ferogram::filters::{Dispatcher, command, data};
use ferogram::tl;
use ferogram::{Client, InputMessage};
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 inline_keyboard.rs");
std::process::exit(1);
}
let (client, _shutdown) = Client::quick_connect("keyboard.session", API_ID, API_HASH).await?;
let me = client.get_me().await?;
println!(
"Bot running as @{}",
me.username.as_deref().unwrap_or("unknown")
);
let mut dp = Dispatcher::new();
dp.on_message(command("start"), |msg| async move {
let keyboard = kb(vec![
vec![bc("đ Hello", "cb:hello"), bc("âšī¸ About", "cb:about")],
vec![bc("đĻ What is ferogram?", "cb:ferogram")],
vec![bu("GitHub", "https://github.com/ankit-chaubey/ferogram")],
]);
msg.reply(InputMessage::html("Welcome! Pick an option below:").reply_markup(keyboard))
.await
.ok();
});
{
let client = client.clone();
dp.on_callback_query(data("cb:hello"), move |cb| {
let client = client.clone();
async move {
cb.answer().text("Hello there!").send(&client).await.ok();
}
});
}
{
let client = client.clone();
dp.on_callback_query(data("cb:about"), move |cb| {
let client = client.clone();
async move {
cb.answer()
.alert("Built with ferogram: pure Rust MTProto.")
.send(&client)
.await
.ok();
}
});
}
{
let client = client.clone();
dp.on_callback_query(data("cb:ferogram"), move |cb| {
let client = client.clone();
async move {
cb.answer()
.alert("An async Rust MTProto client built from scratch.")
.send(&client)
.await
.ok();
}
});
}
{
let client = client.clone();
dp.on_callback_query(
!(data("cb:hello") | data("cb:about") | data("cb:ferogram")),
move |cb| {
let client = client.clone();
async move {
cb.answer().text("Unknown button.").send(&client).await.ok();
}
},
);
}
let mut stream = client.stream_updates();
while let Some(upd) = stream.next().await {
dp.dispatch(upd).await;
}
Ok(())
}
fn kb(rows: Vec<Vec<tl::enums::KeyboardButton>>) -> tl::enums::ReplyMarkup {
tl::enums::ReplyMarkup::ReplyInlineMarkup(tl::types::ReplyInlineMarkup {
rows: rows
.into_iter()
.map(|row| {
tl::enums::KeyboardButtonRow::KeyboardButtonRow(tl::types::KeyboardButtonRow {
buttons: row,
})
})
.collect(),
})
}
fn bc(text: &str, data: &str) -> tl::enums::KeyboardButton {
tl::enums::KeyboardButton::Callback(tl::types::KeyboardButtonCallback {
requires_password: false,
style: None,
text: text.to_string(),
data: data.as_bytes().to_vec(),
})
}
fn bu(text: &str, url: &str) -> tl::enums::KeyboardButton {
tl::enums::KeyboardButton::Url(tl::types::KeyboardButtonUrl {
style: None,
text: text.to_string(),
url: url.to_string(),
})
}