// Package connector is the backend's gRPC client for the Telegram platform // connector side-service. The admin console uses it to send operator broadcasts: // a direct message to one user, or a post to a game channel. Each broadcast // selects the delivering bot by language (an operator choice, since the connector // hosts one bot per service language). The connector lives on the trusted internal // network, so the connection uses insecure (plaintext) transport credentials // (docs/ARCHITECTURE.md ยง12). It mirrors gateway/internal/connector, narrowed to // the two broadcast methods the admin surface needs. package connector import ( "context" "fmt" "google.golang.org/grpc" "google.golang.org/grpc/credentials/insecure" telegramv1 "scrabble/pkg/proto/telegram/v1" ) // Client wraps the connector's Telegram gRPC service. type Client struct { conn *grpc.ClientConn c telegramv1.TelegramClient } // New dials the connector gRPC endpoint at addr. func New(addr string) (*Client, error) { conn, err := grpc.NewClient(addr, grpc.WithTransportCredentials(insecure.NewCredentials())) if err != nil { return nil, fmt.Errorf("connector: dial %s: %w", addr, err) } return &Client{conn: conn, c: telegramv1.NewTelegramClient(conn)}, nil } // Close releases the gRPC connection. func (c *Client) Close() error { return c.conn.Close() } // SendToUser sends an operator text message to one user, addressed by their // platform external_id, through the bot for the given language. delivered reports // whether the connector actually sent it (false when the user has not started that // bot). func (c *Client) SendToUser(ctx context.Context, externalID, text, language string) (bool, error) { resp, err := c.c.SendToUser(ctx, &telegramv1.SendToUserRequest{ExternalId: externalID, Text: text, Language: language}) if err != nil { return false, err } return resp.GetDelivered(), nil } // SendToGameChannel posts an operator text message to the game channel of the bot // for the given language. delivered reports whether the connector sent it (false // when that bot has no channel configured). func (c *Client) SendToGameChannel(ctx context.Context, text, language string) (bool, error) { resp, err := c.c.SendToGameChannel(ctx, &telegramv1.SendToGameChannelRequest{Text: text, Language: language}) if err != nil { return false, err } return resp.GetDelivered(), nil }