Десктопная система для автоматизации лидогенерации в холодных продажах
Система обрабатывает выгрузки компаний из Яндекс.Карт/2GIS через сервис Webbee AI, преобразует «сырые» данные в очищенный CSV и готовит их к импорту в Битрикс24.
- Возможности
- Быстрый старт
- Структура проекта
- Архитектура
- Инструкция по использованию
- Конфигурация
- API
- База данных
- Тестирование
- Устранение проблем
- Вклад в проект
- Лицензия
- ✅ Загрузка TSV/CSV/JSON файлов от Webbee AI
- ✅ Очистка и нормализация телефонных номеров (конвертация из научной нотации)
- ✅ Удаление дубликатов по номерам телефонов
- ✅ Распределение лидов по менеджерам (round-robin)
- ✅ Маппинг данных в формат Битрикс24 (64 колонки)
- ✅ Экспорт в CSV с кодировкой UTF-8 с BOM
- ✅ REST API Битрикс24 (вебхуки)
- ✅ Аналитика из Битрикс24 (загрузка LEAD.csv, DEAL.csv)
- ✅ Генератор ссылок Яндекс.Карт по сегментам
- ✅ Парсинг ЛПР (ФИО, должности, ИНН, телефоны, email)
- ✅ PySide6 интерфейс с тёмной темой
- ✅ Sidebar навигация с анимацией
- ✅ Drag & Drop загрузка файлов
- ✅ Предпросмотр данных с пагинацией
- ✅ Прогресс-бар обработки
- ✅ Мониторинг менеджеров в реальном времени
- ✅ SQLite база данных для хранения статистики
- ✅ История обработок файлов
- ✅ Экспорт отчётов в Excel (openpyxl)
- ✅ Генерация диаграмм (matplotlib)
pip install -r requirements.txt# Скопируйте шаблон переменных окружения
copy .env.example .envОтредактируйте .env и добавьте ваш вебхук Битрикс24:
BITRIX_WEBHOOK_URL=https://your-company.bitrix24.ru/rest/1/your_webhook_code/python main.pyLeadGen_v5/
├── main.py # Точка входа (PySide6 QApplication)
├── config.json # Настройки приложения
├── .env.example # Шаблон переменных окружения
├── requirements.txt # Зависимости Python
├── README.md # Пользовательская документация
├── QWEN.md # Контекст для AI-агентов
├── CHANGELOG.md # История изменений
├── mypy.ini # Настройки типизации
├── pytest.ini # Настройки pytest
│
├── core/ # Ядро приложения
│ ├── __init__.py
│ └── dependency_container.py # Dependency Injection Container
│
├── modules/ # Бизнес-логика
│ ├── __init__.py
│ ├── services/
│ │ ├── __init__.py
│ │ └── processing_service.py # Сервисный слой обработки
│ ├── phone_validator.py # Валидация/нормализация телефонов
│ ├── data_processor.py # Загрузка, очистка, объединение файлов
│ ├── bitrix_mapper.py # Маппинг в 64 колонки Битрикс24
│ ├── bitrix_webhook.py # REST API Битрикс24 (вебхуки)
│ ├── bitrix_analytics.py # Аналитика из Битрикс24
│ ├── chart_generator.py # Генерация диаграмм (matplotlib)
│ ├── report_exporter.py # Экспорт отчётов в Excel (openpyxl)
│ ├── lpr_parser.py # Парсинг ЛПР (лицо, принимающее решение)
│ └── exceptions.py # Иерархия исключений (10 типов)
│
├── gui/ # PySide6 интерфейс
│ ├── __init__.py
│ ├── main_window.py # Главное окно с sidebar навигацией
│ ├── sidebar.py # Боковая панель навигации
│ ├── preview_table.py # Предпросмотр данных
│ ├── progress_bar.py # Прогресс-бар
│ ├── pages/ # Страницы приложения
│ │ ├── __init__.py
│ │ ├── home_page.py # Главная страница
│ │ ├── processing_page.py # Страница обработки файлов
│ │ ├── analytics_page.py # Аналитика Битрикс
│ │ ├── link_generator_page.py # Генератор ссылок
│ │ ├── lpr_finder_page.py # Поиск ЛПР
│ │ ├── manager_monitor_page.py # Мониторинг менеджеров
│ │ └── settings_page.py # Настройки
│ ├── components/ # Переиспользуемые компоненты
│ │ ├── __init__.py
│ │ ├── circular_progress.py # Круговой прогресс
│ │ ├── file_list.py # Список файлов
│ │ └── file_loader.py # Загрузка файлов Drag&Drop
│ ├── styles/ # Стили и темы
│ │ ├── __init__.py
│ │ ├── stylesheet.py # Таблицы стилей
│ │ └── theme.py # Цветовые переменные
│ ├── threads/ # Потоки обработки
│ │ ├── __init__.py
│ │ └── processing_thread.py # ProcessingThread, ExportThread
│ └── utils/ # Утилиты GUI
│ ├── __init__.py
│ ├── error_handler.py # Обработка ошибок
│ └── thread_helpers.py # Помощники потоков
│
├── database/ # База данных SQLite
│ ├── __init__.py
│ ├── db_manager.py # Менеджер БД (обёртка)
│ └── models.py # Модели таблиц (statistics, managers, history)
│
├── utils/ # Утилиты
│ ├── __init__.py
│ ├── logger.py # Настройка логирования
│ ├── config_loader.py # Загрузка/сохранение конфигурации
│ ├── url_cleaner.py # Очистка URL от UTM-меток
│ ├── url_generator.py # Генератор URL Яндекс.Карт
│ └── windows_blur.py # Windows DWM blur эффект
│
├── data/ # Данные приложения
│ ├── input/ # Входные файлы (JSON/TSV/CSV)
│ ├── output/ # Выходные CSV файлы
│ ├── reports/ # Отчёты Excel
│ ├── logs/ # Логи приложения (*.log)
│ └── database.db # SQLite база данных
│
├── docs/ # Документация
│ ├── CODEMAPS/ # Карты проекта
│ │ ├── frontend.md
│ │ ├── backend.md
│ │ ├── database.md
│ │ ├── services.md
│ │ └── integrations.md
│ ├── api/ # API документация
│ │ └── bitrix-webhook.md
│ ├── architecture.md # Архитектурный обзор
│ └── database-schema.md # Схема базы данных
│
└── tests/ # Модульные тесты
├── __init__.py
├── conftest.py # Конфигурация pytest
├── test_phone_validator.py # 9 тестов
├── test_data_processor.py # 4 теста
├── test_bitrix_mapper.py # 4 теста
├── test_bitrix_webhook.py # Тесты вебхуков
├── test_bitrix_analytics.py # Тесты аналитики
├── test_chart_generator.py # Тесты графиков
├── test_lpr_parser.py # Тесты парсера ЛПР
├── test_report_exporter.py # Тесты экспорта
├── test_processing_service.py # 8 тестов сервиса
├── test_exceptions.py # 19 тестов исключений
└── test_gui/ # GUI тесты
┌─────────────────────────────────────────────────────────┐
│ GUI Layer (PySide6) │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────────┐ │
│ │ Pages │ │ Components │ │ Threads │ │
│ └─────────────┘ └─────────────┘ └─────────────────┘ │
└─────────────────────────────────────────────────────────┘
↓
┌─────────────────────────────────────────────────────────┐
│ Service Layer (ProcessingService) │
│ ┌─────────────────────────────────────────────────┐ │
│ │ Dependency Injection Container │ │
│ └─────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────┘
↓
┌─────────────────────────────────────────────────────────┐
│ Business Logic Layer (modules/) │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────────┐ │
│ │ Data │ │ Bitrix │ │ Validators │ │
│ │ Processor │ │ Mapper │ │ │ │
│ └─────────────┘ └─────────────┘ └─────────────────┘ │
└─────────────────────────────────────────────────────────┘
↓
┌─────────────────────────────────────────────────────────┐
│ Data Access Layer (database/) │
│ ┌─────────────┐ ┌─────────────┐ │
│ │ DB Manager │ │ Models │ │
│ └─────────────┘ └─────────────┘ │
└─────────────────────────────────────────────────────────┘
PySide6 виджеты, обработка событий UI:
- Pages — страницы приложения (HomePage, ProcessingPage, etc.)
- Components — переиспользуемые компоненты (FileLoader, CircularProgress)
- Threads — фоновые потоки обработки (ProcessingThread, ExportThread)
- Styles — таблицы стилей и цветовые темы
Сервисный слой для абстракции между GUI и бизнес-логикой:
- DependencyContainer — централизованное управление зависимостями
- ProcessingService — сервис обработки лидов
Обработка данных, маппинг, валидация:
- phone_validator.py — нормализация телефонов
- data_processor.py — загрузка и обработка файлов
- bitrix_mapper.py — маппинг в формат Битрикс24
- bitrix_webhook.py — REST API интеграция
- bitrix_analytics.py — аналитика из Битрикс24
- chart_generator.py — генерация графиков
- report_exporter.py — экспорт в Excel
- lpr_parser.py — парсинг ЛПР
- exceptions.py — иерархия исключений
SQLite операции:
- db_manager.py — менеджер подключений
- models.py — SQL модели и функции
Логирование, конфигурация, вспомогательные функции:
- logger.py — настройка логирования
- config_loader.py — загрузка конфигурации
- url_cleaner.py — очистка URL от UTM
- url_generator.py — генератор URL Яндекс.Карт
-
Скопируйте
.env.exampleв.env:copy .env.example .env
-
Добавьте URL вебхука Битрикс24 в файл
.env:BITRIX_WEBHOOK_URL=https://your-company.bitrix24.ru/rest/1/your_webhook_code/
- Запустите приложение:
python main.py - Перейдите на страницу «Обработка файлов»
- Нажмите кнопку «📁 Выбрать файлы (JSON/TSV/CSV)» или перетащите файлы в область Drag & Drop
- Файлы отобразятся в списке
- В правой панели введите имена менеджеров (по одному на строку)
- Валидация автоматически проверит:
- Минимум 1 менеджер
- Максимум 10 менеджеров
- Длина имени от 2 до 50 символов
- Нажмите «Сохранить список менеджеров»
- Нажмите кнопку «Очистить и объединить»
- Дождитесь завершения обработки (прогресс-бар показывает статус)
- Проверьте предпросмотр результатов
- Нажмите кнопку «📤 Экспортировать для Битрикс»
- Выберите место сохранения файла
- Импортируйте CSV в Битрикс24
- Перейдите на вкладку «Аналитика Битрикс»
- Загрузите файлы
LEAD.csvиDEAL.csvиз экспорта Битрикс24 - Нажмите «Запустить анализ»
- Просмотрите воронки, категории, менеджеров и причины отказа
- Экспортируйте отчёт в Excel
- Перейдите на вкладку «Генератор ссылок»
- Введите поисковый запрос (сегмент)
- Выберите города и районы
- Нажмите «Сгенерировать ссылки»
- Скопируйте или сохраните в CSV
- Перейдите на вкладку «Поиск ЛПР»
- Загрузите CSV файл со списком компаний
- Нажмите «Запустить поиск ЛПР»
- Получите ФИО, должности, ИНН, телефоны и email ЛПР
- Перейдите на вкладку «Мониторинг менеджеров»
- Настройте URL вебхука Битрикс24
- Нажмите «Проверить и загрузить»
- Просмотрите распределение лидов по менеджерам
- Исключите менеджеров из распределения при необходимости
# Битрикс24 Вебхук
BITRIX_WEBHOOK_URL=https://your-company.bitrix24.ru/rest/1/your_webhook_code/
# Настройки обработки
PHONE_FORMAT=7
MIN_PHONE_LENGTH=10
REMOVE_DUPLICATES=true
IGNORE_PHONE_2=false
# Настройки UI
UI_THEME=dark
UI_FONT_SIZE=10
# Пути
INPUT_DIR=data/input
OUTPUT_DIR=data/output
DATABASE_PATH=data/database.db
# Логирование
LOG_LEVEL=INFO{
"managers": ["Елена Юматова"],
"processing": {
"phone_format": "7",
"remove_duplicates": true,
"min_phone_length": 10,
"ignore_phone_2": false
},
"paths": {
"input_dir": "data/input",
"output_dir": "data/output",
"database": "data/database.db"
},
"ui": {
"theme": "dark",
"font_family": "Cambria",
"font_size": 10
},
"bitrix": {
"stage": "Новая заявка",
"source": "Холодный звонок",
"service_type": "ГЦК"
},
"bitrix_webhook": {
"webhook_url": "",
"status_id": "Новая заявка",
"max_leads_per_manager": 75,
"excluded_managers": []
},
"regions": ["Москва", "Санкт-Петербург"],
"city_districts": {},
"log_level": "INFO"
}Клиент для работы с REST API Битрикс24 через вебхуки.
from modules.bitrix_webhook import BitrixWebhookClient
client = BitrixWebhookClient(
webhook_url="https://your-company.bitrix24.ru/rest/1/webhook_code/",
config=config
)Проверяет подключение к Битрикс24.
if client.test_connection():
print("Подключение успешно")Получает новые лиды из Битрикс24.
leads = client.get_new_leads()
for lead in leads:
print(f"Лид: {lead['TITLE']}, Телефон: {lead['PHONE']}")Получает список менеджеров (пользователей Битрикс24).
managers = client.get_managers()
for manager in managers:
print(f"Менеджер: {manager['NAME']} {manager['LAST_NAME']}")Назначает лида на менеджера.
success = client.assign_lead(lead_id="123", manager_id="456")Обновляет статус лида.
success = client.update_lead_status(lead_id="123", status="В работе")from modules.exceptions import (
BitrixWebhookNotFoundError,
BitrixWebhookForbiddenError,
BitrixWebhookRateLimitError,
BitrixWebhookConnectionError
)
try:
leads = client.get_new_leads()
except BitrixWebhookNotFoundError:
logger.error("Вебхук не найден")
except BitrixWebhookForbiddenError:
logger.error("Нет прав доступа")
except BitrixWebhookRateLimitError:
logger.warning("Превышен лимит запросов, ждём 1 секунду")
time.sleep(1)
except BitrixWebhookConnectionError:
logger.error("Нет подключения к интернету")Информация о загрузках файлов.
| Колонка | Тип | Описание |
|---|---|---|
| id | INTEGER | Первичный ключ |
| filename | TEXT | Имя файла |
| rows_processed | INTEGER | Количество обработанных строк |
| duplicates_removed | INTEGER | Количество удалённых дубликатов |
| processing_time_ms | INTEGER | Время обработки (мс) |
| created_at | TIMESTAMP | Дата и время создания |
Список активных менеджеров.
| Колонка | Тип | Описание |
|---|---|---|
| id | INTEGER | Первичный ключ |
| name | TEXT | Имя менеджера |
| is_active | BOOLEAN | Активен ли менеджер |
| created_at | TIMESTAMP | Дата добавления |
История обработок файлов.
| Колонка | Тип | Описание |
|---|---|---|
| id | INTEGER | Первичный ключ |
| filename | TEXT | Имя файла |
| rows_processed | INTEGER | Количество строк |
| duplicates_removed | INTEGER | Удалённые дубликаты |
| processing_time_ms | INTEGER | Время обработки |
| created_at | TIMESTAMP | Дата обработки |
from database.db_manager import DatabaseManager
db = DatabaseManager("data/database.db")
# Сохранение статистики
db.add_statistics(
filename="file.json",
rows_processed=100,
duplicates_removed=10,
processing_time_ms=500
)
# Сохранение менеджеров
db.save_managers(["Менеджер 1", "Менеджер 2"])
# Получение активных менеджеров
managers = db.get_active_managers()
# Получение истории
history = db.get_history(limit=10)# Запуск всех тестов
pytest tests/
# Запуск с отчётом о покрытии
pytest tests/ --cov=. --cov-report=html
# Запуск конкретных тестов
pytest tests/test_phone_validator.py
pytest tests/test_processing_service.py| Модуль | Тесты | Покрытие |
|---|---|---|
| phone_validator.py | 9 тестов | ~95% |
| data_processor.py | 4 теста | ~85% |
| bitrix_mapper.py | 4 теста | ~90% |
| processing_service.py | 8 тестов | ~92% |
| exceptions.py | 19 тестов | ~100% |
# tests/test_example.py
import pytest
from modules.phone_validator import clean_phone
def test_clean_phone_valid():
assert clean_phone("79991234567") == "79991234567"
def test_clean_phone_scientific():
assert clean_phone(7.8005001695e+10) == "78005001695"
def test_clean_phone_invalid():
assert clean_phone("123") is Nonepip install --upgrade PySide6pip install matplotlibУбедитесь, что файл в кодировке UTF-8. При необходимости конвертируйте.
- Убедитесь, что файл
.envсуществует - Проверьте, что
BITRIX_WEBHOOK_URLуказан в.env - Перезапустите приложение
Убедитесь, что приложение запущено от имени администратора (Windows UAC может блокировать).
Проверьте, что файлы находятся в директории data/input или выбирайте через диалог.
- Именование: snake_case для функций/переменных, PascalCase для классов
- Типизация: Type hints для всех функций (Python 3.10+ синтаксис)
- Docstrings: Google-style docstrings для публичных функций
- Логирование: Использовать
logging.getLogger(__name__)в каждом модуле
- Создайте ветку для новой функции
- Напишите тесты
- Реализуйте функциональность
- Запустите тесты и линтеры
- Создайте pull request
Используйте Conventional Commits:
feat: добавление экспорта в Excel
fix: исправление ошибки валидации телефонов
docs: обновление документации API
refactor: рефакторинг ProcessingService
test: добавление тестов для bitrix_webhook
Внутренняя разработка DIRECT-LINE.
По вопросам обращайтесь к разработчику проекта.
Версия: 5.1.0 Дата обновления: 20 марта 2026 г.
- Новая компоновка интерфейса: сегмент+результаты слева, города справа
- Часовые пояса городов: автоматическое определение времени для каждого города
- Диалог управления городами: удобное добавление/удаление городов и районов
- Сохранение выбранных городов: между сессиями приложения
- Логотип приложения: визуальный элемент на HomePage
- Glassmorphism эффекты: полупрозрачные карточки с размытием
- Улучшенная типографика: обновлённые шрифты и отступы
- Удалено дублирование кнопок «Добавить город»
- Перемещено управление городами из настроек в генератор ссылок
- Добавлены стили glassmorphism для современных эффектов
