Client Commands: telegram-panel slash commands with Discord-style parameters

Lists the panel account's client commands as Telegram slash commands (hourly
refresh, cached on the device), shows their parameters while typing, runs
complete commands on the panel instead of sending them and shows the answer
as an "Only visible to you" message (latest 20 kept in memory). Holding send
offers Run / Send as message / Send response in chat (red ! badge); an
answer's menu starts with Send in chat. Other plugins register their own
commands through the client_commands library module.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
lyuksovannyyandClaude Opus 5.5 committed 2026-10-09 16:19:20 +02:00
1 parent 84bdc44a76
commit 46a1f6ee1f
29 files changed
+3293 -220

No files matched your search

+16
View File
@@ -112,3 +112,19 @@ The official structured plugin format (Elyx/ElyxBuilder) is a real alternative t
This repo's bundler instead compiles a normal multi-file `src/` project down to the one
`.plugin` file the base engine already knows how to load, so the dev-server write/reload loop
works from the first deploy with no extra on-device engine.
## Gotchas found on exteraGram 12.10.6 (client_commands)
- **Class checks.** `hook_utils.find_class` returns a Chaquopy class wrapper without
`isInstance`. Use `jutil.java_class(name)`, which gives the real `java.lang.Class`.
- **Plugin-made modules.** A module a plugin puts into `sys.modules` doesn't reliably survive
that plugin's reload. State that must outlive a reload (the library registry) hangs off
`builtins` instead.
- **Suggestion list.** `MentionsAdapter.notifyDataSetChanged` diffs rows by their item (the
command string). Rows whose label stays the same aren't rebound, so call
`notifyItemRangeChanged` too. The adapter's `:` emoji search is async and replaces the
rows, so replace the search (skip the method) instead of patching its result.
- **Recycled cells.** A cell restyled by an earlier load of the plugin keeps that style.
Remember the original in the view's tag, not in plugin memory.
- **Ephemeral messages.** A tap opens their menu; a long press does nothing. Deleting one goes
through `MessagesController.deleteEphemeralMessage`, which also asks Telegram to delete it.