mirror of
https://github.com/hempyhemp/hh-auto-reply.git
synced 2026-06-08 18:04:57 +00:00
🎨 Изменение(bot-commands): Обновлено отображение списка пропущенных вакансий
This commit is contained in:
@@ -0,0 +1,11 @@
|
|||||||
|
-- CreateTable
|
||||||
|
CREATE TABLE "SkippedVacancy" (
|
||||||
|
"id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
|
||||||
|
"telegramId" BIGINT NOT NULL,
|
||||||
|
"href" TEXT NOT NULL,
|
||||||
|
"title" TEXT NOT NULL,
|
||||||
|
"createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP
|
||||||
|
);
|
||||||
|
|
||||||
|
-- CreateIndex
|
||||||
|
CREATE UNIQUE INDEX "SkippedVacancy_telegramId_href_key" ON "SkippedVacancy"("telegramId", "href");
|
||||||
@@ -42,3 +42,13 @@ model Settings {
|
|||||||
maxApplies Int @default(1)
|
maxApplies Int @default(1)
|
||||||
selectedResumeId String?
|
selectedResumeId String?
|
||||||
}
|
}
|
||||||
|
|
||||||
|
model SkippedVacancy {
|
||||||
|
id Int @id @default(autoincrement())
|
||||||
|
telegramId BigInt
|
||||||
|
href String
|
||||||
|
title String
|
||||||
|
createdAt DateTime @default(now())
|
||||||
|
|
||||||
|
@@unique([telegramId, href])
|
||||||
|
}
|
||||||
|
|||||||
@@ -328,6 +328,28 @@ export function registerHHCommands() {
|
|||||||
await showResult(chatId, messageId, '⛔ Авто остановлен')
|
await showResult(chatId, messageId, '⛔ Авто остановлен')
|
||||||
break
|
break
|
||||||
|
|
||||||
|
case 'hh_skipped': {
|
||||||
|
const skipped = await prisma.skippedVacancy.findMany({
|
||||||
|
where: { telegramId: chatId },
|
||||||
|
orderBy: { createdAt: 'desc' },
|
||||||
|
take: 50,
|
||||||
|
})
|
||||||
|
if (!skipped.length) {
|
||||||
|
await showResult(chatId, messageId, '✅ Проблемных вакансий нет')
|
||||||
|
break
|
||||||
|
}
|
||||||
|
const lines = ['🚫 <b>Вакансии с опросником (бот не может откликнуться):</b>', '']
|
||||||
|
skipped.forEach(v => lines.push(`• <a href="${escapeHtml(v.href)}">${escapeHtml(v.title)}</a>`))
|
||||||
|
await bot.editMessageText(lines.join('\n'), {
|
||||||
|
chat_id: chatId,
|
||||||
|
message_id: messageId,
|
||||||
|
parse_mode: 'HTML',
|
||||||
|
disable_web_page_preview: true,
|
||||||
|
reply_markup: BACK_MARKUP,
|
||||||
|
})
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
case 'hh_resume_list': {
|
case 'hh_resume_list': {
|
||||||
await bot.editMessageText('🔄 Загружаю список резюме...', {
|
await bot.editMessageText('🔄 Загружаю список резюме...', {
|
||||||
chat_id: chatId,
|
chat_id: chatId,
|
||||||
|
|||||||
@@ -218,8 +218,21 @@ export async function applyToJobs(
|
|||||||
return results
|
return results
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const vacancy of vacancies.slice(0, maxApplies)) {
|
const knownSkipped = new Set(
|
||||||
|
(await prisma.skippedVacancy.findMany({ where: { telegramId: chatId }, select: { href: true } }))
|
||||||
|
.map(v => v.href),
|
||||||
|
)
|
||||||
|
|
||||||
|
let appliedCount = 0
|
||||||
|
for (const vacancy of vacancies) {
|
||||||
|
if (appliedCount >= maxApplies)
|
||||||
|
break
|
||||||
const ref: VacancyRef = { title: vacancy.title, href: vacancy.href }
|
const ref: VacancyRef = { title: vacancy.title, href: vacancy.href }
|
||||||
|
|
||||||
|
if (knownSkipped.has(vacancy.href)) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await status(`🔄 Обрабатывается: ${vacancy.title}`)
|
await status(`🔄 Обрабатывается: ${vacancy.title}`)
|
||||||
await page.goto(vacancy.href, { waitUntil: 'domcontentloaded' })
|
await page.goto(vacancy.href, { waitUntil: 'domcontentloaded' })
|
||||||
@@ -249,8 +262,21 @@ export async function applyToJobs(
|
|||||||
await randomScroll(page)
|
await randomScroll(page)
|
||||||
|
|
||||||
await applyBtn.click()
|
await applyBtn.click()
|
||||||
|
await page.waitForLoadState('domcontentloaded').catch(() => {})
|
||||||
await page.waitForTimeout(randomDelay())
|
await page.waitForTimeout(randomDelay())
|
||||||
|
|
||||||
|
const hasQuestionnaire = await page.$('[data-qa="employer-asking-for-test"]').catch(() => null)
|
||||||
|
if (hasQuestionnaire) {
|
||||||
|
console.log(`[x] ${vacancy.title} hasQuestionnaire`)
|
||||||
|
await prisma.skippedVacancy.upsert({
|
||||||
|
where: { telegramId_href: { telegramId: chatId, href: vacancy.href } },
|
||||||
|
create: { telegramId: chatId, href: vacancy.href, title: vacancy.title },
|
||||||
|
update: {},
|
||||||
|
})
|
||||||
|
results.skipped.push(ref)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
if (resumes.length > 1) {
|
if (resumes.length > 1) {
|
||||||
// Выбор резюме
|
// Выбор резюме
|
||||||
const currentResumeEl = await page.$('[data-qa="resume-title"]')
|
const currentResumeEl = await page.$('[data-qa="resume-title"]')
|
||||||
@@ -284,15 +310,20 @@ export async function applyToJobs(
|
|||||||
}
|
}
|
||||||
|
|
||||||
const letter = await letterPromise
|
const letter = await letterPromise
|
||||||
await keep(`✅ <b>${escapeHtml(vacancy.title)}</b>\n\n${escapeHtml(letter)}`)
|
|
||||||
|
|
||||||
if (letter) {
|
if (letter) {
|
||||||
|
await keep(`✅ <b>${escapeHtml(vacancy.title)}</b>\n\n${escapeHtml(letter)}`)
|
||||||
const letterInput = await page.$('[data-qa="vacancy-response-popup-form-letter-input"]')
|
const letterInput = await page.$('[data-qa="vacancy-response-popup-form-letter-input"]')
|
||||||
|
|
||||||
await letterInput?.click()
|
await letterInput?.click()
|
||||||
await letterInput?.fill(letter)
|
await letterInput?.fill(letter)
|
||||||
await page.pause()
|
await page.pause()
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
await keep(`Письмо не сгенерировано, ошибка`)
|
||||||
|
}
|
||||||
|
|
||||||
|
await page.waitForTimeout(randomDelay())
|
||||||
|
|
||||||
const submitBtn = await page.$('[data-qa="vacancy-response-submit-popup"]')// vacancy-response-popup-submit
|
const submitBtn = await page.$('[data-qa="vacancy-response-submit-popup"]')// vacancy-response-popup-submit
|
||||||
if (submitBtn) {
|
if (submitBtn) {
|
||||||
@@ -303,6 +334,8 @@ export async function applyToJobs(
|
|||||||
const errMsg = 'Not found submit button'
|
const errMsg = 'Not found submit button'
|
||||||
console.log(errMsg)
|
console.log(errMsg)
|
||||||
results.errors.push({ ...ref, message: errMsg })
|
results.errors.push({ ...ref, message: errMsg })
|
||||||
|
// results.skipped.push(vacancy)
|
||||||
|
continue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@@ -310,18 +343,32 @@ export async function applyToJobs(
|
|||||||
|
|
||||||
const letter = await letterPromise
|
const letter = await letterPromise
|
||||||
console.log('letter: ', letter)
|
console.log('letter: ', letter)
|
||||||
await keep(`✅ <b>${escapeHtml(vacancy.title)}</b>\n\n${escapeHtml(letter)}`)
|
|
||||||
|
|
||||||
if (letter) {
|
if (letter) {
|
||||||
|
await keep(`✅ <b>${escapeHtml(vacancy.title)}</b>\n\n${escapeHtml(letter)}`)
|
||||||
const letterInput = await page.$('[data-qa="textarea-native-wrapper"] textarea')
|
const letterInput = await page.$('[data-qa="textarea-native-wrapper"] textarea')
|
||||||
?? await page.$('[data-qa="vacancy-response-popup-form-letter-input"]')
|
?? await page.$('[data-qa="vacancy-response-popup-form-letter-input"]')
|
||||||
await letterInput?.click()
|
await letterInput?.click()
|
||||||
await letterInput?.fill(letter)
|
await letterInput?.fill(letter)
|
||||||
await page.pause()
|
await page.pause()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
await page.waitForTimeout(randomDelay())
|
||||||
|
|
||||||
|
const submitBtn = await page.$('[data-qa="vacancy-response-letter-submit"]') ?? await page.$('[data-qa="vacancy-response-submit-popup"]')// vacancy-response-popup-submit
|
||||||
|
if (submitBtn) {
|
||||||
|
await submitBtn.click()
|
||||||
|
await page.waitForTimeout(randomDelay())
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
const errMsg = 'Not found submit button'
|
||||||
|
console.log(errMsg)
|
||||||
|
results.errors.push({ ...ref, message: errMsg })
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
results.applied.push(ref)
|
results.applied.push(ref)
|
||||||
|
appliedCount++
|
||||||
}
|
}
|
||||||
catch (err) {
|
catch (err) {
|
||||||
results.errors.push({ ...ref, message: (err as Error).message })
|
results.errors.push({ ...ref, message: (err as Error).message })
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ export const MAIN_MARKUP = {
|
|||||||
{ text: '📄 Выбрать резюме', callback_data: 'hh_resume_list' },
|
{ text: '📄 Выбрать резюме', callback_data: 'hh_resume_list' },
|
||||||
{ text: '📋 Моё резюме', callback_data: 'hh_my_resume' },
|
{ text: '📋 Моё резюме', callback_data: 'hh_my_resume' },
|
||||||
],
|
],
|
||||||
|
[{ text: '🚫 Проблемные вакансии', callback_data: 'hh_skipped' }],
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user