consume add block company config in ghosting reminder and auto start chat

This commit is contained in:
geekgeekrun
2026-02-10 06:09:21 +08:00
parent c0326605a9
commit a1f8b6c6f0
3 changed files with 118 additions and 11 deletions

View File

@@ -247,6 +247,19 @@ const recommendJobPageUrl = `https://www.zhipin.com/web/geek/jobs`
const expectCompanySet = new Set(targetCompanyList)
const enableCompanyAllowList = Boolean(expectCompanySet.size)
const blockCompanyNameRegExpStr = readConfigFile('boss.json').blockCompanyNameRegExpStr ?? ''
const blockCompanyNameRegExp = (() => {
if (!blockCompanyNameRegExpStr?.trim()) {
return null
}
try {
return new RegExp(blockCompanyNameRegExpStr, 'im')
}
catch {
return null
}
})()
const blockCompanyNameRegMatchStrategy = readConfigFile('boss.json').blockCompanyNameRegMatchStrategy ?? MarkAsNotSuitOp.NO_OP
/**
* @type { import('puppeteer').Browser }
@@ -298,6 +311,18 @@ async function markJobAsNotSuitInRecommendPage (reasonCode) {
let isOptionChosen = false
if (chooseReasonDialogProxy) {
switch (reasonCode) {
case MarkAsNotSuitReason.COMPANY_NAME_NOT_SUIT: {
const opProxy = (await chooseReasonDialogProxy.$(`.zp-type-item[title*="公司"]`))
?? (await chooseReasonDialogProxy.$(`.zp-type-item[title="面试过/入职过"]`))
?? (await chooseReasonDialogProxy.$(`.zp-type-item[title="重复推荐"]`))
?? (await chooseReasonDialogProxy.$(`.zp-type-item[title*="距离"]`))
?? (await chooseReasonDialogProxy.$(`.zp-type-item[title*="薪资"]`))
if (opProxy) {
await opProxy.click()
isOptionChosen = true
}
break
}
case MarkAsNotSuitReason.BOSS_INACTIVE: {
const opProxy = (await chooseReasonDialogProxy.$(`.zp-type-item[title="BOSS活跃度低"]`))
?? (await chooseReasonDialogProxy.$(`.zp-type-item[title="职位停招/招满"]`))
@@ -312,7 +337,7 @@ async function markJobAsNotSuitInRecommendPage (reasonCode) {
case MarkAsNotSuitReason.JOB_WORK_EXP_NOT_SUIT:
case MarkAsNotSuitReason.JOB_CITY_NOT_SUIT: {
const opProxy = (await chooseReasonDialogProxy.$(`.zp-type-item[title$="城市"]`))
?? (await chooseReasonDialogProxy.$(`.zp-type-item[title*="距离"]`))
?? (await chooseReasonDialogProxy.$(`.zp-type-item[title*="距离"]`))
?? (await chooseReasonDialogProxy.$(`.zp-type-item[title*="公司"]`))
?? (await chooseReasonDialogProxy.$(`.zp-type-item[title="面试过/入职过"]`))
?? (await chooseReasonDialogProxy.$(`.zp-type-item[title="重复推荐"]`))
@@ -325,7 +350,7 @@ async function markJobAsNotSuitInRecommendPage (reasonCode) {
case MarkAsNotSuitReason.JOB_SALARY_NOT_SUIT: {
const opProxy = (await chooseReasonDialogProxy.$(`.zp-type-item[title*="薪资"]`))
?? (await chooseReasonDialogProxy.$(`.zp-type-item[title$="城市"]`))
?? (await chooseReasonDialogProxy.$(`.zp-type-item[title*="距离"]`))
?? (await chooseReasonDialogProxy.$(`.zp-type-item[title*="距离"]`))
?? (await chooseReasonDialogProxy.$(`.zp-type-item[title*="公司"]`))
?? (await chooseReasonDialogProxy.$(`.zp-type-item[title="面试过/入职过"]`))
?? (await chooseReasonDialogProxy.$(`.zp-type-item[title="重复推荐"]`))
@@ -984,6 +1009,14 @@ async function toRecommendPage (hooks) {
].includes(expectSalaryNotMatchStrategy) &&
strategyScopeOptionWhenMarkSalaryNotMatch === StrategyScopeOptionWhenMarkJobNotMatch.ALL_JOB
) ? !checkIfSalarySuit(it.salaryDesc) : false
) || (
// enter job detail to mark as not suit for company name filter
!!blockCompanyNameRegExp &&
blockCompanyNameRegExp.test(it.brandName?.toLowerCase?.() ?? '') &&
[
MarkAsNotSuitOp.MARK_AS_NOT_SUIT_ON_BOSS,
MarkAsNotSuitOp.MARK_AS_NOT_SUIT_ON_LOCAL
].includes(blockCompanyNameRegMatchStrategy)
)
)
})
@@ -1077,6 +1110,47 @@ async function toRecommendPage (hooks) {
//#region collect not suit reasons
const notSuitReasonIdToStrategyMap = {}
const notSuitConditionHandleMap = {
async companyName() {
blockJobNotSuit.add(targetJobData.jobInfo.encryptId)
if (blockCompanyNameRegMatchStrategy === MarkAsNotSuitOp.MARK_AS_NOT_SUIT_ON_LOCAL && !await page.$('.job-detail-box .job-detail-operate .not-suitable')) {
try {
await hooks.jobMarkedAsNotSuit.promise(
targetJobData,
{
markFrom: ChatStartupFrom.AutoFromRecommendList,
markReason: MarkAsNotSuitReason.COMPANY_NAME_NOT_SUIT,
extInfo: null,
markOp: MarkAsNotSuitOp.MARK_AS_NOT_SUIT_ON_LOCAL,
jobSource: JobSource[computedSourceList[currentSourceIndex]?.type]
}
)
} catch {
}
}
else if (blockCompanyNameRegMatchStrategy === MarkAsNotSuitOp.MARK_AS_NOT_SUIT_ON_BOSS) {
try {
await waitForSageTimeOrJustContinue({
tag: 'beforeJobNotSuitMarked',
hooks
})
const { chosenReasonInUi } = await markJobAsNotSuitInRecommendPage(MarkAsNotSuitReason.COMPANY_NAME_NOT_SUIT)
await hooks.jobMarkedAsNotSuit.promise(
targetJobData,
{
markFrom: ChatStartupFrom.AutoFromRecommendList,
markReason: MarkAsNotSuitReason.COMPANY_NAME_NOT_SUIT,
extInfo: {
chosenReasonInUi
},
markOp: MarkAsNotSuitOp.MARK_AS_NOT_SUIT_ON_BOSS,
jobSource: JobSource[computedSourceList[currentSourceIndex]?.type]
}
)
} catch(err) {
console.log(`mark boss inactive failed`, err)
}
}
},
async active() {
blockBossNotActive.add(targetJobData.jobInfo.encryptUserId)
if (jobNotActiveStrategy === MarkAsNotSuitOp.MARK_AS_NOT_SUIT_ON_LOCAL || !await page.$('.job-detail-box .job-detail-operate .not-suitable')) {
@@ -1289,6 +1363,11 @@ async function toRecommendPage (hooks) {
}
}
if (
!!blockCompanyNameRegExp && blockCompanyNameRegExp.test(selectedJobData.brandName ?? '')
) {
notSuitReasonIdToStrategyMap.companyName = blockCompanyNameRegMatchStrategy
}
//#region
// null
// 刚刚活跃 // 今日活跃 // 昨日活跃 // 3日内活跃 // 本周活跃 // 2周内活跃

View File

@@ -6,6 +6,7 @@ export enum MarkAsNotSuitReason {
JOB_CITY_NOT_SUIT = 4,
JOB_WORK_EXP_NOT_SUIT = 5,
JOB_SALARY_NOT_SUIT = 6,
COMPANY_NAME_NOT_SUIT = 7,
}
export enum MarkAsNotSuitOp {

View File

@@ -60,7 +60,23 @@ const rechatLlmFallback =
const expectJobTypeRegExpStr = readConfigFile('boss.json').expectJobTypeRegExpStr
const onlyRemindBossWithExpectJobType =
readConfigFile('boss.json').autoReminder?.onlyRemindBossWithExpectJobType ?? !!expectJobTypeRegExpStr
readConfigFile('boss.json').autoReminder?.onlyRemindBossWithExpectJobType ??
!!expectJobTypeRegExpStr
const blockCompanyNameRegExpStr = readConfigFile('boss.json').blockCompanyNameRegExpStr ?? ''
const blockCompanyNameRegExp = (() => {
if (!blockCompanyNameRegExpStr?.trim()) {
return null
}
try {
return new RegExp(blockCompanyNameRegExpStr, 'im')
} catch {
return null
}
})()
const onlyRemindBossWithoutBlockCompanyName =
readConfigFile('boss.json').autoReminder?.onlyRemindBossWithoutBlockCompanyName ??
!!blockCompanyNameRegExp
const dbInitPromise = initDb(getPublicDbFilePath())
@@ -156,7 +172,8 @@ async function saveCurrentChatRecord(page) {
async function checkJobIsClosed() {
const encryptJobId = await pageMapByName.boss!.evaluate(() => {
return document.querySelector('.chat-conversation .chat-im.chat-editor')?.__vue__?.conversation$.encryptJobId
return document.querySelector('.chat-conversation .chat-im.chat-editor')?.__vue__?.conversation$
.encryptJobId
})
if (!encryptJobId) {
return false
@@ -431,6 +448,9 @@ const mainLoop = async () => {
const toCheckItemAtIndex = friendListData.findIndex((it, index) => {
return (
index >= cursorToContinueFind &&
(onlyRemindBossWithoutBlockCompanyName && blockCompanyNameRegExp
? !blockCompanyNameRegExp.test(it.brandName)
: true) &&
(rechatLimitDay && it.updateTime
? +new Date() - it.updateTime < rechatLimitDay * 24 * 60 * 60 * 1000
: true) &&
@@ -605,11 +625,14 @@ export async function runEntry() {
})
initPublicIpc()
await connectToDaemon()
await sendToDaemon({
type: 'ping'
}, {
needCallback: true
})
await sendToDaemon(
{
type: 'ping'
},
{
needCallback: true
}
)
sendToDaemon({
type: 'worker-to-gui-message',
data: {
@@ -690,7 +713,11 @@ export async function runEntry() {
process.exit(AUTO_CHAT_ERROR_EXIT_CODE.ACCESS_IS_DENIED)
break
}
if (err.message.includes(`PUPPETEER_IS_NOT_EXECUTABLE`) || err.message.includes(`Could not find Chrome`) || err.message.includes(`no executable was found`)) {
if (
err.message.includes(`PUPPETEER_IS_NOT_EXECUTABLE`) ||
err.message.includes(`Could not find Chrome`) ||
err.message.includes(`no executable was found`)
) {
process.exit(AUTO_CHAT_ERROR_EXIT_CODE.PUPPETEER_IS_NOT_EXECUTABLE)
break
}
@@ -703,7 +730,7 @@ export async function runEntry() {
buttons: ['退出']
})
process.exit(AUTO_CHAT_ERROR_EXIT_CODE.LLM_UNAVAILABLE)
break;
break
}
}
} finally {