feat(telegram): bot support relay — per-user forum topics
CI / changes (pull_request) Successful in 2s
CI / unit (pull_request) Successful in 12s
CI / integration (pull_request) Successful in 16s
CI / ui (pull_request) Successful in 56s
CI / gate (pull_request) Successful in 0s
CI / deploy (pull_request) Successful in 1m20s
CI / changes (pull_request) Successful in 2s
CI / unit (pull_request) Successful in 12s
CI / integration (pull_request) Successful in 16s
CI / ui (pull_request) Successful in 56s
CI / gate (pull_request) Successful in 0s
CI / deploy (pull_request) Successful in 1m20s
Users who DM the bot anything but /start are relayed into a private forum supergroup, one topic per user. Operators (the chat's admins) reply in the topic and the bot copies it back to the user; an info card opening each topic carries a Block/Unblock toggle and a Clear button. State is a small JSON file on a new /data volume — the bot host has no database. Off by default (TELEGRAM_SUPPORT_CHAT_ID=0): the prod bot is unchanged until the operator sets the chat id and adds the bot as a forum admin. - internal/support: concurrency-safe JSON store (topic map, block list, relayed message ids) with field-targeted mutators and atomic save - bot/support.go: relay both ways via copyMessage, short-TTL admin cache, callback buttons, per-user topic-create lock, loop guard (skip the bot's own posts), reopen a deleted topic on the next message - config + compose + CI/prod-deploy: TELEGRAM_SUPPORT_CHAT_ID per contour + TELEGRAM_SUPPORT_STATE_DIR; bot-state named volume; /data pre-owned by UID 65532 so a fresh volume is writable under distroless - docs: ARCHITECTURE §15 + decision record, FUNCTIONAL (+ru), README
This commit is contained in:
@@ -1200,3 +1200,25 @@ blocks **only** feedback submission (unlike a suspension, the whole-account bloc
|
||||
granted from the feedback section (the delete-with-block checkbox) and granted/revoked from the
|
||||
`/users` console card. Roles are validated against a known set in Go, so adding one needs no
|
||||
migration.
|
||||
|
||||
**Telegram support relay.** Separate from the in-app Feedback above, the bot offers a direct
|
||||
support channel for users who message it on Telegram. Any message other than `/start` is relayed
|
||||
into a private **forum supergroup** (`TELEGRAM_SUPPORT_CHAT_ID`): a user's first message opens a
|
||||
dedicated **forum topic** whose first message is an info card (name, @username, language, premium,
|
||||
id, profile deep-link) carrying a Block/Unblock toggle and a Clear button; every message is then
|
||||
copied into that topic (`copyMessage`, so any content — text, media, voice, files — carries over).
|
||||
Any **administrator** of the support chat who writes in a user's topic has their message copied
|
||||
back to that user; non-admins and the bot's own posts are ignored (the loop guard). Block drops the
|
||||
user's incoming messages (the topic stays); Clear deletes the relayed messages, keeping the info
|
||||
card; a topic the operators delete is reopened on the next message. State (user→topic map, block
|
||||
list, relayed message ids) is a small JSON file on a writable volume — the bot host has no database
|
||||
and cannot reach Postgres. The relay is **bot-local**: it touches neither the backend, the gateway,
|
||||
nor `feedback_messages`. The bot must be an administrator in the forum group with the manage-topics
|
||||
and delete-messages rights.
|
||||
|
||||
> **Decision (2026-06-23) — bot-local support relay over forum topics.** The direct Telegram
|
||||
> support channel lives entirely in the bot (no backend, no bot-link command), because the bot host
|
||||
> has no database. One forum **topic per user** (not a reply-to-header thread) gives native per-user
|
||||
> separation and survives message deletion; the topic id, not a fragile header message, anchors the
|
||||
> mapping. Operators are the support chat's administrators (no separate owner id); messages relay
|
||||
> both ways with `copyMessage`. State persists as JSON on a dedicated volume.
|
||||
|
||||
Reference in New Issue
Block a user