From aded3fff7e9f46bccf8e69a3b2e09caa774c3bf7 Mon Sep 17 00:00:00 2001 From: Oscar Date: Fri, 29 May 2026 17:07:35 +0300 Subject: [PATCH] =?UTF-8?q?=F0=9F=9A=80=20feat(bot-commands):=20=D0=94?= =?UTF-8?q?=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB=D0=B5=D0=BD=D0=B0=20=D0=BE=D0=B1?= =?UTF-8?q?=D1=80=D0=B0=D0=B1=D0=BE=D1=82=D0=BA=D0=B0=20=D1=81=D1=82=D0=B0?= =?UTF-8?q?=D1=82=D1=83=D1=81=D0=B0=20"=D0=BE=D1=82=D0=BA=D0=BB=D0=B8?= =?UTF-8?q?=D0=BA=D0=B0=D1=8E=D1=81=D1=8C=20=D0=BD=D0=B0=20=D0=B2=D0=B0?= =?UTF-8?q?=D0=BA=D0=B0=D0=BD=D1=81=D0=B8=D0=B8"=20=D0=BF=D1=80=D0=B8=20?= =?UTF-8?q?=D0=BA=D0=BE=D0=BC=D0=B0=D0=BD=D0=B4=D0=B5=20/apply.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hh/bot-commands.ts | 6 ++++++ src/hh/handlers/apply.ts | 14 ++++++++++++-- src/hh/state.ts | 2 ++ src/hh/ui.ts | 6 ++++++ 4 files changed, 26 insertions(+), 2 deletions(-) diff --git a/src/hh/bot-commands.ts b/src/hh/bot-commands.ts index 6607bbe..f670729 100644 --- a/src/hh/bot-commands.ts +++ b/src/hh/bot-commands.ts @@ -127,6 +127,12 @@ export function registerHHCommands() { const chatId = msg.chat.id const state = getState(chatId) + + if (state.isApplying) { + await bot.sendMessage(chatId, '⏳ Подождите, идут отклики на вакансии...') + return + } + const isAwaiting = state.awaitingEmail || state.awaitingQuery || state.awaitingMax || state.awaitingPrompt const isMenuButton = Object.values(BTN).includes(msg.text as typeof BTN[keyof typeof BTN]) diff --git a/src/hh/handlers/apply.ts b/src/hh/handlers/apply.ts index 15ad666..3873b8a 100644 --- a/src/hh/handlers/apply.ts +++ b/src/hh/handlers/apply.ts @@ -1,18 +1,24 @@ import bot from '@bot' import prisma from '@prisma' import { applyToJobs } from '../scraper.js' -import { createStatusReporter, escapeHtml } from '../ui.js' +import { APPLYING_REPLY_KEYBOARD, MAIN_REPLY_KEYBOARD, createStatusReporter, escapeHtml } from '../ui.js' +import { getState } from '../state.js' export async function handleApply(chatId: number): Promise { const settings = await prisma.settings.findUnique({ where: { telegramId: chatId } }) if (!settings) return + const state = getState(chatId) + state.isApplying = true + const reporter = createStatusReporter(chatId) - await reporter.keep(`🔄 Ищу вакансии по запросу "${settings.searchQuery}"...`) + await bot.sendMessage(chatId, `🔄 Ищу вакансии по запросу "${settings.searchQuery}"...`, { reply_markup: APPLYING_REPLY_KEYBOARD }) applyToJobs({ query: settings.searchQuery, maxApplies: settings.maxApplies }, { chatId, reporter }) .then(async (result) => { + state.isApplying = false + await bot.sendMessage(chatId, '✅ Готово', { reply_markup: MAIN_REPLY_KEYBOARD }) if (result.error) { await bot.sendMessage(chatId, `❌ ${result.error}`) return @@ -46,4 +52,8 @@ export async function handleApply(chatId: number): Promise { }) } }) + .catch(async () => { + state.isApplying = false + await bot.sendMessage(chatId, '❌ Ошибка при откликах', { reply_markup: MAIN_REPLY_KEYBOARD }) + }) } diff --git a/src/hh/state.ts b/src/hh/state.ts index 8d966e8..5699e9c 100644 --- a/src/hh/state.ts +++ b/src/hh/state.ts @@ -3,6 +3,7 @@ import type { ScheduledTask } from 'node-cron' export interface UserState { autoCron: ScheduledTask | null + isApplying: boolean awaitingEmail: boolean awaitingQuery: boolean awaitingMax: boolean @@ -17,6 +18,7 @@ export interface UserState { function makeUserState(): UserState { return { autoCron: null, + isApplying: false, awaitingEmail: false, awaitingQuery: false, awaitingMax: false, diff --git a/src/hh/ui.ts b/src/hh/ui.ts index 4efacc6..a92f826 100644 --- a/src/hh/ui.ts +++ b/src/hh/ui.ts @@ -52,6 +52,12 @@ export const INFO_REPLY_KEYBOARD = { persistent: true, } +export const APPLYING_REPLY_KEYBOARD = { + keyboard: [[{ text: '⏳ Откликаюсь на вакансии...' }]], + resize_keyboard: true, + persistent: true, +} + export const BACK_MARKUP = { inline_keyboard: [[{ text: '◀️ Назад', callback_data: 'hh_back' }]], }