From c2971645adee69cda292c8284ff1e7ea4b0647d3 Mon Sep 17 00:00:00 2001 From: itqop Date: Sat, 28 Jun 2025 19:39:23 +0300 Subject: [PATCH] feat: add AI cover letter CLI option and update README - Add CLI toggle for AI-generated cover letters - Update README with cover letter documentation and examples - Display cover letter status in launch summary - Independent control from AI vacancy filtering --- README.md | 41 +++++++++++++++++++++++++++++- hh_bot/cli/interface.py | 14 ++++++++-- hh_bot/config/settings.py | 1 + hh_bot/services/browser_service.py | 3 +++ 4 files changed, 56 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index a8287ef..d4ed236 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,8 @@ - **🔍 Умный поиск** - Находит релевантные вакансии по ключевым словам - **🤖 ИИ-анализ** - Gemini AI оценивает соответствие резюме требованиям -- **📝 Автоматические отклики** - Отправляет заявки на подходящие вакансии +- **📝 Автоматические отклики** - Отправляет заявки на подходящие вакансии +- **✉️ ИИ-сопроводительные письма** - Автоматически генерирует персональные письма для каждой вакансии - **⚙️ Гибкая настройка** - Настраиваемые критерии поиска и фильтрации - **📊 Детальная статистика** - Отчёты о проделанной работе - **🛡️ Безопасность** - Имитация человеческого поведения, паузы между действиями @@ -81,6 +82,7 @@ python main.py 🎯 НАСТРОЙКА ПОИСКА: Ключевые слова [python junior]: python разработчик Использовать AI фильтрацию? [y/n]: y +Использовать ИИ-сопроводительные письма? [y/n]: y Максимум заявок [40]: 25 Начать автоматизацию? [y/n]: y @@ -132,6 +134,9 @@ class AppConstants: # ИИ анализ DEFAULT_AI_THRESHOLD = 0.7 + # Сопроводительные письма + USE_AI_COVER_LETTERS = True + # Таймауты DEFAULT_TIMEOUT = 30 API_PAUSE_SECONDS = 0.5 @@ -159,6 +164,40 @@ class AppConstants: 📈 % одобрения: 53.3% ``` +## ✉️ ИИ-сопроводительные письма + +### Как работает автоматическая генерация писем + +1. **Обнаружение возможности** - Ищет кнопку "Добавить сопроводительное письмо" +2. **Анализ вакансии** - Извлекает требования, обязанности, название и компанию +3. **Персонализация** - Использует ваши реальные данные из файлов резюме +4. **Генерация письма** - Gemini AI создает уникальное письмо для каждой вакансии +5. **Автозаполнение** - Вставляет письмо в поле и отправляет заявку + +### Особенности ИИ-писем + +- **Персональные** - Каждое письмо уникально для конкретной вакансии +- **Честные** - Не придумывает несуществующий опыт +- **Человечные** - Дружелюбный тон без официоза +- **Контактные** - Всегда включает контакт "Telegram — @itqen" +- **Адаптивные** - Работает с любыми типами вакансий + +### Пример сгенерированного письма + +``` +Добрый день! + +Заинтересовался вашей вакансией Python-разработчика. +У меня есть опыт работы с Python, Django и базами данных, +что соответствует вашим требованиям. + +Готов обсудить возможности сотрудничества и рассказать +подробнее о своем опыте. + +С уважением, +Telegram — @itqen +``` + ## 📊 Статистика работы После завершения работы бот предоставляет подробную статистику: diff --git a/hh_bot/cli/interface.py b/hh_bot/cli/interface.py index 53bbb28..858ac79 100644 --- a/hh_bot/cli/interface.py +++ b/hh_bot/cli/interface.py @@ -39,6 +39,14 @@ class CLIInterface: print("⚠️ AI фильтрация недоступна (нет GEMINI_API_KEY)") use_ai = False + use_ai_cover_letters = True + if settings.enable_ai_matching(): + cover_letter_choice = input("Использовать ИИ-сопроводительные письма? [y/n]: ").lower() + use_ai_cover_letters = cover_letter_choice != "n" + else: + print("⚠️ ИИ-сопроводительные письма недоступны (нет GEMINI_API_KEY)") + use_ai_cover_letters = False + excludes = ", ".join(settings.get_exclude_keywords()[:5]) print(f"\n🚫 Текущие исключения: {excludes}...") exclude_choice = input("Изменить список исключений? [y/n]: ").lower() @@ -56,7 +64,7 @@ class CLIInterface: except ValueError: max_apps = settings.application.max_applications - return keywords, use_ai, max_apps + return keywords, use_ai, use_ai_cover_letters, max_apps @staticmethod def _configure_exclude_keywords(): @@ -104,14 +112,16 @@ class CLIInterface: cli.print_welcome() ResumeFileManager.create_sample_files() cli.print_settings_info() - keywords, use_ai, max_apps = cli.get_user_preferences() + keywords, use_ai, use_ai_cover_letters, max_apps = cli.get_user_preferences() settings.update_search_keywords(keywords) settings.application.max_applications = max_apps + settings.application.use_ai_cover_letters = use_ai_cover_letters print("\n🎯 ЗАПУСК С ПАРАМЕТРАМИ:") print(f"🔍 Поиск: {keywords}") print(f"🤖 AI: {'Включен' if use_ai else 'Отключен'}") + print(f"📝 ИИ-письма: {'Включены' if use_ai_cover_letters else 'Отключены'}") print(f"📊 Максимум заявок: {max_apps}") confirm = input("\nНачать автоматизацию? [y/n]: ").lower() diff --git a/hh_bot/config/settings.py b/hh_bot/config/settings.py index 69f21d6..5997e36 100644 --- a/hh_bot/config/settings.py +++ b/hh_bot/config/settings.py @@ -65,6 +65,7 @@ class ApplicationConfig: pause_min: float = 3.0 pause_max: float = 6.0 manual_login: bool = True + use_ai_cover_letters: bool = True @dataclass diff --git a/hh_bot/services/browser_service.py b/hh_bot/services/browser_service.py index 53a7277..226de93 100644 --- a/hh_bot/services/browser_service.py +++ b/hh_bot/services/browser_service.py @@ -435,6 +435,9 @@ class VacancyApplicator: def _add_cover_letter_if_possible(self, vacancy: Vacancy) -> None: """Добавление сопроводительного письма если возможно""" try: + if not settings.application.use_ai_cover_letters: + logger.info("ИИ-сопроводительные письма отключены в настройках") + return cover_letter_button_selectors = [ '[data-qa="add-cover-letter"]', 'button[data-qa*="cover-letter"]',