Initial commit
Build & Push / build (push) Canceled after 0s

This commit is contained in:
2026-08-05 19:31:35 +03:00
commit a33fa24e99
272 changed files with 40566 additions and 0 deletions
+152
View File
@@ -0,0 +1,152 @@
package main
import (
"os"
"regexp"
"strings"
"time"
"github.com/NicoNex/echotron/v3"
"github.com/TelegramExchange/tgex-backend/tg_bot/backend"
"github.com/TelegramExchange/tgex-backend/tg_bot/bot"
"github.com/TelegramExchange/tgex-backend/tg_bot/screens"
"github.com/rs/zerolog"
"github.com/rs/zerolog/log"
)
var botCommands = []echotron.BotCommand{
{Command: "start", Description: "Главное меню"},
{Command: "projects", Description: "Мои проекты"},
{Command: "placements", Description: "Размещения"},
{Command: "platform", Description: "Веб-платформа"},
{Command: "help", Description: "Помощь"},
}
func main() {
initLogger()
botToken := mustEnv("TELEGRAM__TOKEN")
backendClient := backend.New(backend.Config{
BaseURL: mustEnv("BACKEND__BASE_URL"),
LoginURL: mustEnv("LOGIN_URL"),
})
// Регистрируем команды бота в Telegram
api := echotron.NewAPI(botToken)
if me, err := api.GetMe(); err != nil {
log.Error().Err(err).Msg("Failed to get bot profile")
} else if me.Result != nil {
bot.SetUsername(me.Result.Username)
log.Info().Str("username", me.Result.Username).Msg("Telegram bot authorized")
}
if _, err := api.SetMyCommands(nil, botCommands...); err != nil {
log.Error().Err(err).Msg("Failed to set bot commands")
} else {
log.Info().Msg("Bot commands registered successfully")
}
var commandRouter = func(command string) bot.State {
createCreativeRe := regexp.MustCompile(`^/start project_(.+)_createcreative$`)
switch {
case command == "/start":
return &screens.MainMenu{}
case command == "/start login":
return &screens.Login{}
case command == "/projects":
return &screens.MyProjects{BackState: &screens.MainMenu{}}
case command == "/placements":
return &screens.MyProjects{BackState: &screens.MainMenu{}, OpenPlacements: true}
case command == "/platform":
return &screens.PlatformLink{}
case command == "/help":
return &screens.Help{}
case createCreativeRe.MatchString(command):
projectID := createCreativeRe.FindStringSubmatch(command)[1]
return &screens.AddCreativeStart{Ctx: &screens.AddCreativeCtx{
ProjectID: projectID,
BackState: &screens.MainMenu{},
}}
}
panic("Unknown command: " + command)
}
var handleGlobalCallback = func(callbackData string) bot.State {
id, ok := strings.CutPrefix(callbackData, "pending_channel:")
if ok {
return &screens.SelectWorkspace{ChannelID: id, BackState: &screens.MainMenu{}}
}
id, ok = strings.CutPrefix(callbackData, "workspace_invite_accept:")
if ok {
return &screens.AcceptWorkspaceInvite{InviteID: id}
}
return nil
}
newBot := func(chatID int64) echotron.Bot {
return bot.NewBot(chatID, botToken, commandRouter, backendClient, handleGlobalCallback)
}
dsp := echotron.NewDispatcher(botToken, newBot)
updateOpts := echotron.UpdateOptions{
AllowedUpdates: []echotron.UpdateType{
echotron.MessageUpdate,
echotron.CallbackQueryUpdate,
echotron.MyChatMemberUpdate,
echotron.ChatMemberUpdate,
echotron.UpdateType("chat_join_request"),
},
}
echotron.SetChatRequestLimit(0, 0)
for {
err := dsp.PollOptions(false, updateOpts)
if err != nil {
log.Error().Err(err).Msg("dsp.Poll failed, retrying in 5 seconds...")
time.Sleep(5 * time.Second)
continue
}
break
}
}
func initLogger() {
zerolog.TimeFieldFormat = time.RFC3339
level := zerolog.InfoLevel
if parsedLevel, err := zerolog.ParseLevel(os.Getenv("LOGGER__LEVEL")); err == nil {
level = parsedLevel
}
zerolog.SetGlobalLevel(level)
log.Logger = zerolog.New(os.Stdout).With().Timestamp().Logger().Level(level)
prettyConsole := os.Getenv("LOGGER__PRETTY_CONSOLE")
if prettyConsole == "" {
prettyConsole = "true"
}
if prettyConsole == "true" {
log.Logger = zerolog.New(zerolog.ConsoleWriter{Out: os.Stdout, TimeFormat: "15:04:05"}).
With().
Timestamp().
Logger().
Level(level)
}
log.Info().Msg("Logger initialized")
}
func mustEnv(key string) string {
v := os.Getenv(key)
if v == "" {
log.Fatal().Str("env", key).Msg("missing required environment variable")
}
return v
}