Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
cc1bc6b
Создание файла конфигурации
LZTD1 Mar 27, 2025
c067570
add tracing + logger middleware
LZTD1 Mar 28, 2025
c9f8785
add fsm machine
LZTD1 Mar 28, 2025
19a949d
add handler dispatcher + test
LZTD1 Mar 28, 2025
7ac2a76
add start handler + tests
LZTD1 Apr 1, 2025
1f40d37
add /start, settings, set_cookie handler + tests
LZTD1 Apr 1, 2025
031335c
add changeNotification handler
LZTD1 Apr 2, 2025
374f46b
add migrator application
LZTD1 Apr 2, 2025
a918646
add auth mw
LZTD1 Apr 3, 2025
655eca2
realization sqlite base and 2 methods + tests
LZTD1 Apr 3, 2025
88bc6c7
add cookies and notification methods
LZTD1 Apr 3, 2025
d81c5c2
migrate to new telebot router
LZTD1 Apr 3, 2025
bb9a53f
add setCookie method and handler
LZTD1 Apr 4, 2025
9e4f62f
add set notification method + tests
LZTD1 Apr 4, 2025
e154cd3
add my groups handler + tests
LZTD1 Apr 4, 2025
63c2436
add handler myGroups + test
LZTD1 Apr 4, 2025
d55e71a
add rate limiter + tests
LZTD1 Apr 4, 2025
12d2db7
add rate limiter + tests
LZTD1 Apr 4, 2025
0d67d72
add grpc service
LZTD1 Apr 4, 2025
b6cbad8
fix communication with grpc
LZTD1 Apr 4, 2025
938ba81
add generate image method + tests
LZTD1 Apr 7, 2025
cd6e79e
add chat ai method + tests
LZTD1 Apr 7, 2025
9bd0b92
add handler refresh group + service
LZTD1 Apr 7, 2025
56f273d
add tests for handler and service
LZTD1 Apr 8, 2025
7063f46
add refresh groups + tests
LZTD1 Apr 8, 2025
a061f6a
add start with payload
LZTD1 Apr 8, 2025
6ee03b4
add test for viewInformer.go handler
LZTD1 Apr 10, 2025
b1452f2
add service backoffice + tests
LZTD1 Apr 10, 2025
aef4cb6
add backoffice methods + tests
LZTD1 Apr 10, 2025
9f7118d
add backoffice KidView method + tests
LZTD1 Apr 10, 2025
cf00175
add fet with payload in router
LZTD1 Apr 10, 2025
64833f0
change sending refresh groups method
LZTD1 Apr 10, 2025
4a00423
add missing kids handler + test, start writing service
LZTD1 Apr 10, 2025
054033b
add missing kids service + test
LZTD1 Apr 11, 2025
8357c40
add /abs command
LZTD1 Apr 11, 2025
8ff4187
add status changer
LZTD1 Apr 11, 2025
bc126fe
add service get credentials
LZTD1 Apr 14, 2025
1d7f5dd
fix handler test
LZTD1 Apr 14, 2025
b2e0807
add message scheduler
LZTD1 Apr 14, 2025
6bab0e9
change set message logic if empty
LZTD1 Apr 14, 2025
a340548
change set message logic if empty
LZTD1 Apr 14, 2025
0b5a573
Merge remote-tracking branch 'origin/new-architecture' into new-archi…
LZTD1 Apr 14, 2025
6c46b0b
add readme
LZTD1 Apr 14, 2025
a1c7ae7
fix pipeline
LZTD1 Apr 14, 2025
480e9fc
go mod tidy
LZTD1 Apr 14, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 11 additions & 7 deletions .github/workflows/workflow.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,17 +21,21 @@ jobs:
with:
go-version: '1.23.3'

- name: Install rsrc
run: go install github.com/akavel/rsrc@latest

- name: Add icon and build binary
run: |
cd ./cmd
rsrc -ico ./icon.ico
cd ./cmd/algobot
GOOS=windows GOARCH=amd64 go build -o ./algobot.exe

- name: build binary migrator
run: |
cd ./cmd/migrator
GOOS=windows GOARCH=amd64 go build -o ./migrator.exe

