feat(messages): inline-button support (buttons/click) and live latest#11
Open
zhiyue wants to merge 3 commits into
Open
feat(messages): inline-button support (buttons/click) and live latest#11zhiyue wants to merge 3 commits into
zhiyue wants to merge 3 commits into
Conversation
Add three `messages` subcommands built on grammers' raw API so the CLI can drive bots that reply with inline keyboards (e.g. search bots that deliver a file when you tap a result): - `messages buttons` list a message's inline keyboard (index, kind, callback data / url), read live via `Message::reply_markup()`. - `messages click` press a callback button via `messages.getBotCallbackAnswer`, selecting by `--button <index>` or raw `--data <base64>`; with `--wait`/`--download` it then polls for the bot's follow-up message and downloads its media. `BOT_RESPONSE_TIMEOUT` is treated as delivered (slow bots still act on the press). - `messages latest` fetch the newest messages straight from Telegram, bypassing the local DB (a live view without a prior `sync`). Implementation: new `src/app/buttons.rs` (parses `ReplyInlineMarkup` into a flat, indexable button list, plus click + wait/download helpers); `App::resolve_peer_ref` made `pub(crate)`; README updated. Verified end-to-end against a live search bot: /s <book> -> latest -> buttons -> click bookpreview -> buttons -> click download -> file auto-downloaded (valid EPUB). Claude-Session: https://claude.ai/code/session_016T92jG6xyYALWQfuaUaB82
There was a problem hiding this comment.
Pull request overview
Adds new tgcli messages functionality to support bot inline keyboards (list buttons, click callback buttons, and fetch latest messages directly from Telegram) using grammers raw TL API where needed.
Changes:
- Introduces
messages buttons,messages click, andmessages latestCLI subcommands and wires them into command dispatch/output formatting. - Adds
src/app/buttons.rsimplementing inline keyboard extraction, callback “click” viamessages.getBotCallbackAnswer, optional polling for follow-up messages, and optional media downloading. - Exposes
App::resolve_peer_refaspub(crate)so the new app module can resolve chat peers for raw API calls.
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
| src/cmd/messages.rs | Adds new subcommands and human/JSON output for buttons/click/latest. |
| src/app/send.rs | Makes resolve_peer_ref pub(crate) for cross-module reuse. |
| src/app/mod.rs | Registers the new buttons app module. |
| src/app/buttons.rs | Implements button listing, callback clicking, follow-up polling, and download integration. |
| README.md | Documents the new inline button/bot workflow commands. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
- buttons: show the base64 callback payload (copy-pasteable into `messages click --data`), appending the decoded text when printable, instead of only the decoded text. - click: fetch the origin message up front so `msg_id` is validated even on the --data path, and capture its sender to filter follow-ups. - wait_for_new_messages: keep only messages from the origin sender (so a busy group's other messages aren't mistaken for the bot's reply) and widen the per-poll window from 10 to 50 to avoid missing follow-ups. - de-duplicate the "fetch one message by id" logic into a shared App::fetch_message_by_id, reused by download_media and the button commands. Addresses the automated review comments on dgrr#11. Claude-Session: https://claude.ai/code/session_016T92jG6xyYALWQfuaUaB82
Author
|
Thanks for the review! Pushed c2df11d addressing all five comments:
|
60 chars truncated useful content — e.g. a search bot's results listing where each item's format/size/rating lives past the first line. Show the full message (bounded at 4000 to avoid dumping pathological messages) so callers can read/filter it (pick by TXT/EPUB, etc.). Claude-Session: https://claude.ai/code/session_016T92jG6xyYALWQfuaUaB82
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Adds three
messagessubcommands, built on grammers' raw API, so tgcli can drive bots that reply with inline keyboards (e.g. search bots that send a file when you tap a result):messages buttons --chat <id> --message <id>Message::reply_markup().messages click --chat <id> --message <id> --button <idx>messages.getBotCallbackAnswer. Select by--button <index>or raw--data <base64>. With--wait <secs>/--download [--dest <path>]it polls for the bot's follow-up message and downloads its media.messages latest --chat <id> --limit <n>sync.Why
grammers exposes received buttons through
Message::reply_markup()but has no high-level "click"; the actual press needs the rawmessages.getBotCallbackAnswer. This wires that up so the CLI can complete flows like search bot → pick a result → receive the file that previously required the official app.Notes
BOT_RESPONSE_TIMEOUT. tgcli treats this as delivered and still waits for the follow-up message when--wait/--downloadis set.src/app/buttons.rs; the only change to existing code is makingApp::resolve_peer_refpub(crate)plus the command wiring and README docs.cargo build,cargo build --release, andcargo fmtare all clean.Verification
End-to-end against a live search bot:
/s <book>→messages latest(get the results message id) →messages buttons→messages clickthe preview button →messages buttons→messages clickthe download button with--download→ file auto-downloaded and verified (valid EPUB).https://claude.ai/code/session_016T92jG6xyYALWQfuaUaB82