.env.example: понятная инструкция по активации + защита config от пустых значений
- .env.example переписан как пошаговый гид: разделы (подключение к сообществу, кому приходят заявки, почта, ссылки, /favi-stop), пометки «ОБЯЗАТЕЛЬНО», правила заполнения (без инлайн-комментариев, числа не оставлять пустыми). - config: безопасный разбор чисел (_int_env) — пустое/кривое VK_GROUP_ID/порт/часы больше не роняют бот при старте, откатываются на дефолт. '#' в значениях (URL #prices) не трогаем. pytest 43 passed. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
+71
-27
@@ -1,42 +1,72 @@
|
||||
# VK API Configuration
|
||||
# Токен сообщества ВКонтакте (с правами на управление сообщениями)
|
||||
# ============================================================================
|
||||
# НАСТРОЙКА БОТА «Кибершкола БАЗА» — файл .env
|
||||
# ============================================================================
|
||||
# Это ШАБЛОН. Что делать:
|
||||
# 1) Скопируйте этот файл рядом и назовите ровно .env (без .example).
|
||||
# Проще: запустите start_bot.bat — он сам создаст .env и откроет его в
|
||||
# Блокноте. Заполните, сохраните, запустите start_bot.bat снова.
|
||||
# 2) Заполните строки из раздела 1 и 2 (помечены «ОБЯЗАТЕЛЬНО»). Остальное —
|
||||
# по желанию.
|
||||
#
|
||||
# ПРАВИЛА ЗАПОЛНЕНИЯ (важно!):
|
||||
# • Формат строки: ПЕРЕМЕННАЯ=значение — без пробелов вокруг «=», без кавычек.
|
||||
# • НЕ пишите комментарии в одной строке со значением. Комментарий — только
|
||||
# на отдельной строке, начинается с #.
|
||||
# • Числовые поля (ID, порт) не оставляйте пустыми — впишите число.
|
||||
# ============================================================================
|
||||
|
||||
|
||||
# ───────────────── 1. ПОДКЛЮЧЕНИЕ К СООБЩЕСТВУ (ОБЯЗАТЕЛЬНО) ──────────────
|
||||
# VK_TOKEN — ключ доступа ВАШЕГО сообщества:
|
||||
# Сообщество → Управление → Работа с API → Ключи доступа → Создать ключ
|
||||
# (право «Сообщения сообщества») → скопировать сюда.
|
||||
# Там же: Работа с API → Long Poll API → включить, версия — последняя.
|
||||
VK_TOKEN=your_vk_community_token_here
|
||||
|
||||
# Идентификатор (ID) сообщества ВКонтакте (только цифры)
|
||||
# VK_GROUP_ID — числовой ID сообщества (только цифры). Замените 0 на свой ID.
|
||||
# Узнать ID: Управление → Работа с API (виден там), либо через vk.com.
|
||||
VK_GROUP_ID=0
|
||||
|
||||
# ID оператора / администратора ВКонтакте для отправки лидов и оповещений (только цифры)
|
||||
OPERATOR_PEER_ID=12345678
|
||||
|
||||
# Список ID администраторов (через запятую) для управления услугами через чат
|
||||
ADMIN_IDS=12345678
|
||||
# ───────────────── 2. КОМУ ПРИХОДЯТ ЗАЯВКИ (ОБЯЗАТЕЛЬНО) ──────────────────
|
||||
# OPERATOR_PEER_ID — VK ID человека, которому падают заявки/запросы клиентов.
|
||||
# Узнать свой ID можно, написав боту @idbot во ВКонтакте.
|
||||
OPERATOR_PEER_ID=0
|
||||
|
||||
# Разрешённый источник (Origin) для CORS веб-формы (домен сайта). Для локальной отладки можно '*'
|
||||
ALLOWED_ORIGIN=https://infocyber.pro
|
||||
# ADMIN_IDS — у кого есть «Админка» в боте (через запятую, только цифры).
|
||||
# Обычно тот же ID, что OPERATOR_PEER_ID. Пример: 350793273,12345678
|
||||
ADMIN_IDS=0
|
||||
|
||||
# Промокоды на скидку. Пока выключены. Поставь true, когда захочешь их выдавать клиентам.
|
||||
PROMO_ENABLED=false
|
||||
# (Необязательно) Несколько операторов — заявки уйдут ВСЕМ. Через запятую.
|
||||
# OPERATOR_PEER_IDS=350793273,12345678
|
||||
|
||||
# ===== Email (SMTP) для уведомлений о заявках =====
|
||||
# Адрес SMTP-сервера почты (например, smtp.yandex.ru / smtp.gmail.com / smtp.mail.ru)
|
||||
# (Необязательно) Часы работы — вне их клиенту пишем «ответим утром».
|
||||
WORK_HOUR_START=9
|
||||
WORK_HOUR_END=21
|
||||
|
||||
|
||||
# ───────────────── 3. ПОЧТА ДЛЯ ЗАЯВОК (по желанию) ──────────────────────
|
||||
# Заполните — и каждая заявка продублируется на почту. Оставите пусто — бот
|
||||
# работает как обычно, просто письма не шлёт.
|
||||
# SMTP_HOST — сервер почты, напр. smtp.yandex.ru / smtp.mail.ru / smtp.gmail.com
|
||||
SMTP_HOST=
|
||||
# Порт: 465 для SSL, 587 для STARTTLS
|
||||
# SMTP_PORT — 465 для SSL (обычно), 587 для STARTTLS
|
||||
SMTP_PORT=465
|
||||
# Логин (полный email) и пароль (для Яндекс/Gmail — пароль приложения, не основной!)
|
||||
# SMTP_USER — полный email-логин
|
||||
SMTP_USER=
|
||||
# SMTP_PASSWORD — ПАРОЛЬ ПРИЛОЖЕНИЯ (для Яндекс/Gmail), не основной пароль!
|
||||
SMTP_PASSWORD=
|
||||
# От кого отправлять (по умолчанию = SMTP_USER)
|
||||
# MAIL_FROM — от кого (пусто = как SMTP_USER)
|
||||
MAIL_FROM=
|
||||
# Куда отправлять заявки (можно несколько через запятую)
|
||||
# MAIL_TO — куда слать заявки (можно несколько через запятую)
|
||||
MAIL_TO=group-zakaz@infocyber.pro
|
||||
# Куда отправлять отклики на вакансии/набор в состав. Пусто = на тот же адрес, что MAIL_TO.
|
||||
# Можно вынести на отдельный HR-адрес, напр. hr@infocyber.pro
|
||||
HR_MAIL_TO=
|
||||
# true — SSL (порт 465), false — STARTTLS (порт 587)
|
||||
# SMTP_USE_SSL — true для порта 465, false для 587
|
||||
SMTP_USE_SSL=true
|
||||
|
||||
# --- Ссылки Кибершколы БАЗА (кнопки записи/оплаты в боте) ---
|
||||
# UTM добавляются кодом автоматически; здесь только базовые URL. Замените при необходимости.
|
||||
|
||||
# ───────────────── 4. ССЫЛКИ КНОПОК ЗАПИСИ/ОПЛАТЫ ────────────────────────
|
||||
# Куда ведут кнопки в боте. Их также можно менять прямо из «Админки → Ссылки».
|
||||
# UTM-метки бот добавляет сам.
|
||||
LINK_TRIAL=https://infocyber.pro/form/index.html
|
||||
LINK_TARIFFS=https://infocyber.pro/#prices
|
||||
LINK_GROUP_4=https://infocyber.pro/form/index.html?service_id=web_2
|
||||
@@ -44,10 +74,24 @@ LINK_GROUP_8=https://infocyber.pro/form/index.html?service_id=web_3
|
||||
LINK_IND_1=https://infocyber.pro/form/index.html?service_id=web_1
|
||||
LINK_IND_4=https://infocyber.pro/form/index.html?service_id=web_4
|
||||
LINK_IND_8=https://infocyber.pro/form/index.html?service_id=web_5
|
||||
# Летний интенсив: отдельной страницы на сайте нет — ведём на общую форму (замените, когда появится)
|
||||
# LINK_SUMMER — летний интенсив (замените, когда будет своя страница)
|
||||
LINK_SUMMER=https://infocyber.pro/form/index.html
|
||||
|
||||
# Экстренное отключение бота (/favi-stop) — ХЭШ пароля (PBKDF2), не сам пароль.
|
||||
# Сгенерировать: py -3.11 -c "import hashlib,os; s=os.urandom(16); import sys; pw=sys.argv[1].encode(); print('pbkdf2_sha256$240000$'+s.hex()+'$'+hashlib.pbkdf2_hmac('sha256',pw,s,240000).hex())" "ВАШ_ПАРОЛЬ"
|
||||
# Пусто — команда /favi-stop отключена.
|
||||
|
||||
# ───────────────── 5. ЭКСТРЕННЫЙ СТОП /favi-stop (по желанию) ─────────────
|
||||
# Команда /favi-stop у супер-админа отключает бота по паролю. Хранится ХЭШ
|
||||
# пароля, а не сам пароль. Пусто — команда отключена.
|
||||
# Сгенерировать хэш своего пароля (замените ВАШ_ПАРОЛЬ):
|
||||
# py -3.11 -c "import hashlib,os,sys; s=os.urandom(16); print('pbkdf2_sha256$240000$'+s.hex()+'$'+hashlib.pbkdf2_hmac('sha256',sys.argv[1].encode(),s,240000).hex())" "ВАШ_ПАРОЛЬ"
|
||||
FAVI_STOP_HASH=
|
||||
|
||||
|
||||
# ───────────────── ПРОЧЕЕ (можно не трогать) ─────────────────────────────
|
||||
ALLOWED_ORIGIN=https://infocyber.pro
|
||||
PROMO_ENABLED=false
|
||||
|
||||
# ============================================================================
|
||||
# СУПЕР-АДМИН (кто добавляет админов и делает /favi-stop) задаётся НЕ здесь,
|
||||
# а в коде — файл config.py, список SUPER_ADMIN_IDS.
|
||||
# Готово? Запускайте start_bot.bat.
|
||||
# ============================================================================
|
||||
|
||||
@@ -23,14 +23,26 @@ def _load_env():
|
||||
|
||||
_load_env()
|
||||
|
||||
|
||||
def _int_env(key: str, default) -> int:
|
||||
"""Безопасно читает целое из .env: пустое/кривое значение → default (без краха)."""
|
||||
raw = os.getenv(key, None)
|
||||
if raw is None or str(raw).strip() == "":
|
||||
return int(default)
|
||||
try:
|
||||
return int(str(raw).strip())
|
||||
except (ValueError, TypeError):
|
||||
return int(default)
|
||||
|
||||
|
||||
# VK API Configuration
|
||||
# In production, these should be loaded from environment variables or a secure .env file.
|
||||
VK_TOKEN = os.getenv("VK_TOKEN", "your_vk_community_token_here")
|
||||
GROUP_ID = int(os.getenv("VK_GROUP_ID", "0")) # Community ID (must be integer)
|
||||
VK_TOKEN = os.getenv("VK_TOKEN", "your_vk_community_token_here") or "your_vk_community_token_here"
|
||||
GROUP_ID = _int_env("VK_GROUP_ID", 0) # Community ID (must be integer)
|
||||
|
||||
# Operator / Admin configuration
|
||||
# ID of the user or chat where notifications about new leads and operator requests will be sent
|
||||
OPERATOR_PEER_ID = int(os.getenv("OPERATOR_PEER_ID", "12345678")) # Change to actual VK user ID of operator
|
||||
OPERATOR_PEER_ID = _int_env("OPERATOR_PEER_ID", 12345678) # Change to actual VK user ID of operator
|
||||
|
||||
# Parse ADMIN_IDS as a list of integers from comma-separated env values
|
||||
admin_ids_raw = os.getenv("ADMIN_IDS")
|
||||
@@ -69,8 +81,8 @@ else:
|
||||
OPERATOR_PEER_IDS = [OPERATOR_PEER_ID]
|
||||
|
||||
# Часы работы (для статуса оператора). Вне этого интервала — «ответим утром».
|
||||
WORK_HOUR_START = int(os.getenv("WORK_HOUR_START", "9"))
|
||||
WORK_HOUR_END = int(os.getenv("WORK_HOUR_END", "21"))
|
||||
WORK_HOUR_START = _int_env("WORK_HOUR_START", 9)
|
||||
WORK_HOUR_END = _int_env("WORK_HOUR_END", 21)
|
||||
|
||||
# Разрешённый источник (Origin) для CORS веб-формы. '*' допустим только для локальной отладки.
|
||||
ALLOWED_ORIGIN = os.getenv("ALLOWED_ORIGIN", "https://infocyber.pro")
|
||||
@@ -81,7 +93,7 @@ PROMO_ENABLED = os.getenv("PROMO_ENABLED", "false").strip().lower() in ("1", "tr
|
||||
|
||||
# Email (SMTP) configuration для уведомлений о заявках
|
||||
SMTP_HOST = os.getenv("SMTP_HOST", "")
|
||||
SMTP_PORT = int(os.getenv("SMTP_PORT", "465"))
|
||||
SMTP_PORT = _int_env("SMTP_PORT", 465)
|
||||
SMTP_USER = os.getenv("SMTP_USER", "")
|
||||
SMTP_PASSWORD = os.getenv("SMTP_PASSWORD", "")
|
||||
MAIL_FROM = os.getenv("MAIL_FROM", "") or SMTP_USER
|
||||
|
||||
Reference in New Issue
Block a user