feat(telegram,game): single bot + per-user variant preferences
CI / changes (pull_request) Successful in 2s
CI / unit (pull_request) Successful in 10s
CI / integration (pull_request) Successful in 13s
CI / ui (pull_request) Successful in 54s
CI / gate (pull_request) Successful in 0s
CI / deploy (pull_request) Successful in 57s
CI / changes (pull_request) Successful in 2s
CI / unit (pull_request) Successful in 10s
CI / integration (pull_request) Successful in 13s
CI / ui (pull_request) Successful in 54s
CI / gate (pull_request) Successful in 0s
CI / deploy (pull_request) Successful in 57s
Collapse the two per-language Telegram bots into one unified bot and
replace language-based variant gating with explicit per-user variant
preferences.
- Telegram: one bot; drop service_language and the supported_languages
set everywhere (DB, account, auth, FlatBuffers Session wire, gateway,
connector proto). The single bot renders chat and out-of-app push in
the recipient's preferred_language; remove the game-language push
routing override (notify Intent.Language / push Event.language).
- Preferences: new accounts.variant_preferences (text[], DB default
{erudit_ru}, CHECK non-empty + subset of the three variants). Gates
the New Game picker, vs-AI and the friend invitation the player
creates, enforced server-side (HTTP 400 otherwise); an invited friend
may still accept any variant. Edited on the Settings screen; variants
are Erudit-first everywhere.
- Admin: drop the per-bot language selectors (broadcast / send-to-user)
and the feedback channel_lang column/field.
- Env/CI: collapse TELEGRAM_BOT_TOKEN_{EN,RU}, TELEGRAM_GAME_CHANNEL_ID_{EN,RU},
VITE_TELEGRAM_LINK{,_EN,_RU} and VITE_TELEGRAM_GAME_CHANNEL_NAME_{EN,RU}
to single unsuffixed names; drop GATEWAY_DEFAULT_SUPPORTED_LANGUAGES.
- Docs updated (ARCHITECTURE, FUNCTIONAL + _ru, platform/telegram, gateway,
backend, ui, UI_DESIGN, PRERELEASE).
The migration squash is deferred to a follow-up PR.
This commit is contained in:
@@ -13,38 +13,17 @@ import (
|
||||
// created before the table that references it, and no two tables/vectors are
|
||||
// under construction at once.
|
||||
|
||||
// buildSupportedLanguagesVector creates the Session.supported_languages [string]
|
||||
// vector from langs. FlatBuffers is built bottom-up, so the caller must invoke this
|
||||
// (which itself creates the element strings) before SessionStart and with no table
|
||||
// under construction.
|
||||
func buildSupportedLanguagesVector(b *flatbuffers.Builder, langs []string) flatbuffers.UOffsetT {
|
||||
offsets := make([]flatbuffers.UOffsetT, len(langs))
|
||||
for i, lang := range langs {
|
||||
offsets[i] = b.CreateString(lang)
|
||||
}
|
||||
fb.SessionStartSupportedLanguagesVector(b, len(langs))
|
||||
for i := len(offsets) - 1; i >= 0; i-- {
|
||||
b.PrependUOffsetT(offsets[i])
|
||||
}
|
||||
return b.EndVector(len(langs))
|
||||
}
|
||||
|
||||
// encodeSession builds a Session payload. supportedLangs is the service's set of
|
||||
// offered game languages, which the UI gates the New Game variant choice by.
|
||||
func encodeSession(s backendclient.SessionResp, supportedLangs []string) []byte {
|
||||
// encodeSession builds a Session payload.
|
||||
func encodeSession(s backendclient.SessionResp) []byte {
|
||||
b := flatbuffers.NewBuilder(128)
|
||||
token := b.CreateString(s.Token)
|
||||
uid := b.CreateString(s.UserID)
|
||||
name := b.CreateString(s.DisplayName)
|
||||
svcLang := b.CreateString(s.ServiceLanguage)
|
||||
langs := buildSupportedLanguagesVector(b, supportedLangs)
|
||||
fb.SessionStart(b)
|
||||
fb.SessionAddToken(b, token)
|
||||
fb.SessionAddUserId(b, uid)
|
||||
fb.SessionAddIsGuest(b, s.IsGuest)
|
||||
fb.SessionAddDisplayName(b, name)
|
||||
fb.SessionAddSupportedLanguages(b, langs)
|
||||
fb.SessionAddServiceLanguage(b, svcLang)
|
||||
b.Finish(fb.SessionEnd(b))
|
||||
return b.FinishedBytes()
|
||||
}
|
||||
@@ -74,6 +53,7 @@ func encodeProfile(p backendclient.ProfileResp) []byte {
|
||||
if p.Banner != nil {
|
||||
banner = encodeBanner(b, *p.Banner)
|
||||
}
|
||||
prefs := buildStringVector(b, p.VariantPreferences, fb.ProfileStartVariantPreferencesVector)
|
||||
fb.ProfileStart(b)
|
||||
fb.ProfileAddUserId(b, uid)
|
||||
fb.ProfileAddDisplayName(b, name)
|
||||
@@ -86,6 +66,7 @@ func encodeProfile(p backendclient.ProfileResp) []byte {
|
||||
fb.ProfileAddAwayStart(b, awayStart)
|
||||
fb.ProfileAddAwayEnd(b, awayEnd)
|
||||
fb.ProfileAddNotificationsInAppOnly(b, p.NotificationsInAppOnly)
|
||||
fb.ProfileAddVariantPreferences(b, prefs)
|
||||
if p.Banner != nil {
|
||||
fb.ProfileAddBanner(b, banner)
|
||||
}
|
||||
@@ -147,10 +128,8 @@ func encodeBlockStatus(s backendclient.BlockStatusResp) []byte {
|
||||
|
||||
// encodeLinkResult builds a LinkResult payload. A switched-session token
|
||||
// (a guest initiator whose durable counterpart won) is carried as a nested Session
|
||||
// for the client to adopt; it is omitted otherwise. supportedLangs is the variant
|
||||
// gating set for that switched session — the link flows run on the web, so it is the
|
||||
// gateway's default (non-platform) set.
|
||||
func encodeLinkResult(r backendclient.LinkResultResp, supportedLangs []string) []byte {
|
||||
// for the client to adopt; it is omitted otherwise.
|
||||
func encodeLinkResult(r backendclient.LinkResultResp) []byte {
|
||||
b := flatbuffers.NewBuilder(256)
|
||||
status := b.CreateString(r.Status)
|
||||
secID := b.CreateString(r.SecondaryUserID)
|
||||
@@ -161,13 +140,11 @@ func encodeLinkResult(r backendclient.LinkResultResp, supportedLangs []string) [
|
||||
token := b.CreateString(r.Token)
|
||||
uid := b.CreateString(r.Profile.UserID)
|
||||
name := b.CreateString(r.Profile.DisplayName)
|
||||
langs := buildSupportedLanguagesVector(b, supportedLangs)
|
||||
fb.SessionStart(b)
|
||||
fb.SessionAddToken(b, token)
|
||||
fb.SessionAddUserId(b, uid)
|
||||
fb.SessionAddIsGuest(b, r.Profile.IsGuest)
|
||||
fb.SessionAddDisplayName(b, name)
|
||||
fb.SessionAddSupportedLanguages(b, langs)
|
||||
sess = fb.SessionEnd(b)
|
||||
}
|
||||
fb.LinkResultStart(b)
|
||||
|
||||
Reference in New Issue
Block a user