TKBK Studio
TKBK Studio
Запись к мастеру прямо в Telegram: услуги, календарь на 14 дней, напоминание за сутки
Mini App для салонов, барбершопов, студий и частных мастеров. Клиент открывает приложение из бота, выбирает услугу, мастера (или «любого свободного»), день и время — и через пару касаний записан. Никаких сторонних сервисов записи и абонентской платы.
Свободные окна считаются по рабочему графику каждого мастера с перерывами, длительностью услуги и уже занятым временем; двойная запись на одно время исключена. Часовой пояс салона учитывается, даже если сервер стоит в другом.
Администратор получает уведомление о каждой записи и может отменить её кнопкой, командой /today видит расписание на день. Клиенту приходит подтверждение и напоминание за 24 часа. Данные хранятся в SQLite, подпись Telegram проверяется по HMAC-SHA256.
Для кого: Салоны красоты, барбершопы, студии, частные мастера, клиники
Ключи и токены не вводятся на сайте — их кладут в файл .env на своём сервере.
BOT_TOKENТокен бота — Создайте бота у @BotFather → /newbotPUBLIC_URLАдрес приложения (HTTPS) — Домен с HTTPS, где запущен сервер, например https://book.example.ruADMIN_CHAT_IDЧат администратора — Отправьте боту /id в личке или в группе администраторов# {{BRAND}} — онлайн-запись в Telegram
Mini App для записи к мастерам: клиент выбирает услугу, мастера, день и время прямо в Telegram.
Администратор получает уведомление о каждой записи, клиент — подтверждение и напоминание за сутки.
## Что умеет
- Услуги, мастера и их график — в одном файле `catalog/services.json` (перерывы, выходные).
- Календарь на 14 дней (настраивается) и сетка свободного времени.
- Конкретный мастер или «Любой свободный» — сервер сам выберет мастера.
- Двойная запись на одно время невозможна: проверка и запись — в одной транзакции SQLite.
- Подпись данных Telegram (`initData`) проверяется по HMAC-SHA256.
- Клиенту: подтверждение, напоминание за 24 часа, «Мои записи» с отменой.
- Администратору: уведомление с кнопкой «Отменить», команды `/today` и `/tomorrow`.
- Часовой пояс салона (`TIMEZONE`) учитывается, даже если сервер работает по UTC.
## Как устроено
```
catalog/services.json услуги, мастера, график
public/ Mini App: index.html, app.js, styles.css (без сборщика)
src/config.js название, цвет, тексты, часовой пояс, шаг сетки — меняйте здесь
src/slots.js расчёт свободного времени (покрыт тестами)
src/booking.js запись, отмена, уведомления, напоминания
src/db.js SQLite: таблица bookings (файл data/bookings.db)
src/server.js API для Mini App и webhook бота
src/bot.js /start, /id, /today, /tomorrow, отмена кнопкой
```
## Запуск за 5 минут (Docker)
1. Создайте бота: [@BotFather](https://t.me/BotFather) → `/newbot` → скопируйте токен.
2. Нужен адрес с HTTPS (Telegram открывает Mini App только по HTTPS): домен на сервере
или туннель для теста (см. ниже).
3. Скопируйте `.env.example` в `.env`, заполните `BOT_TOKEN`, `PUBLIC_URL`, `ADMIN_CHAT_ID`.
4. Опишите услуги и мастеров в `catalog/services.json`.
5. Запустите:
```bash
docker compose up -d --build
docker compose logs -f
```
6. Отправьте боту `/start` — появится кнопка «Записаться».
При запуске сервер сам регистрирует webhook и кнопку меню бота.
## Запуск без Docker
Нужен Node.js 20.16 или новее (рекомендуем 22 LTS). Пакет `better-sqlite3` ставит готовую
сборку под вашу систему; если её нет, понадобятся Python и компилятор C++.
```bash
npm install
cp .env.example .env # заполните значения
npm start
```
Тесты: `npm test`.
### HTTPS для теста на своём компьютере
```bash
cloudflared tunnel --url http://localhost:3000
```
Адрес `https://…trycloudflare.com` впишите в `PUBLIC_URL` и перезапустите сервер. Для постоянной
работы поставьте перед сервером Caddy (`book.example.ru { reverse_proxy localhost:3000 }`).
## Где взять токены
- **BOT_TOKEN** — @BotFather → `/newbot` (или `/mybots` → бот → API Token).
- **ADMIN_CHAT_ID** — отправьте боту `/id` в личке или в группе администраторов
(бота нужно добавить в группу). Команды `/today`, `/tomorrow` и кнопка отмены работают только в этом чате.
## Подключить Mini App в @BotFather
Кнопку меню «Записаться» сервер ставит сам. Вручную:
- **Кнопка меню:** @BotFather → `/mybots` → бот → Bot Settings → Menu Button → укажите `PUBLIC_URL`.
- **Отдельная ссылка `t.me/имя_бота/book`:** @BotFather → `/newapp` → выберите бота, укажите название,
описание, картинку 640×360 и `PUBLIC_URL`. Ссылку можно ставить в соцсети и на визитки.
## Услуги и график
`catalog/services.json`:
```json
{
"services": [{ "id": "haircut", "title": "Стрижка", "duration": 60, "price": 1800 }],
"masters": [{
"id": "anna", "name": "Анна", "role": "Стилист", "services": ["haircut"],
"schedule": { "mon": "10:00-14:00, 15:00-20:00", "tue": "10:00-20:00", "sun": null }
}]
}
```
- `duration` — длительность услуги в минутах, `price` — цена в рублях (для показа).
- `schedule` — дни `mon` … `sun`; несколько интервалов через запятую (так задаётся перерыв);
`null` или отсутствующий день — выходной.
- Шаг сетки, срок записи вперёд, минимальное время до записи и правила отмены — в `src/config.js`.
## FAQ
**Где хранятся записи?** В SQLite-файле `data/bookings.db` (в Docker — том `booking-data`).
Резервная копия: `docker compose cp booking:/app/data/bookings.db ./backup.db`.
**Клиенту не пришло подтверждение.** Бот может писать только тем, кто нажал `/start`
или разрешил сообщения. Приложение само спрашивает разрешение перед записью, если его нет.
**Время в записях сдвинуто на несколько часов.** Проверьте часовой пояс салона в `src/config.js`
(`timeZone`). Часовой пояс сервера значения не имеет.
**Как добавить мастера или поменять график?** Отредактируйте `catalog/services.json` — приложение
подхватит изменения само, перезапуск не нужен. Уже созданные записи сохранятся. Если в файле ошибка,
она будет в логах, а клиенты увидят «Расписание временно недоступно».
**Можно ли брать предоплату?** Да, это доработка: Telegram Stars или ЮKassa через `createInvoiceLink`
(см. шаблон «Магазин в Telegram Mini App»).
Услуги с ценами, мастера и онлайн-запись
Услуги, мастера, свободные окна на 14 дней, напоминания за сутки и за 2 часа, предоплата и отзывы
Оценка 0–10 после заказа: довольных — на Яндекс Карты, 2ГИС и WB, недовольных — сразу к менеджеру