diff --git a/.gitignore b/.gitignore index f808674..8172dbf 100644 --- a/.gitignore +++ b/.gitignore @@ -6,5 +6,4 @@ hosts coverage.out .envrc /my_token -/vk -/telegram \ No newline at end of file +/bot \ No newline at end of file diff --git a/Dockerfile b/Dockerfile index 8530ab9..0b5aef4 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,17 +1,11 @@ -ARG VERSION - FROM golang:1.20.4-alpine3.18 -ARG VERSION -ENV VERSION=$VERSION COPY . /go/src/go-mtg-vk WORKDIR /go/src/go-mtg-vk -RUN go build ./cmd/$VERSION +RUN go build ./cmd/bot FROM alpine:3.18 RUN mkdir /app WORKDIR /app -ARG VERSION -ENV VERSION=$VERSION -COPY --from=0 /go/src/go-mtg-vk/$VERSION . +COPY --from=0 /go/src/go-mtg-vk/bot . ENV GIN_MODE=release -ENTRYPOINT ./$VERSION \ No newline at end of file +ENTRYPOINT ./bot \ No newline at end of file diff --git a/cmd/bot/main.go b/cmd/bot/main.go new file mode 100644 index 0000000..6be8986 --- /dev/null +++ b/cmd/bot/main.go @@ -0,0 +1,136 @@ +package main + +import ( + "context" + "fmt" + "log" + "math/rand" + "os" + "strconv" + "time" + + "gitlab.com/flygrounder/go-mtg-vk/internal/caching" + "gitlab.com/flygrounder/go-mtg-vk/internal/cardsinfo" + "gitlab.com/flygrounder/go-mtg-vk/internal/scenario" + "gitlab.com/flygrounder/go-mtg-vk/internal/telegram" + + "github.com/gin-gonic/gin" + tgbotapi "github.com/go-telegram-bot-api/telegram-bot-api" + environ "github.com/ydb-platform/ydb-go-sdk-auth-environ" + "github.com/ydb-platform/ydb-go-sdk/v3" + "gitlab.com/flygrounder/go-mtg-vk/internal/vk" +) + +type config struct { + tgToken string + vkGroupId int64 + vkSecretKey string + vkToken string + vkConfirmationString string + ydbConnectionString string +} + +func getConfig() *config { + var cfg config + var exists bool + var err error + + cfg.tgToken, exists = os.LookupEnv("TG_TOKEN") + if !exists { + panic("TG_TOKEN environment variable not defined") + } + + vkGroupId, exists := os.LookupEnv("VK_GROUP_ID") + if !exists { + panic("VK_GROUP_ID environment variable not defined") + } + cfg.vkGroupId, err = strconv.ParseInt(vkGroupId, 10, 64) + if err != nil { + panic("VK_GROUP_ID is not a number") + } + + cfg.vkSecretKey, exists = os.LookupEnv("VK_SECRET_KEY") + if !exists { + panic("VK_SECRET_KEY environment variable not defined") + } + + cfg.vkToken, exists = os.LookupEnv("VK_TOKEN") + if !exists { + panic("VK_TOKEN environment variable not defined") + } + + cfg.vkConfirmationString, exists = os.LookupEnv("VK_CONFIRMATION_STRING") + if !exists { + panic("VK_CONFIRMATION_STRING environment variable not defined") + } + + cfg.ydbConnectionString, exists = os.LookupEnv("YDB_CONNECTION_STRING") + if !exists { + panic("YDB_CONNECTION_STRING environment variable not defined") + } + + return &cfg +} + +func main() { + rand.Seed(time.Now().UTC().UnixNano()) + + cfg := getConfig() + + bot, _ := tgbotapi.NewBotAPI(cfg.tgToken) + r := gin.Default() + + ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) + defer cancel() + + db, err := ydb.Open(ctx, + cfg.ydbConnectionString, + environ.WithEnvironCredentials(ctx), + ) + if err != nil { + panic(fmt.Errorf("connect error: %w", err)) + } + defer func() { _ = db.Close(ctx) }() + + cache := &caching.CacheClient{ + Storage: db.Table(), + Expiration: 12 * time.Hour, + Prefix: db.Name(), + } + err = cache.Init(context.Background()) + if err != nil { + panic(fmt.Errorf("init error: %w", err)) + } + + logger := log.New(os.Stdout, "", 0) + fetcher := &cardsinfo.Fetcher{} + handler := vk.Handler{ + Scenario: &scenario.Scenario{ + Sender: &vk.ApiSender{ + Token: cfg.vkToken, + Logger: logger, + }, + Logger: logger, + InfoFetcher: fetcher, + Cache: cache, + }, + SecretKey: cfg.vkSecretKey, + GroupId: cfg.vkGroupId, + ConfirmationString: cfg.vkConfirmationString, + } + + tgHandler := telegram.Handler{ + Scenario: &scenario.Scenario{ + Sender: &telegram.Sender{ + API: bot, + }, + Logger: logger, + InfoFetcher: fetcher, + Cache: cache, + }, + } + + r.POST("vk", handler.HandleMessage) + r.POST("tg", tgHandler.HandleMessage) + _ = r.Run(":8000") +} diff --git a/cmd/telegram/main.go b/cmd/telegram/main.go deleted file mode 100644 index 8c11aa7..0000000 --- a/cmd/telegram/main.go +++ /dev/null @@ -1,81 +0,0 @@ -package main - -import ( - "context" - "fmt" - "log" - "os" - "time" - - tgbotapi "github.com/go-telegram-bot-api/telegram-bot-api" - environ "github.com/ydb-platform/ydb-go-sdk-auth-environ" - "github.com/ydb-platform/ydb-go-sdk/v3" - "gitlab.com/flygrounder/go-mtg-vk/internal/caching" - "gitlab.com/flygrounder/go-mtg-vk/internal/cardsinfo" - "gitlab.com/flygrounder/go-mtg-vk/internal/scenario" - "gitlab.com/flygrounder/go-mtg-vk/internal/telegram" -) - -const welcomeMessage = "Здравствуйте, вас приветствует бот для поиска цен на карты MTG, введите название карты, которая вас интересует." - -func main() { - token, exists := os.LookupEnv("TG_TOKEN") - if !exists { - panic("TG_TOKEN environment variable not defined") - } - bot, _ := tgbotapi.NewBotAPI(token) - - ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) - defer cancel() - - dsn, exists := os.LookupEnv("YDB_CONNECTION_STRING") - if !exists { - panic("YDB_CONNECTION_STRING environment variable not defined") - } - - db, err := ydb.Open(ctx, - dsn, - environ.WithEnvironCredentials(ctx), - ) - if err != nil { - panic(fmt.Errorf("connect error: %w", err)) - } - defer func() { _ = db.Close(ctx) }() - - sender := &telegram.Sender{ - API: bot, - } - cache := &caching.CacheClient{ - Storage: db.Table(), - Expiration: 12 * time.Hour, - Prefix: db.Name(), - } - err = cache.Init(context.Background()) - if err != nil { - panic(fmt.Errorf("init error: %w", err)) - } - sc := &scenario.Scenario{ - Sender: sender, - Logger: log.New(os.Stdout, "", 0), - Cache: cache, - InfoFetcher: &cardsinfo.Fetcher{}, - } - - u := tgbotapi.NewUpdate(0) - updates, _ := bot.GetUpdatesChan(u) - for update := range updates { - if update.Message == nil { - continue - } - - if update.Message.Text == "/start" { - sender.Send(update.Message.Chat.ID, welcomeMessage) - continue - } - - go sc.HandleSearch(context.Background(), &scenario.UserMessage{ - Body: update.Message.Text, - UserId: update.Message.Chat.ID, - }) - } -} diff --git a/cmd/vk/main.go b/cmd/vk/main.go deleted file mode 100644 index eedf0ef..0000000 --- a/cmd/vk/main.go +++ /dev/null @@ -1,73 +0,0 @@ -package main - -import ( - "context" - "fmt" - "log" - "math/rand" - "os" - "strconv" - "time" - - "gitlab.com/flygrounder/go-mtg-vk/internal/caching" - "gitlab.com/flygrounder/go-mtg-vk/internal/cardsinfo" - "gitlab.com/flygrounder/go-mtg-vk/internal/scenario" - - "github.com/gin-gonic/gin" - environ "github.com/ydb-platform/ydb-go-sdk-auth-environ" - "github.com/ydb-platform/ydb-go-sdk/v3" - "gitlab.com/flygrounder/go-mtg-vk/internal/vk" -) - -func main() { - rand.Seed(time.Now().UTC().UnixNano()) - - r := gin.Default() - - ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) - defer cancel() - - dsn, exists := os.LookupEnv("YDB_CONNECTION_STRING") - if !exists { - panic("YDB_CONNECTION_STRING environment variable not defined") - } - - db, err := ydb.Open(ctx, - dsn, - environ.WithEnvironCredentials(ctx), - ) - if err != nil { - panic(fmt.Errorf("connect error: %w", err)) - } - defer func() { _ = db.Close(ctx) }() - - cache := &caching.CacheClient{ - Storage: db.Table(), - Expiration: 12 * time.Hour, - Prefix: db.Name(), - } - err = cache.Init(context.Background()) - if err != nil { - panic(fmt.Errorf("init error: %w", err)) - } - - groupId, _ := strconv.ParseInt(os.Getenv("VK_GROUP_ID"), 10, 64) - logger := log.New(os.Stdout, "", 0) - handler := vk.Handler{ - Scenario: &scenario.Scenario{ - Sender: &vk.ApiSender{ - Token: os.Getenv("VK_TOKEN"), - Logger: logger, - }, - Logger: logger, - InfoFetcher: &cardsinfo.Fetcher{}, - Cache: cache, - }, - SecretKey: os.Getenv("VK_SECRET_KEY"), - GroupId: groupId, - ConfirmationString: os.Getenv("VK_CONFIRMATION_STRING"), - } - - r.POST("callback/message", handler.HandleMessage) - _ = r.Run(":8000") -} diff --git a/docker-compose.yaml b/docker-compose.yaml index 5eea809..05c34a9 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -1,10 +1,7 @@ version: "3.3" services: - vk: - build: - context: . - args: - - VERSION=vk + bot: + build: . environment: - YDB_CONNECTION_STRING - YDB_ACCESS_TOKEN_CREDENTIALS @@ -12,17 +9,8 @@ services: - VK_SECRET_KEY - VK_GROUP_ID - VK_CONFIRMATION_STRING + - TG_TOKEN ports: - "127.0.0.1:8888:8000" - restart: "always" - telegram: - build: - context: . - args: - - VERSION=telegram - environment: - - YDB_CONNECTION_STRING - - YDB_ACCESS_TOKEN_CREDENTIALS - - TG_TOKEN - restart: "always" \ No newline at end of file + restart: "unless-stopped" \ No newline at end of file diff --git a/internal/telegram/handler.go b/internal/telegram/handler.go new file mode 100644 index 0000000..e89312f --- /dev/null +++ b/internal/telegram/handler.go @@ -0,0 +1,33 @@ +package telegram + +import ( + "context" + + "github.com/gin-gonic/gin" + tgbotapi "github.com/go-telegram-bot-api/telegram-bot-api" + "gitlab.com/flygrounder/go-mtg-vk/internal/scenario" +) + +const welcomeMessage = "Здравствуйте, вас приветствует бот для поиска цен на карты MTG, введите название карты, которая вас интересует." + +type Handler struct { + Scenario *scenario.Scenario +} + +func (h *Handler) HandleMessage(c *gin.Context) { + var upd tgbotapi.Update + err := c.Bind(&upd) + if err != nil || upd.Message == nil { + return + } + + if upd.Message.Text == "/start" { + h.Scenario.Sender.Send(upd.Message.Chat.ID, welcomeMessage) + return + } + + h.Scenario.HandleSearch(context.Background(), &scenario.UserMessage{ + Body: upd.Message.Text, + UserId: upd.Message.Chat.ID, + }) +}