6aeb529f13
CI / changes (pull_request) Successful in 2s
CI / unit (pull_request) Successful in 10s
CI / integration (pull_request) Successful in 15s
CI / ui (pull_request) Successful in 53s
CI / gate (pull_request) Successful in 1s
CI / deploy (pull_request) Failing after 2m6s
Move all Telegram egress off the main host. The single connector held the bot token, long-polled Telegram and answered the gateway/backend over the trusted internal network, so the whole component (including login validation) shared fate with its VPN sidecar. Split it into two binaries that share the token: - cmd/validator (home, no VPN): Mini App initData + Login Widget HMAC only, never calls the Bot API. The gateway dials it for Telegram auth, so game login is now independent of Telegram reachability. - cmd/bot (remote): Bot API long-poll + sendMessage, the only component reaching Telegram. It holds no inbound port — it dials the gateway over a new reverse mTLS bot-link (pkg/proto/botlink/v1) and executes the send commands the gateway pushes. The gateway funnels sends to the bot-link: out-of-app push is fire-and-forget (at-most-once, dropped if no bot is connected); the backend admin broadcasts reach a gateway-served relay that forwards them and awaits the bot's ack (SendToUser/SendToGameChannel contract preserved). mTLS (pkg/mtls) is the one inter-service link that leaves the trusted segment; validator<->gateway and the relay stay plaintext internal. The bot is Telegram-rate-limited. One bot now; the gateway bot registry, an owns_updates flag and per-command ids leave seams for N later. Webhook rejected (one URL per token, adds inbound + a static address). The unified test contour runs the split (the bot keeps its VPN sidecar and dials the gateway by its internal name; bot-link certs from deploy/gen-certs.sh, generated in CI). The prod wiring — the bot on a separate host (no VPN), the gateway bot-link port published, PROD_ certs with scheduled rotation, an SSH deploy of both hosts together — is the deferred final stage (PRERELEASE.md TX, Stage 18). Docs: ARCHITECTURE, PRERELEASE (phase TX), platform/telegram + gateway + backend + deploy READMEs, FUNCTIONAL(+ru), CLAUDE.md, .env.example.
39 lines
1.1 KiB
Go
39 lines
1.1 KiB
Go
package botlink
|
|
|
|
import (
|
|
botlinkv1 "scrabble/pkg/proto/botlink/v1"
|
|
telegramv1 "scrabble/pkg/proto/telegram/v1"
|
|
)
|
|
|
|
// NotifyCommand builds an out-of-app push command rendered by the bot in the
|
|
// recipient's interface language.
|
|
func NotifyCommand(externalID, kind string, payload []byte, language string) *botlinkv1.Command {
|
|
return &botlinkv1.Command{
|
|
Payload: &botlinkv1.Command_Notify{Notify: &telegramv1.NotifyRequest{
|
|
ExternalId: externalID,
|
|
Kind: kind,
|
|
Payload: payload,
|
|
Language: language,
|
|
}},
|
|
}
|
|
}
|
|
|
|
// SendToUserCommand builds an admin text message addressed to one user.
|
|
func SendToUserCommand(externalID, text string) *botlinkv1.Command {
|
|
return &botlinkv1.Command{
|
|
Payload: &botlinkv1.Command_SendToUser{SendToUser: &telegramv1.SendToUserRequest{
|
|
ExternalId: externalID,
|
|
Text: text,
|
|
}},
|
|
}
|
|
}
|
|
|
|
// SendToGameChannelCommand builds an admin text message for the bot's game channel.
|
|
func SendToGameChannelCommand(text string) *botlinkv1.Command {
|
|
return &botlinkv1.Command{
|
|
Payload: &botlinkv1.Command_SendToChannel{SendToChannel: &telegramv1.SendToGameChannelRequest{
|
|
Text: text,
|
|
}},
|
|
}
|
|
}
|