Telegram-бот для управления базой данных сообщений для проекта cozy-world. Работает как Supabase Edge Function на Deno, использует Telegram Bot API через Webhook.
| Функция | Описание |
|---|---|
| 📅 Ежедневные сообщения | Добавить сообщение на конкретную дату. Автоматически предлагает ближайший свободный день. |
| 📂 Категоризированные сообщения | Добавить сообщение в одну из существующих категорий или создать новую. |
| ✏️ Редактирование | Изменить текст, дату, тип или категорию существующего сообщения. |
| 🗑 Удаление | Удалить любое сообщение (ежедневное или категоризированное). |
| 🧹 Очистка устаревших | Экспортировать в чат и удалить все сообщения с прошедшими датами. |
| 🔍 Проверка дат | Показывает, есть ли сообщения на сегодня и завтра, и до какого дня заполнен календарь. |
- Runtime: Deno (Supabase Edge Runtime)
- Backend: Supabase (PostgreSQL + Edge Functions)
- Telegram API: нативные HTTP-запросы (без фреймворков)
- Архитектура: Webhook-based, stateful через таблицу сессий в БД
Подробно всё описано в файле DEPLOY.md.
- Docker Desktop
- Supabase CLI:
npm i -g supabase - Telegram-бот от @BotFather
- ngrok или аналог для публичного туннеля
cd supabase
supabase start
supabase db resetcp functions/telegram-bot/.env.example functions/telegram-bot/.env.localЗаполнить .env.local:
TELEGRAM_BOT_TOKEN=<токен от BotFather>
TELEGRAM_WEBHOOK_SECRET=<любая случайная строка>
SB_URL=http://host.docker.internal:54321
SB_SERVICE_ROLE_KEY=<service_role key из вывода supabase start>
BOT_MESSAGES_TABLE=messages
BOT_SESSIONS_TABLE=telegram_bot_sessions
BOT_TZ_OFFSET_MINUTES=180
BOT_DEFAULT_TYPE=textsupabase functions serve --env-file functions/telegram-bot/.env.localngrok http 54321curl -X POST "https://api.telegram.org/bot<TOKEN>/setWebhook" \
-H "Content-Type: application/json" \
-d '{"url": "https://<ngrok-id>.ngrok.io/functions/v1/telegram-bot", "secret_token": "<WEBHOOK_SECRET>"}'Готово — откройте бота в Telegram и отправьте /start.
Подробное руководство: DEPLOY.md
Краткая последовательность:
supabase login
supabase link --project-ref <project-ref>
supabase db push
supabase secrets set TELEGRAM_BOT_TOKEN="..." SB_URL="https://<ref>.supabase.co" ...
supabase functions deploy telegram-bot --no-verify-jwtsupabase/
├── config.toml # Конфигурация Supabase CLI
├── DEPLOY.md # Руководство по деплою
├── migrations/
│ └── 20260412145237_remote_schema.sql
├── .github/
│ └── workflows/
│ └── deploy.yml
├── functions/
│ └── telegram-bot/
│ ├── index.ts # Точка входа (Webhook handler)
│ ├── .env.example # Шаблон переменных окружения (в репозитории)
│ └── src/
│ ├── bot.ts # Основной роутер бота
│ ├── config.ts # Чтение env-переменных
│ ├── types.ts # TypeScript-типы
│ ├── db/
│ │ ├── client.ts # Инициализация клиента БД
│ │ ├── messages.ts # Репозиторий сообщений
│ │ └── sessions.ts # Репозиторий сессий
│ ├── handlers/
│ │ ├── callbacks.ts # Обработчики inline-кнопок
│ │ ├── commands.ts # Обработчики команд
│ │ ├── context.ts # Контекст запроса
│ │ ├── shared.ts # Общие хелперы
│ │ └── text.ts # Обработчик текстовых сообщений
│ └── lib/
│ ├── date.ts # Утилиты для работы с датами
│ ├── errors.ts # Обработчики ошибок
│ ├── keyboards.ts # Все inline-клавиатуры
│ └── telegram.ts # HTTP-клиент Telegram API
| Поле | Тип | Описание |
|---|---|---|
message_id |
integer PK |
Автоинкремент |
content |
text |
Текст сообщения |
on_day |
date UNIQUE |
Дата (только для ежедневных) |
type |
message_type |
text / video / audio |
category |
text |
Категория (только для категоризированных) |
is_read |
boolean |
Прочитано ли |
created_at |
timestamptz |
Время создания |
| Поле | Тип | Описание |
|---|---|---|
chat_id |
bigint PK |
ID чата в Telegram |
state |
jsonb |
Текущее состояние сессии |
View, поддерживаемый триггером — содержит уникальные категории.
- Все запросы от Telegram проверяются по заголовку
X-Telegram-Bot-Api-Secret-Token - Бот рассчитан на одного пользователя — дополнительная проверка
chat_idопциональна - Edge Function использует
service_roleключ — никогда не передавайте его клиентам
Все переменные описаны в functions/telegram-bot/.env.example.
Для продакшена устанавливаются через supabase secrets set.
MIT