Stage 15: dual Telegram bots & language-gated variants
Tests · Go / test (push) Successful in 9s
Tests · Integration / integration (push) Successful in 10s
Tests · UI / test (push) Successful in 20s
Tests · Go / test (pull_request) Successful in 8s
Tests · Integration / integration (pull_request) Successful in 11s
Tests · UI / test (pull_request) Successful in 19s
Tests · Go / test (push) Successful in 9s
Tests · Integration / integration (push) Successful in 10s
Tests · UI / test (push) Successful in 20s
Tests · Go / test (pull_request) Successful in 8s
Tests · Integration / integration (pull_request) Successful in 11s
Tests · UI / test (pull_request) Successful in 19s
Service-agnostic refinement of the owner's idea: the sign-in service returns a set of supported game languages with the user identity, and the lobby gates the New Game variant choice by it (en -> English; ru -> Russian + Эрудит). - Connector hosts two bots in one container (one per service language, each its own token + game channel; the same telegram_id spans both). ValidateInitData tries each token and returns the validating bot's service_language + supported_languages. Per-language config (TELEGRAM_BOT_TOKEN_EN/_RU, channels). - supported_languages rides the Session (fbs, session-scoped, not persisted); the UI offers only the matching variants on New Game — gating only the START of a new game (auto-match + friend invite), not accept/open/play; backend does not enforce. - service_language persisted (accounts.service_language, migration 00010, written every login, last-login-wins) and routes the user-facing Notify push back through the right bot (push-target coalesces with preferred_language). - Admin SendToUser/SendToGameChannel gain an operator-chosen language selector in the console (unrelated to ValidateInitData). - Non-Telegram logins carry the gateway default set (GATEWAY_DEFAULT_SUPPORTED_LANGUAGES, all variants). Wire (committed regen): ValidateInitDataResponse +service_language +supported_languages; Session +supported_languages; SendToUser/SendToGameChannel +language. Docs (ARCHITECTURE/FUNCTIONAL/_ru/READMEs) + PLAN updated; stage marked done.
This commit is contained in:
@@ -22,13 +22,15 @@ const (
|
||||
|
||||
// registerStage11 adds the linking & merge operations. The telegram ops need the
|
||||
// connector's Login Widget validator, so they are registered only when tg is set.
|
||||
func registerStage11(r *Registry, backend *backendclient.Client, tg TelegramValidator) {
|
||||
// supportedLangs is the variant gating set for a switched link session (the link
|
||||
// flows run on the web, so the gateway default set).
|
||||
func registerStage11(r *Registry, backend *backendclient.Client, tg TelegramValidator, supportedLangs []string) {
|
||||
r.ops[MsgLinkEmailRequest] = Op{Handler: linkEmailRequestHandler(backend), Auth: true, Email: true}
|
||||
r.ops[MsgLinkEmailConfirm] = Op{Handler: linkEmailConfirmHandler(backend), Auth: true, Email: true}
|
||||
r.ops[MsgLinkEmailMerge] = Op{Handler: linkEmailMergeHandler(backend), Auth: true, Email: true}
|
||||
r.ops[MsgLinkEmailConfirm] = Op{Handler: linkEmailConfirmHandler(backend, supportedLangs), Auth: true, Email: true}
|
||||
r.ops[MsgLinkEmailMerge] = Op{Handler: linkEmailMergeHandler(backend, supportedLangs), Auth: true, Email: true}
|
||||
if tg != nil {
|
||||
r.ops[MsgLinkTelegram] = Op{Handler: linkTelegramHandler(backend, tg, false), Auth: true}
|
||||
r.ops[MsgLinkTelegramMerge] = Op{Handler: linkTelegramHandler(backend, tg, true), Auth: true}
|
||||
r.ops[MsgLinkTelegram] = Op{Handler: linkTelegramHandler(backend, tg, false, supportedLangs), Auth: true}
|
||||
r.ops[MsgLinkTelegramMerge] = Op{Handler: linkTelegramHandler(backend, tg, true, supportedLangs), Auth: true}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -42,31 +44,31 @@ func linkEmailRequestHandler(backend *backendclient.Client) Handler {
|
||||
}
|
||||
}
|
||||
|
||||
func linkEmailConfirmHandler(backend *backendclient.Client) Handler {
|
||||
func linkEmailConfirmHandler(backend *backendclient.Client, supportedLangs []string) Handler {
|
||||
return func(ctx context.Context, req Request) ([]byte, error) {
|
||||
in := fb.GetRootAsLinkEmailConfirm(req.Payload, 0)
|
||||
res, err := backend.LinkEmailConfirm(ctx, req.UserID, string(in.Email()), string(in.Code()))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return encodeLinkResult(res), nil
|
||||
return encodeLinkResult(res, supportedLangs), nil
|
||||
}
|
||||
}
|
||||
|
||||
func linkEmailMergeHandler(backend *backendclient.Client) Handler {
|
||||
func linkEmailMergeHandler(backend *backendclient.Client, supportedLangs []string) Handler {
|
||||
return func(ctx context.Context, req Request) ([]byte, error) {
|
||||
in := fb.GetRootAsLinkEmailConfirm(req.Payload, 0)
|
||||
res, err := backend.LinkEmailMerge(ctx, req.UserID, string(in.Email()), string(in.Code()))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return encodeLinkResult(res), nil
|
||||
return encodeLinkResult(res, supportedLangs), nil
|
||||
}
|
||||
}
|
||||
|
||||
// linkTelegramHandler validates Login Widget data via the connector and then calls
|
||||
// the backend's link or merge endpoint with the trusted Telegram external id.
|
||||
func linkTelegramHandler(backend *backendclient.Client, tg TelegramValidator, merge bool) Handler {
|
||||
func linkTelegramHandler(backend *backendclient.Client, tg TelegramValidator, merge bool, supportedLangs []string) Handler {
|
||||
return func(ctx context.Context, req Request) ([]byte, error) {
|
||||
in := fb.GetRootAsLinkTelegramRequest(req.Payload, 0)
|
||||
user, err := tg.ValidateLoginWidget(ctx, string(in.Data()))
|
||||
@@ -82,6 +84,6 @@ func linkTelegramHandler(backend *backendclient.Client, tg TelegramValidator, me
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return encodeLinkResult(res), nil
|
||||
return encodeLinkResult(res, supportedLangs), nil
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user