Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
19 changes: 11 additions & 8 deletions .env.example
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
# twitch app data
TWITCH_CLIENTID=
TWITCH_CLIENTSECRET=
# telegram bot token
TELEGRAM_TOKEN=
# ids, separated by command
TELEGRAM_BOT_ADMINS=
DATABASE_URL=postgres://test:test@localhost:54326/test?sslmode=
# Secrets (use wrangler secret put)
APP_ENV = "development"
BASE_URL = "http://localhost:8787"
TELEGRAM_TOKEN = ""
TWITCH_CLIENT_ID = ""
TWITCH_CLIENT_SECRET = ""
TELEGRAM_BOT_ADMINS = "comma-separated user IDs"
TWITCH_EVENTSUB_SECRET = "for webhook verification"

# BOT INFO FOR SKIP /me REQUEST ON EACH REQUEST
BOT_INFO = """{"id": 1234567890,"is_bot": true,"first_name": "mybot","username": "MyBot","can_join_groups": true,"can_read_all_group_messages": false,"supports_inline_queries": true,"can_connect_to_business": false}"""
35 changes: 0 additions & 35 deletions .github/workflows/docker.yml

This file was deleted.

30 changes: 0 additions & 30 deletions .github/workflows/migrations_lint.yml

This file was deleted.

16 changes: 0 additions & 16 deletions .github/workflows/pr_title_lint.yml

This file was deleted.

38 changes: 0 additions & 38 deletions .github/workflows/tests.yml

This file was deleted.

3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,6 @@ ent/**/*
!ent/generate.go
.vscode
.DS_Store
wrangler.toml
node_modules
.wrangler
183 changes: 152 additions & 31 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,66 +1,187 @@
# Twitch Notifier
# Twitch Notifier Bot

