CLI contract¶
The CLI uses pydantic-settings nested CLI parsing with CliSubCommand, CliPositionalArg, cli_parse_args, cli_kebab_case, and cli_implicit_flags.
Global flags¶
--database-url <path|sqlite:///path>
--bot-token <token>
--api-base <url>
--output-format short|json|yaml|table
--media-storage-mode skip|file|blob
--media-base-dir <dir>
--poll-timeout-seconds <int>
--poll-limit <int>
--poll-allowed-updates message,edited_message,callback_query,...
Browse commands¶
tg status [--live]
# webhook inspection / mutation
tg webhook show
tg webhook set --url <https-url> [--allowed-updates message,callback_query,...]
tg webhook delete [--drop-pending-updates]
# chats / messages / updates
tg chats list [--search TEXT] [--limit N] [--type private|group|supergroup|channel]
tg chats show <chat-ref>
tg messages list [--chat-ref <chat-ref>] [--search TEXT] [--media-kind KIND] [--limit N]
tg message show <msg-ref>
tg updates list [--limit N] [--kind KIND] [--source webhook|poll|inject] [--status normalized|failed|ignored]
tg updates show <upd-ref>
# callback queries / media / actions
tg callbacks list [--message-ref <msg-ref>] [--answered|--no-answered] [--limit N]
tg callbacks show <cbq-ref>
tg media list [--message-ref <msg-ref>] [--chat-ref <chat-ref>] [--media-kind document|photo|video|...] [--download-status pending|downloaded|failed|skipped] [--limit N]
tg media show <media-ref>
tg actions list [--subject-ref <ref>] [--action-kind KIND] [--limit N]
tg actions show <act-ref>
Ingest commands¶
Semantics:
ingest updatereplays a raw Telegram update into the normalized SQLite store.- If
--bot-tokenis available and media policy is notskip, the ingester attempts to resolve and persist file payloads. - Without a live API client, media rows are still normalized and marked
pending.
Action commands¶
tg send text --chat-ref <chat-ref> --text <text>
tg send photo --chat-ref <chat-ref> --file <path> [--caption TEXT]
tg send document --chat-ref <chat-ref> --file <path> [--caption TEXT]
tg reply <msg-ref> --text <text>
tg react <msg-ref> --emoji <emoji> [--big]
tg ack <cbq-ref> [--text TEXT] [--alert]
tg delete <msg-ref>
tg pin <msg-ref> [--disable-notification]
tg unpin <msg-ref>
Semantics:
- All outbound actions require
--bot-tokenorTGCLI_BOT_TOKEN. - Every action is recorded in
tg_actions, including failures. reply,react,delete,pin, andunpinoperate on local stable refs.
Polling commands¶
tg poll once [--timeout-seconds N] [--limit N] [--allowed-updates CSV] [--source NAME] [--hook-names CSV]
tg poll schedules list
tg poll schedules add --name <name> --interval-seconds <n> [--timeout-seconds N] [--limit N] [--allowed-updates CSV] [--hook-names CSV] [--source NAME] [--disabled]
tg poll schedules run-due
tg poll runs list [--schedule-name NAME] [--limit N]
Semantics:
poll oncecallsgetUpdates, normalizes each returned update, optionally downloads media, records atg_poll_runsrow, and emits named hooks.poll schedules addonly persists scheduling metadata; it does not talk to Telegram and therefore works without a live token.poll schedules run-dueis the primitive scheduler loop: it finds enabled schedules withnext_run_at <= now, executes them, advances offsets, and updatesnext_run_at.- Hooks are registered in code via
HookRegistry. The scaffold ships with anoophook and leaves room for daemon-local service integrations.
Output modes¶
shortis meant for operator use and shell pipelines.json/yamlpreserve the structured contract.tableis best-effort and follows the same normalized data models.