- name: Upload Windows binary
uses: actions/upload-artifact@v4
with:
name: algobot
path: ./cmd/algobot.exe
name: binary
path: |
./cmd/migrator/migrator.exe
./cmd/algobot/algobot.exe
./config/dev.yaml
6 changes: 4 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
/base.db
*.db
.env
/.idea
/.idea
config/local.yaml
*_mock.go
21 changes: 21 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,24 @@ gen:
--go-grpc_out=. \
--go-grpc_opt=paths=source_relative \
./protos/*.proto

.PHONY: dev
dev:
go run ./cmd/algobot/main.go -config=./config/local.yaml


.PHONY: mock-gen
mock-gen:
cd test && go generate ./...

.PHONY: grpc-gen
grpc-gen:
protoc --go_out=. \
--go_opt=paths=source_relative \
--go-grpc_out=. \
--go-grpc_opt=paths=source_relative \
./protos/*.proto

.PHONY: migrate
migrate:
go run ./cmd/migrator/main.go -migrations-path=./migrations -storage-path=./storage/storage.db
102 changes: 102 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
# Algobot

## Описание
**Алгобот** — это Telegram-бот, предназначенный для помощи в ведении учительной деятельности Алгоритмика

Репозиторий состоит из двух приложений:
- `algobot` — основной Telegram-бот
- `migrator` — утилита для применения миграций с помощью [Goose](https://github.com/pressly/goose)

Бот использует:
- [gpt4free-grpc-gateway](https://github.com/LZTD1/gpt4free-grpc-gateway) — gRPC-сервер для обращения к нейросетям
- [telebot-context-router](https://github.com/LZTD1/telebot-context-router) — роутер для удобного управления обработчиками сообщений в Telebot

---

## Структура проекта
```
cmd/
├── algobot/ # Точка входа для Telegram-бота
│ └── main.go
├── migrator/ # Миграции SQLite базы через Goose
│ └── main.go

config/ # Конфигурация
migrations/ # SQL миграции
storage/ # SQLite база данных
protos/ # gRPC proto-файлы
```

---

## Конфигурация

Файл `config.yaml`:
```yaml
env: local # или prod
storage_path: "./storage/storage.db" # путь то файла базы данных
# telegram_token можно указать в .env или через переменные окружения TELEGRAM_TOKEN
migrations_path: "./migrations" # путь до папки с миграциями
grpc: # настройки grpc
host: "localhost" # адрес grpc сервера с нейронкой
port: 50051 # порт grpc сервера
timeout: 300s # таймаут ответа
rate_limit: # rate limit для запросов в бота
fill_period: 800ms # период пополнение бакета
bucket_limit: 6 # величина бакета
backoffice: # конфигурация для работы с бэкофисом
message_timer: 5m # период опроса новых сообщений от учеников
retries: 3 # количество ретраев при ошибке от сервера
retries_timeout: 5s # ожидание между ретраями
response_timeout: 15s # ожидание ответа от сервера
```

Можно передать путь до файла конфига через аргумент `--config` или переменную окружения `CONFIG_PATH`.

---

## Запуск

### 1. Сборка
```bash
go build -o migrator ./cmd/migrator
go build -o algobot ./cmd/algobot
```

### 2. Применение миграций
```bash
./migrator -migrations-path=./migrations -storage-path=./storage/storage.db
```

### 3. Запуск бота
```bash
./algobot -config ./config/config.yaml
```


---

## Makefile команды
Для удобства сборки и генерации предусмотрен Makefile:

| Цель | Описание |
|------------------|-----------------------------------------------------------------|
| `make gen` | Генерация Go и gRPC кода из `.proto` файлов (`./protos`) |
| `make grpc-gen` | То же самое, альтернатива `make gen` |
| `make dev` | Запуск бота в dev-режиме с конфигом `./config/local.yaml` |
| `make mock-gen` | Генерация mock'ов в папке `test/` |
| `make migrate` | Запуск миграций через `cmd/migrator` |

Пример:
```bash
make migrate
make dev
```

---

## Переменные окружения
| Название | Описание |
|-------------------|-------------------------------|
| `TELEGRAM_TOKEN` | Токен Telegram-бота |
| `CONFIG_PATH` | Путь к файлу конфигурации |
51 changes: 51 additions & 0 deletions cmd/algobot/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package main

import (
"algobot/internal/app"
"algobot/internal/config"
"algobot/internal/lib/logger/handlers/slogpretty"
"log/slog"
"os"
"os/signal"
"syscall"
)

const (
envProd string = "prod"
envLocal string = "local"
)

func main() {
cfg := config.MustLoad()
log := setupLogger(cfg.Env)
log.Info("starting application")

application := app.New(log, cfg)

go application.TelegramBot.Run()
log.Info("started telegram bot")
go application.Scheduler.Run()
log.Info("starting msg scheduler")

// graceful shutdown
ch := make(chan os.Signal, 1)
signal.Notify(ch, os.Interrupt, os.Kill, syscall.SIGTERM)
<-ch
log.Info("shutting down application")
application.TelegramBot.Stop()
application.Scheduler.Stop()
log.Info("application gracefully stopped")
}

func setupLogger(env string) *slog.Logger {
var log *slog.Logger

switch env {
case envLocal:
log = slog.New(slogpretty.NewHandler(&slog.HandlerOptions{Level: slog.LevelDebug}))
case envProd:
log = slog.New(slog.NewJSONHandler(os.Stdout, &slog.HandlerOptions{Level: slog.LevelInfo}))
}

return log
}
Binary file removed cmd/icon.ico
Binary file not shown.
107 changes: 0 additions & 107 deletions cmd/main.go

This file was deleted.

38 changes: 38 additions & 0 deletions cmd/migrator/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package main

import (
"database/sql"
"flag"
"fmt"
_ "github.com/ncruces/go-sqlite3/driver"
_ "github.com/ncruces/go-sqlite3/embed"
"github.com/pressly/goose/v3"
)

func main() {
var migrationsPath, storagePath string

flag.StringVar(&migrationsPath, "migrations-path", "", "path to migrations folder")
flag.StringVar(&storagePath, "storage-path", "", "path to storage file")
flag.Parse()

if migrationsPath == "" {
panic("migrations-path is required")
}

if storagePath == "" {
panic("storage-path is required")
}

db, err := sql.Open("sqlite3", fmt.Sprintf("file:%s", storagePath))
if err != nil {
panic(err)
}

if err := goose.SetDialect("sqlite3"); err != nil {
panic(err)
}
if err := goose.Up(db, "migrations"); err != nil {
panic(err)
}
}
16 changes: 16 additions & 0 deletions config/dev.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
env: local # or prod
storage_path: "./storage/storage.db"
# telegram_token: TOKEN or set in env variables - TELEGRAM_TOKEN
migrations_path: "./migrations"
grpc:
host: "localhost"
port: 50051
timeout: 300s
rate_limit:
fill_period: 800ms
bucket_limit: 6
backoffice:
message_timer: 5m
retries: 3
retries_timeout: 5s
response_timeout: 15s
Loading