![GitHub go.mod Go version](https://img.shields.io/github/go-mod/go-version/satont/twitch-notifier)
[![Coverage Status](https://coveralls.io/repos/github/Satont/twitch-notifier/badge.svg)](https://coveralls.io/github/Satont/twitch-notifier)
Telegram бот для уведомлений о стримах Twitch с использованием Cloudflare Workers, D1 и KV.

Bot for sending twitch streams notifications in telegram.
## Архитектура

# Development
### Serverless-Agnostic Design
Проект построен с учетом возможности запуска в разных окружениях:
- **Cloudflare Workers** (основная платформа)
- **Docker** (для локальной разработки)
- Другие serverless платформы (AWS Lambda, Vercel, etc.)

Download dependencies

```bash
go mod download
### Repository Pattern
```
src/db/
├── connection.ts # IDatabaseConnection интерфейс
├── repository.factory.ts # Factory для создания репозиториев
├── repositories/
│ ├── interfaces/ # Интерфейсы репозиториев
│ ├── drizzle/ # Реализации для Drizzle ORM (D1, PostgreSQL)
│ └── cloudflare-kv/ # Реализации для Cloudflare KV
```

### Requirements
### Технологический стек
- **Runtime**: Cloudflare Workers (Node.js compatible)
- **Database**: Cloudflare D1 (SQLite)
- **Cache/Sessions**: Cloudflare KV
- **ORM**: Drizzle ORM
- **Bot Framework**: Grammy
- **HTTP Framework**: Hono
- **Twitch API**: Twurple

- Golang `1.19+`
## Команды бота

### Generate
### Пользовательские команды:
- `/start`, `/help`, `/info`, `/settings` - Меню настроек
- `/follow <username>` - Подписаться на канал Twitch
- `/follows`, `/unfollow` - Управление подписками
- `/live` - Показать онлайн стримы

After clone/on first setup/on schema change - you should run
### Админские команды:
- `/broadcast <message>` - Рассылка всем пользователям
- `/change_channel_id <old> <new>` - Обновить Twitch ID канала

## Установка и деплой

### 1. Установка зависимостей
```bash
make generate
bun install
```

### Testing
### 2. Создание Cloudflare D1 базы данных
```bash
wrangler d1 create twitch-notifier-db
```

Скопируйте `database_id` из вывода команды и вставьте в `wrangler.toml`:
```toml
[[d1_databases]]
binding = "DB"
database_name = "twitch-notifier-db"
database_id = "YOUR_DATABASE_ID_HERE"
```

### 3. Создание Cloudflare KV namespace для сессий
```bash
make tests
wrangler kv:namespace create SESSIONS_KV
```

### Running
Скопируйте `id` из вывода команды и вставьте в `wrangler.toml`:
```toml
[[kv_namespaces]]
binding = "SESSIONS_KV"
id = "YOUR_KV_ID_HERE"
```

### 4. Применение миграций
```bash
docker compose -f docker-compose.dev.yml up -d
make dev
wrangler d1 execute twitch-notifier-db --file=./drizzle/0000_init.sql
```

## Database schemas and migrations
### 5. Настройка переменных окружения

### Writing schemas
**Через Cloudflare Dashboard** или с помощью `wrangler secret put`:

All schemas located in `./ent/schema` directory, but also we are using internal structures. Internal structures located in `internal/db/db_models`. So you should change both of them.
```bash
wrangler secret put TELEGRAM_TOKEN
wrangler secret put BASE_URL # URL вашего воркера, например: https://twitch-notifier.yourname.workers.dev
```

Остальные переменные можно задать в `wrangler.toml`:
```toml
[vars]
TWITCH_CLIENT_ID = "your_client_id"
TWITCH_CLIENT_SECRET = "your_client_secret"
TELEGRAM_BOT_ADMINS = "123456789,987654321" # Telegram user IDs через запятую
TWITCH_EVENTSUB_SECRET = "your_eventsub_secret"
```

After changing any schema in `/ent/schema` folder, you should regenerate data via `make generate`
### 6. Деплой
```bash
bun run deploy
```

### Migrations
### 7. Настройка Telegram webhook
После деплоя настройте webhook для бота:
```bash
curl -X POST "https://api.telegram.org/bot<YOUR_BOT_TOKEN>/setWebhook" \
-H "Content-Type: application/json" \
-d '{"url":"https://your-worker.workers.dev/telegram-webhook"}'
```

#### Requirements
### 8. Настройка Twitch EventSub
Webhook для Twitch EventSub настроится автоматически при подписке на каналы через команду `/follow`.

- [atlasgo cli](https://atlasgo.io/getting-started#installation)
- Docker
URL для EventSub: `https://your-worker.workers.dev/twitch-webhook`

### Create
## Разработка

### Локальный запуск
```bash
make migrate-create somecoolname
bun run dev
```

### Apply
### Генерация миграций
```bash
bun drizzle-kit generate
```

### Применение миграций локально
```bash
bun drizzle-kit migrate
```

### Проверка типов
```bash
make migrate-apply
bun run typecheck
```

## Структура проекта

```
src/
├── bot/
│ ├── commands/ # Команды через Composer
│ ├── helpers.ts # Вспомогательные функции
│ ├── storage.ts # Storage adapter для Grammy
│ └── types.ts # Типы контекста
├── db/
│ ├── connection.ts # Абстракция подключения к БД
│ ├── schema.ts # Drizzle схема
│ ├── repository.factory.ts
│ └── repositories/
│ ├── interfaces/ # Интерфейсы репозиториев
│ ├── drizzle/ # Реализации для D1
│ └── cloudflare-kv/ # Реализации для KV
├── domain/
│ ├── models.ts # Доменные модели
│ └── mapper.ts # Маппер DB → Domain
├── services/ # Сервисы (Twitch, Telegram, etc.)
├── webhooks/ # Обработчики webhook'ов
└── index.ts # Hono приложение
```

## Особенности реализации

### Персистентные сессии через Cloudflare KV
Сессии Grammy хранятся в Cloudflare KV с автоматическим TTL. Это решает проблему сброса сессий в serverless окружении. KV обеспечивает:
- Низкую латентность (читается с ближайшего edge)
- Автоматическое истечение ключей
- Глобальное распределение

### EventSub вместо polling
Используются Twitch EventSub webhooks для получения событий в реальном времени:
- `stream.online` - стример начал трансляцию
- `stream.offline` - стример закончил трансляцию
- `channel.update` - изменились название или категория

### Domain-Driven Design
Разделение между DB schema и domain models для чистой архитектуры.

### Factory Pattern
Единая точка создания репозиториев для простой замены реализаций.

## Лицензия

MIT
Loading
Loading