mirror of
https://github.com/simplex-chat/simplex-chat.git
synced 2026-06-07 13:12:51 +00:00
simplex-chat-python: add BotCommand.params field (#7034)
This commit is contained in:
@@ -33,8 +33,38 @@ from .types import T
|
||||
|
||||
@dataclass(slots=True)
|
||||
class BotCommand:
|
||||
"""One entry in the bot's advertised slash-command list (wire-side
|
||||
`groupPreferences.commands` or profile `preferences.commands`).
|
||||
|
||||
`keyword` and `label` are required: `keyword` is what the user
|
||||
types after `/`; `label` is the human-readable description shown
|
||||
next to the keyword in the SimpleX client's commands menu.
|
||||
|
||||
`params` is an optional placeholder string that controls how the
|
||||
client behaves when the user taps the command in the menu:
|
||||
|
||||
* `params=None` (default) — the client SENDS `/<keyword>`
|
||||
immediately on tap; no input-box detour. Use this for
|
||||
zero-argument commands (`/help`, `/ping`) where the action is
|
||||
unambiguous.
|
||||
|
||||
* `params="<value>"` — the client PASTES `/<keyword> <params>`
|
||||
into the input box and positions the cursor at the end. The
|
||||
user edits the placeholder and sends. Use this for commands
|
||||
that take a required argument (`/review <pr-url>`,
|
||||
`/order <number>`) so the user sees the expected shape
|
||||
without having to remember it.
|
||||
|
||||
Mirrors `CBCCommand` in the Haskell core
|
||||
(`Simplex.Chat.Types.Preferences`) and the wire TypedDict
|
||||
`ChatBotCommand_command`. Both SimpleX clients (Android/Kotlin
|
||||
and iOS/Swift) implement the paste-vs-send branch on the
|
||||
`params` field; see `CommandsMenuView.{kt,swift}` for the
|
||||
reference UI behaviour.
|
||||
"""
|
||||
keyword: str
|
||||
label: str
|
||||
params: str | None = None
|
||||
|
||||
|
||||
class Bot(Client):
|
||||
@@ -145,10 +175,24 @@ class Bot(Client):
|
||||
"files": {"allow": "yes" if self._allow_files else "no"},
|
||||
}
|
||||
if self._commands:
|
||||
prefs["commands"] = [
|
||||
{"type": "command", "keyword": c.keyword, "label": c.label}
|
||||
for c in self._commands
|
||||
]
|
||||
cmds: list[T.ChatBotCommand] = []
|
||||
for c in self._commands:
|
||||
entry: T.ChatBotCommand_command = {
|
||||
"type": "command",
|
||||
"keyword": c.keyword,
|
||||
"label": c.label,
|
||||
}
|
||||
# `params` is `NotRequired[str]` on the wire; omit the
|
||||
# key entirely when None so the Haskell parser sees
|
||||
# `Nothing` rather than `Just ""`. The two have
|
||||
# different client semantics: `Nothing` (`params=None`)
|
||||
# triggers an immediate send on tap; `Just ""` would
|
||||
# paste `/<keyword> ` (with a trailing space) into the
|
||||
# input box, which is rarely what the operator wants.
|
||||
if c.params is not None:
|
||||
entry["params"] = c.params
|
||||
cmds.append(entry)
|
||||
prefs["commands"] = cmds
|
||||
p["preferences"] = prefs
|
||||
p["peerType"] = "bot"
|
||||
return p
|
||||
|
||||
Reference in New Issue
Block a user