Files
scrabble-game/pkg/proto/telegram/v1/telegram.pb.go
T
Ilia Denisov cf66ed7e26
Tests · Go / test (push) Successful in 7s
Tests · Integration / integration (push) Successful in 12s
Tests · Go / test (pull_request) Successful in 6s
Tests · Integration / integration (pull_request) Successful in 11s
Tests · UI / test (pull_request) Successful in 19s
Stage 9: Telegram integration (connector side-service, Mini App, out-of-app push)
New platform/telegram connector (own container, bot token only there):
- go-telegram/bot long-poll loop: /start deep-links + Mini App launch button.
- gRPC API pkg/proto/telegram/v1 (Telegram service): ValidateInitData, Notify
  (renders a localized message + deep-link button), SendToUser/SendToGameChannel
  (admin, wired in Stage 10). Generic methods are platform-agnostic (external_id).
- Bot API base override for Telegram's test environment; Dockerfile + compose
  (VPN sidecar, no public ingress); README.

Gateway:
- initData validation relocated from the gateway into the connector; the gateway
  calls ValidateInitData over gRPC (GATEWAY_CONNECTOR_ADDR), drops the bot token,
  and deletes internal/auth.
- Out-of-app push: runPushPump routes events whose recipient has no live in-app
  stream to connector.Notify, gated by /internal/push-target + the in-app-only
  flag (race-free de-dup); HasSubscribers added to the push hub.

Backend:
- Migration 00007 accounts.notifications_in_app_only (default true) + jetgen.
- ProvisionTelegram seeds a new account's language/display name from the launch
  fields; IdentityExternalID reverse lookup; /internal/push-target handler.

UI:
- Telegram Mini App launch: detect initData, apply themeParams, authTelegram,
  route the deep-link start_param (g/i/f); /telegram/ guard redirects outside
  Telegram. Vite relative base + telegram-web-app.js. In-app-only profile toggle;
  share-to-Telegram link for a friend code. Vitest + Playwright coverage.

Wire/docs/CI: fbs Profile/UpdateProfileRequest gain notifications_in_app_only
(Go + TS); go.work uses ./platform/telegram; go-unit.yaml covers it; PLAN,
ARCHITECTURE, FUNCTIONAL (+ru), UI_DESIGN, READMEs updated.
2026-06-04 07:10:21 +02:00

509 lines
17 KiB
Go

// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.36.11
// protoc (unknown)
// source: telegram/v1/telegram.proto
// Package scrabble.telegram.v1 is the RPC contract of the Telegram platform
// side-service (the "connector"). The connector holds the bot token and is the
// only component that talks to the Telegram Bot API; gateway and backend reach it
// over plain gRPC on the trusted internal network (ARCHITECTURE.md §1, §12).
//
// The generic delivery methods (Notify, SendToUser, SendToGameChannel) are
// platform-agnostic: they address a recipient by the identity external_id (as in
// the backend identities table), so a future VK / MAX connector can implement the
// same service. ValidateInitData is the one Telegram-specific method (it parses
// Telegram Web App launch data); it is kept here for now.
package telegramv1
import (
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
reflect "reflect"
sync "sync"
unsafe "unsafe"
)
const (
// Verify that this generated code is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
// Verify that runtime/protoimpl is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
)
// ValidateInitDataRequest carries the raw Telegram Web App initData string.
type ValidateInitDataRequest struct {
state protoimpl.MessageState `protogen:"open.v1"`
InitData string `protobuf:"bytes,1,opt,name=init_data,json=initData,proto3" json:"init_data,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *ValidateInitDataRequest) Reset() {
*x = ValidateInitDataRequest{}
mi := &file_telegram_v1_telegram_proto_msgTypes[0]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *ValidateInitDataRequest) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*ValidateInitDataRequest) ProtoMessage() {}
func (x *ValidateInitDataRequest) ProtoReflect() protoreflect.Message {
mi := &file_telegram_v1_telegram_proto_msgTypes[0]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use ValidateInitDataRequest.ProtoReflect.Descriptor instead.
func (*ValidateInitDataRequest) Descriptor() ([]byte, []int) {
return file_telegram_v1_telegram_proto_rawDescGZIP(), []int{0}
}
func (x *ValidateInitDataRequest) GetInitData() string {
if x != nil {
return x.InitData
}
return ""
}
// ValidateInitDataResponse is the validated identity. external_id is the Telegram
// user id used as the identities external_id; language_code seeds a new account's
// preferred language.
type ValidateInitDataResponse struct {
state protoimpl.MessageState `protogen:"open.v1"`
ExternalId string `protobuf:"bytes,1,opt,name=external_id,json=externalId,proto3" json:"external_id,omitempty"`
Username string `protobuf:"bytes,2,opt,name=username,proto3" json:"username,omitempty"`
FirstName string `protobuf:"bytes,3,opt,name=first_name,json=firstName,proto3" json:"first_name,omitempty"`
LanguageCode string `protobuf:"bytes,4,opt,name=language_code,json=languageCode,proto3" json:"language_code,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *ValidateInitDataResponse) Reset() {
*x = ValidateInitDataResponse{}
mi := &file_telegram_v1_telegram_proto_msgTypes[1]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *ValidateInitDataResponse) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*ValidateInitDataResponse) ProtoMessage() {}
func (x *ValidateInitDataResponse) ProtoReflect() protoreflect.Message {
mi := &file_telegram_v1_telegram_proto_msgTypes[1]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use ValidateInitDataResponse.ProtoReflect.Descriptor instead.
func (*ValidateInitDataResponse) Descriptor() ([]byte, []int) {
return file_telegram_v1_telegram_proto_rawDescGZIP(), []int{1}
}
func (x *ValidateInitDataResponse) GetExternalId() string {
if x != nil {
return x.ExternalId
}
return ""
}
func (x *ValidateInitDataResponse) GetUsername() string {
if x != nil {
return x.Username
}
return ""
}
func (x *ValidateInitDataResponse) GetFirstName() string {
if x != nil {
return x.FirstName
}
return ""
}
func (x *ValidateInitDataResponse) GetLanguageCode() string {
if x != nil {
return x.LanguageCode
}
return ""
}
// NotifyRequest addresses a push event to one recipient. kind is the backend push
// catalog kind (your_turn, nudge, match_found, notify); payload is the FlatBuffers
// scrabblefb.* body for that kind; language (en/ru) selects the message template.
type NotifyRequest struct {
state protoimpl.MessageState `protogen:"open.v1"`
ExternalId string `protobuf:"bytes,1,opt,name=external_id,json=externalId,proto3" json:"external_id,omitempty"`
Kind string `protobuf:"bytes,2,opt,name=kind,proto3" json:"kind,omitempty"`
Payload []byte `protobuf:"bytes,3,opt,name=payload,proto3" json:"payload,omitempty"`
Language string `protobuf:"bytes,4,opt,name=language,proto3" json:"language,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *NotifyRequest) Reset() {
*x = NotifyRequest{}
mi := &file_telegram_v1_telegram_proto_msgTypes[2]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *NotifyRequest) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*NotifyRequest) ProtoMessage() {}
func (x *NotifyRequest) ProtoReflect() protoreflect.Message {
mi := &file_telegram_v1_telegram_proto_msgTypes[2]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use NotifyRequest.ProtoReflect.Descriptor instead.
func (*NotifyRequest) Descriptor() ([]byte, []int) {
return file_telegram_v1_telegram_proto_rawDescGZIP(), []int{2}
}
func (x *NotifyRequest) GetExternalId() string {
if x != nil {
return x.ExternalId
}
return ""
}
func (x *NotifyRequest) GetKind() string {
if x != nil {
return x.Kind
}
return ""
}
func (x *NotifyRequest) GetPayload() []byte {
if x != nil {
return x.Payload
}
return nil
}
func (x *NotifyRequest) GetLanguage() string {
if x != nil {
return x.Language
}
return ""
}
// NotifyResponse reports whether a message was actually sent (false when the kind
// is not rendered out-of-app or the user has not started the bot).
type NotifyResponse struct {
state protoimpl.MessageState `protogen:"open.v1"`
Delivered bool `protobuf:"varint,1,opt,name=delivered,proto3" json:"delivered,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *NotifyResponse) Reset() {
*x = NotifyResponse{}
mi := &file_telegram_v1_telegram_proto_msgTypes[3]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *NotifyResponse) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*NotifyResponse) ProtoMessage() {}
func (x *NotifyResponse) ProtoReflect() protoreflect.Message {
mi := &file_telegram_v1_telegram_proto_msgTypes[3]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use NotifyResponse.ProtoReflect.Descriptor instead.
func (*NotifyResponse) Descriptor() ([]byte, []int) {
return file_telegram_v1_telegram_proto_rawDescGZIP(), []int{3}
}
func (x *NotifyResponse) GetDelivered() bool {
if x != nil {
return x.Delivered
}
return false
}
// SendToUserRequest is an admin text message to one user by external_id.
type SendToUserRequest struct {
state protoimpl.MessageState `protogen:"open.v1"`
ExternalId string `protobuf:"bytes,1,opt,name=external_id,json=externalId,proto3" json:"external_id,omitempty"`
Text string `protobuf:"bytes,2,opt,name=text,proto3" json:"text,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *SendToUserRequest) Reset() {
*x = SendToUserRequest{}
mi := &file_telegram_v1_telegram_proto_msgTypes[4]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *SendToUserRequest) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*SendToUserRequest) ProtoMessage() {}
func (x *SendToUserRequest) ProtoReflect() protoreflect.Message {
mi := &file_telegram_v1_telegram_proto_msgTypes[4]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use SendToUserRequest.ProtoReflect.Descriptor instead.
func (*SendToUserRequest) Descriptor() ([]byte, []int) {
return file_telegram_v1_telegram_proto_rawDescGZIP(), []int{4}
}
func (x *SendToUserRequest) GetExternalId() string {
if x != nil {
return x.ExternalId
}
return ""
}
func (x *SendToUserRequest) GetText() string {
if x != nil {
return x.Text
}
return ""
}
// SendToGameChannelRequest is an admin text message to the configured game channel.
type SendToGameChannelRequest struct {
state protoimpl.MessageState `protogen:"open.v1"`
Text string `protobuf:"bytes,1,opt,name=text,proto3" json:"text,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *SendToGameChannelRequest) Reset() {
*x = SendToGameChannelRequest{}
mi := &file_telegram_v1_telegram_proto_msgTypes[5]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *SendToGameChannelRequest) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*SendToGameChannelRequest) ProtoMessage() {}
func (x *SendToGameChannelRequest) ProtoReflect() protoreflect.Message {
mi := &file_telegram_v1_telegram_proto_msgTypes[5]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use SendToGameChannelRequest.ProtoReflect.Descriptor instead.
func (*SendToGameChannelRequest) Descriptor() ([]byte, []int) {
return file_telegram_v1_telegram_proto_rawDescGZIP(), []int{5}
}
func (x *SendToGameChannelRequest) GetText() string {
if x != nil {
return x.Text
}
return ""
}
// SendResponse reports whether the message was sent.
type SendResponse struct {
state protoimpl.MessageState `protogen:"open.v1"`
Delivered bool `protobuf:"varint,1,opt,name=delivered,proto3" json:"delivered,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *SendResponse) Reset() {
*x = SendResponse{}
mi := &file_telegram_v1_telegram_proto_msgTypes[6]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *SendResponse) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*SendResponse) ProtoMessage() {}
func (x *SendResponse) ProtoReflect() protoreflect.Message {
mi := &file_telegram_v1_telegram_proto_msgTypes[6]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use SendResponse.ProtoReflect.Descriptor instead.
func (*SendResponse) Descriptor() ([]byte, []int) {
return file_telegram_v1_telegram_proto_rawDescGZIP(), []int{6}
}
func (x *SendResponse) GetDelivered() bool {
if x != nil {
return x.Delivered
}
return false
}
var File_telegram_v1_telegram_proto protoreflect.FileDescriptor
const file_telegram_v1_telegram_proto_rawDesc = "" +
"\n" +
"\x1atelegram/v1/telegram.proto\x12\x14scrabble.telegram.v1\"6\n" +
"\x17ValidateInitDataRequest\x12\x1b\n" +
"\tinit_data\x18\x01 \x01(\tR\binitData\"\x9b\x01\n" +
"\x18ValidateInitDataResponse\x12\x1f\n" +
"\vexternal_id\x18\x01 \x01(\tR\n" +
"externalId\x12\x1a\n" +
"\busername\x18\x02 \x01(\tR\busername\x12\x1d\n" +
"\n" +
"first_name\x18\x03 \x01(\tR\tfirstName\x12#\n" +
"\rlanguage_code\x18\x04 \x01(\tR\flanguageCode\"z\n" +
"\rNotifyRequest\x12\x1f\n" +
"\vexternal_id\x18\x01 \x01(\tR\n" +
"externalId\x12\x12\n" +
"\x04kind\x18\x02 \x01(\tR\x04kind\x12\x18\n" +
"\apayload\x18\x03 \x01(\fR\apayload\x12\x1a\n" +
"\blanguage\x18\x04 \x01(\tR\blanguage\".\n" +
"\x0eNotifyResponse\x12\x1c\n" +
"\tdelivered\x18\x01 \x01(\bR\tdelivered\"H\n" +
"\x11SendToUserRequest\x12\x1f\n" +
"\vexternal_id\x18\x01 \x01(\tR\n" +
"externalId\x12\x12\n" +
"\x04text\x18\x02 \x01(\tR\x04text\".\n" +
"\x18SendToGameChannelRequest\x12\x12\n" +
"\x04text\x18\x01 \x01(\tR\x04text\",\n" +
"\fSendResponse\x12\x1c\n" +
"\tdelivered\x18\x01 \x01(\bR\tdelivered2\x96\x03\n" +
"\bTelegram\x12q\n" +
"\x10ValidateInitData\x12-.scrabble.telegram.v1.ValidateInitDataRequest\x1a..scrabble.telegram.v1.ValidateInitDataResponse\x12S\n" +
"\x06Notify\x12#.scrabble.telegram.v1.NotifyRequest\x1a$.scrabble.telegram.v1.NotifyResponse\x12Y\n" +
"\n" +
"SendToUser\x12'.scrabble.telegram.v1.SendToUserRequest\x1a\".scrabble.telegram.v1.SendResponse\x12g\n" +
"\x11SendToGameChannel\x12..scrabble.telegram.v1.SendToGameChannelRequest\x1a\".scrabble.telegram.v1.SendResponseB+Z)scrabble/pkg/proto/telegram/v1;telegramv1b\x06proto3"
var (
file_telegram_v1_telegram_proto_rawDescOnce sync.Once
file_telegram_v1_telegram_proto_rawDescData []byte
)
func file_telegram_v1_telegram_proto_rawDescGZIP() []byte {
file_telegram_v1_telegram_proto_rawDescOnce.Do(func() {
file_telegram_v1_telegram_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_telegram_v1_telegram_proto_rawDesc), len(file_telegram_v1_telegram_proto_rawDesc)))
})
return file_telegram_v1_telegram_proto_rawDescData
}
var file_telegram_v1_telegram_proto_msgTypes = make([]protoimpl.MessageInfo, 7)
var file_telegram_v1_telegram_proto_goTypes = []any{
(*ValidateInitDataRequest)(nil), // 0: scrabble.telegram.v1.ValidateInitDataRequest
(*ValidateInitDataResponse)(nil), // 1: scrabble.telegram.v1.ValidateInitDataResponse
(*NotifyRequest)(nil), // 2: scrabble.telegram.v1.NotifyRequest
(*NotifyResponse)(nil), // 3: scrabble.telegram.v1.NotifyResponse
(*SendToUserRequest)(nil), // 4: scrabble.telegram.v1.SendToUserRequest
(*SendToGameChannelRequest)(nil), // 5: scrabble.telegram.v1.SendToGameChannelRequest
(*SendResponse)(nil), // 6: scrabble.telegram.v1.SendResponse
}
var file_telegram_v1_telegram_proto_depIdxs = []int32{
0, // 0: scrabble.telegram.v1.Telegram.ValidateInitData:input_type -> scrabble.telegram.v1.ValidateInitDataRequest
2, // 1: scrabble.telegram.v1.Telegram.Notify:input_type -> scrabble.telegram.v1.NotifyRequest
4, // 2: scrabble.telegram.v1.Telegram.SendToUser:input_type -> scrabble.telegram.v1.SendToUserRequest
5, // 3: scrabble.telegram.v1.Telegram.SendToGameChannel:input_type -> scrabble.telegram.v1.SendToGameChannelRequest
1, // 4: scrabble.telegram.v1.Telegram.ValidateInitData:output_type -> scrabble.telegram.v1.ValidateInitDataResponse
3, // 5: scrabble.telegram.v1.Telegram.Notify:output_type -> scrabble.telegram.v1.NotifyResponse
6, // 6: scrabble.telegram.v1.Telegram.SendToUser:output_type -> scrabble.telegram.v1.SendResponse
6, // 7: scrabble.telegram.v1.Telegram.SendToGameChannel:output_type -> scrabble.telegram.v1.SendResponse
4, // [4:8] is the sub-list for method output_type
0, // [0:4] is the sub-list for method input_type
0, // [0:0] is the sub-list for extension type_name
0, // [0:0] is the sub-list for extension extendee
0, // [0:0] is the sub-list for field type_name
}
func init() { file_telegram_v1_telegram_proto_init() }
func file_telegram_v1_telegram_proto_init() {
if File_telegram_v1_telegram_proto != nil {
return
}
type x struct{}
out := protoimpl.TypeBuilder{
File: protoimpl.DescBuilder{
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: unsafe.Slice(unsafe.StringData(file_telegram_v1_telegram_proto_rawDesc), len(file_telegram_v1_telegram_proto_rawDesc)),
NumEnums: 0,
NumMessages: 7,
NumExtensions: 0,
NumServices: 1,
},
GoTypes: file_telegram_v1_telegram_proto_goTypes,
DependencyIndexes: file_telegram_v1_telegram_proto_depIdxs,
MessageInfos: file_telegram_v1_telegram_proto_msgTypes,
}.Build()
File_telegram_v1_telegram_proto = out.File
file_telegram_v1_telegram_proto_goTypes = nil
file_telegram_v1_telegram_proto_depIdxs = nil
}