TKBK Studio
TKBK Studio
Вопросы с кнопками, расчёт цены по формуле, телефон клиента — заявка менеджеру, в CSV и CRM
Квиз-воронка прямо в Telegram для ремонта, мебели на заказ, окон, клининга, строительства, обучения и любых услуг с расчётом цены. Клиент отвечает на несколько вопросов кнопками, сразу видит примерную стоимость и оставляет телефон.
Вопросы, варианты и формула расчёта лежат в простом файле quiz.json: формула вроде (type * area + extras) * deadline считается безопасно, без eval. Бот округляет цену и показывает вилку «от … до …» — или скрывает её, если цену должен назвать менеджер.
Заявка с ответами, расчётом и источником трафика приходит менеджеру в Telegram, сохраняется в CSV для Excel и уходит в CRM: Битрикс24 через входящий вебхук, amoCRM через API или любой вебхук (Make, n8n, Albato).
Для кого: Ремонт, мебель на заказ, окна, клининг, строительство, услуги с расчётом цены
Ключи и токены не вводятся на сайте — их кладут в файл .env на своём сервере.
BOT_TOKENТокен бота — @BotFather → /newbotADMIN_CHAT_IDЧат для заявок — Ваш ID у @userinfobot или ID группы (отправьте боту /id в группе)CRM_KINDТип CRM — generic | bitrix24 | amocrmCRM_WEBHOOK_URLАдрес вебхука или CRM — Битрикс24: входящий вебхук; amoCRM: https://аккаунт.amocrm.ruCRM_WEBHOOK_SECRETСекрет вебхука — Для generic: придёт в заголовке X-Webhook-SecretAMOCRM_TOKENДолгосрочный токен amoCRM — amoCRM → Настройки → Интеграции → Ключи и доступы# {{BRAND}} — квиз-бот для заявок в Telegram
Бот задаёт клиенту несколько вопросов, сразу считает примерную стоимость по вашей формуле и просит телефон.
Готовая заявка с ответами приходит менеджеру в Telegram, сохраняется в CSV и (по желанию) уходит в CRM:
Битрикс24, amoCRM или любой вебхук.
## Что умеет
- **Вопросы из `quiz.json`**: кнопки с одним ответом, несколько вариантов (✅), число («54 м²»), свободный текст;
необязательные вопросы с кнопкой «Пропустить», кнопка «Назад», прогресс «Вопрос 2 из 6».
- **Расчёт стоимости по формуле** из `quiz.json`: `(type * area * property + extras) * deadline` — без `eval`,
только арифметика, сравнения, `if/else` и функции min, max, round, abs, ceil, floor.
- **Вилка цены**: округление (до 1000 ₽) и диапазон «от … до …» (±15 %), можно не показывать цену клиенту.
- **Телефон кнопкой** (`request_contact`) или текстом, с проверкой формата.
- **Заявка менеджеру** в личку или группу: имя, ссылка на профиль, телефон, расчёт, все ответы, источник.
- **CSV** `data/leads.csv` (открывается в Excel) — команда `/leads`; статистика — `/stats`.
- **CRM**: свой вебхук (JSON), Битрикс24 (входящий вебхук → лид), amoCRM (API → сделка с контактом и примечанием).
- **Метки источника**: ссылка `https://t.me/ваш_бот?start=instagram` — в заявке будет «Источник: instagram».
## Запуск за 5 минут
### 1. Получите токены
| Что | Где взять |
|---|---|
| `BOT_TOKEN` | [@BotFather](https://t.me/BotFather) → `/newbot` → имя и юзернейм → скопируйте токен |
| `ADMIN_CHAT_ID` | Ваш ID — напишите [@userinfobot](https://t.me/userinfobot). Для группы менеджеров: добавьте бота в группу и отправьте `/id` |
| `CRM_WEBHOOK_URL` | Необязательно, см. раздел «CRM» ниже |
Скопируйте `.env.example` в `.env` и впишите значения.
### 2а. Запуск в Docker
```bash
docker compose up -d --build
docker compose logs -f # смотреть логи
```
### 2б. Запуск без Docker (Python 3.12+)
```bash
python -m venv .venv
# Windows: .venv\Scripts\activate Linux/macOS: source .venv/bin/activate
pip install -r requirements.txt
python -m app
```
## Настройка `quiz.json`
```json
{
"questions": [
{"id": "type", "text": "Какой ремонт?", "type": "choice",
"options": [{"text": "Косметический", "value": 4500}, {"text": "Капитальный", "value": 9000}]},
{"id": "area", "text": "Площадь, м²?", "type": "number", "min": 5, "max": 1000},
{"id": "extras", "text": "Что ещё?", "type": "multi", "optional": true,
"options": [{"text": "Электрика", "value": 60000}]},
{"id": "comment", "text": "Пожелания?", "type": "text", "optional": true}
],
"formula": "type * area + extras",
"result": {"show_price": true, "round_to": 1000, "spread_percent": 15, "currency": "₽",
"text": "Ориентировочно: от {min} до {max} {currency}"}
}
```
- `id` — латиница в нижнем регистре, цифры и `_`; это имя ответа в формуле.
- `type`: `choice` — один вариант (в формулу идёт его `value`), `multi` — несколько (сумма `value`),
`number` — число от клиента, `text` — свободный ответ (в формуле не используется).
- `formula` — например `type * area * 1.2 if area > 100 else type * area`. Ошибки в формуле бот покажет при запуске.
- `result.text` — подставляются `{price}`, `{min}`, `{max}`, `{currency}`. `show_price: false` — не показывать цену.
После правок перезапустите бота. Тексты приветствия и благодарности — в начале `app/config.py`.
## CRM
| `CRM_KIND` | `CRM_WEBHOOK_URL` | Что произойдёт |
|---|---|---|
| `generic` | любой URL (Make, n8n, Albato, свой сервер) | POST JSON (формат ниже), заголовок `X-Webhook-Secret` — если задан `CRM_WEBHOOK_SECRET` |
| `bitrix24` | входящий вебхук `https://портал.bitrix24.ru/rest/1/код/` (Разработчикам → Другое → Входящий вебхук, права «CRM») | метод `crm.lead.add`: лид с именем, телефоном, суммой и ответами в комментарии |
| `amocrm` | `https://аккаунт.amocrm.ru` + `AMOCRM_TOKEN` | `POST /api/v4/leads/complex`: сделка с контактом и телефоном, ответы — примечанием |
Формат `generic`:
```json
{
"event": "lead",
"created_at": "2026-10-10T14:05:00",
"name": "Иван",
"phone": "+79001234567",
"telegram": {"user_id": 123456789, "username": "ivan"},
"source": "instagram",
"price": {"value": 518000, "min": 440000, "max": 596000},
"answers": [{"question": "Какой ремонт планируете?", "answer": "Капитальный"}]
}
```
Если CRM недоступна, бот повторит отправку 3 раза и предупредит менеджера в Telegram; заявка в любом случае
сохраняется в CSV и приходит в чат.
В Битрикс24 с отключёнными лидами (режим «простая CRM») замените в `app/crm.py` метод `crm.lead.add` на `crm.deal.add`.
## Команды
| Команда | Кто | Что делает |
|---|---|---|
| `/start`, `/quiz` | клиенты | начать / пройти заново |
| `/leads` | менеджер | все заявки файлом CSV |
| `/stats` | менеджер | заявки сегодня, за 7 и 30 дней |
| `/id` | все | ID текущего чата |
## Проверка
```bash
pip install -r requirements.txt pytest==9.1.1
pytest
```
Тесты проверяют формулу (и что опасные выражения запрещены), `quiz.json`, ответы, CSV и форматы CRM.
## Структура
```
app/
__main__.py запуск бота
config.py настройки: .env + тексты из мастера
quiz.py загрузка и проверка quiz.json, ответы, расчёт
formula.py безопасная формула и вилка цены (чистая логика)
handlers.py прохождение квиза и приём телефона
leads.py заявка: CSV, статистика, сообщение менеджеру
crm.py вебхук, Битрикс24, amoCRM
admin.py /leads и /stats
keyboards.py кнопки
quiz.json вопросы, формула и текст результата
```
## FAQ
**Заявки не приходят в группу.** Проверьте `ADMIN_CHAT_ID` (для групп он начинается с `-100`) и что бот — участник группы.
**Где лежат заявки?** `data/leads.csv` (в Docker — том `quiz-data`), удобнее всего получать файлом через `/leads`.
**Можно ли не показывать цену?** Да: `"show_price": false` в `quiz.json` — расчёт увидит только менеджер.
**Как узнать, откуда пришёл клиент?** Давайте разные ссылки: `?start=instagram`, `?start=vk`, `?start=site` —
источник попадёт в заявку, CSV и CRM.
Услуги, мастера, свободные окна на 14 дней, напоминания за сутки и за 2 часа, предоплата и отзывы
Оценка 0–10 после заказа: довольных — на Яндекс Карты, 2ГИС и WB, недовольных — сразу к менеджеру
Оплата звёздами или картой, одноразовые ссылки, напоминания о продлении и автоисключение по окончании