mirror of
https://github.com/geekgeekrun/geekgeekrun.git
synced 2026-09-08 00:47:15 +08:00
consume add block company config in ghosting reminder and auto start chat
This commit is contained in:
@@ -247,6 +247,19 @@ const recommendJobPageUrl = `https://www.zhipin.com/web/geek/jobs`
|
|||||||
|
|
||||||
const expectCompanySet = new Set(targetCompanyList)
|
const expectCompanySet = new Set(targetCompanyList)
|
||||||
const enableCompanyAllowList = Boolean(expectCompanySet.size)
|
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 }
|
* @type { import('puppeteer').Browser }
|
||||||
@@ -298,6 +311,18 @@ async function markJobAsNotSuitInRecommendPage (reasonCode) {
|
|||||||
let isOptionChosen = false
|
let isOptionChosen = false
|
||||||
if (chooseReasonDialogProxy) {
|
if (chooseReasonDialogProxy) {
|
||||||
switch (reasonCode) {
|
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: {
|
case MarkAsNotSuitReason.BOSS_INACTIVE: {
|
||||||
const opProxy = (await chooseReasonDialogProxy.$(`.zp-type-item[title="BOSS活跃度低"]`))
|
const opProxy = (await chooseReasonDialogProxy.$(`.zp-type-item[title="BOSS活跃度低"]`))
|
||||||
?? (await chooseReasonDialogProxy.$(`.zp-type-item[title="职位停招/招满"]`))
|
?? (await chooseReasonDialogProxy.$(`.zp-type-item[title="职位停招/招满"]`))
|
||||||
@@ -312,7 +337,7 @@ async function markJobAsNotSuitInRecommendPage (reasonCode) {
|
|||||||
case MarkAsNotSuitReason.JOB_WORK_EXP_NOT_SUIT:
|
case MarkAsNotSuitReason.JOB_WORK_EXP_NOT_SUIT:
|
||||||
case MarkAsNotSuitReason.JOB_CITY_NOT_SUIT: {
|
case MarkAsNotSuitReason.JOB_CITY_NOT_SUIT: {
|
||||||
const opProxy = (await chooseReasonDialogProxy.$(`.zp-type-item[title$="城市"]`))
|
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="面试过/入职过"]`))
|
||||||
?? (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: {
|
case MarkAsNotSuitReason.JOB_SALARY_NOT_SUIT: {
|
||||||
const opProxy = (await chooseReasonDialogProxy.$(`.zp-type-item[title*="薪资"]`))
|
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*="公司"]`))
|
||||||
?? (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) &&
|
].includes(expectSalaryNotMatchStrategy) &&
|
||||||
strategyScopeOptionWhenMarkSalaryNotMatch === StrategyScopeOptionWhenMarkJobNotMatch.ALL_JOB
|
strategyScopeOptionWhenMarkSalaryNotMatch === StrategyScopeOptionWhenMarkJobNotMatch.ALL_JOB
|
||||||
) ? !checkIfSalarySuit(it.salaryDesc) : false
|
) ? !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
|
//#region collect not suit reasons
|
||||||
const notSuitReasonIdToStrategyMap = {}
|
const notSuitReasonIdToStrategyMap = {}
|
||||||
const notSuitConditionHandleMap = {
|
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() {
|
async active() {
|
||||||
blockBossNotActive.add(targetJobData.jobInfo.encryptUserId)
|
blockBossNotActive.add(targetJobData.jobInfo.encryptUserId)
|
||||||
if (jobNotActiveStrategy === MarkAsNotSuitOp.MARK_AS_NOT_SUIT_ON_LOCAL || !await page.$('.job-detail-box .job-detail-operate .not-suitable')) {
|
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
|
//#region
|
||||||
// null
|
// null
|
||||||
// 刚刚活跃 // 今日活跃 // 昨日活跃 // 3日内活跃 // 本周活跃 // 2周内活跃
|
// 刚刚活跃 // 今日活跃 // 昨日活跃 // 3日内活跃 // 本周活跃 // 2周内活跃
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ export enum MarkAsNotSuitReason {
|
|||||||
JOB_CITY_NOT_SUIT = 4,
|
JOB_CITY_NOT_SUIT = 4,
|
||||||
JOB_WORK_EXP_NOT_SUIT = 5,
|
JOB_WORK_EXP_NOT_SUIT = 5,
|
||||||
JOB_SALARY_NOT_SUIT = 6,
|
JOB_SALARY_NOT_SUIT = 6,
|
||||||
|
COMPANY_NAME_NOT_SUIT = 7,
|
||||||
}
|
}
|
||||||
|
|
||||||
export enum MarkAsNotSuitOp {
|
export enum MarkAsNotSuitOp {
|
||||||
|
|||||||
@@ -60,7 +60,23 @@ const rechatLlmFallback =
|
|||||||
|
|
||||||
const expectJobTypeRegExpStr = readConfigFile('boss.json').expectJobTypeRegExpStr
|
const expectJobTypeRegExpStr = readConfigFile('boss.json').expectJobTypeRegExpStr
|
||||||
const onlyRemindBossWithExpectJobType =
|
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())
|
const dbInitPromise = initDb(getPublicDbFilePath())
|
||||||
|
|
||||||
@@ -156,7 +172,8 @@ async function saveCurrentChatRecord(page) {
|
|||||||
|
|
||||||
async function checkJobIsClosed() {
|
async function checkJobIsClosed() {
|
||||||
const encryptJobId = await pageMapByName.boss!.evaluate(() => {
|
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) {
|
if (!encryptJobId) {
|
||||||
return false
|
return false
|
||||||
@@ -431,6 +448,9 @@ const mainLoop = async () => {
|
|||||||
const toCheckItemAtIndex = friendListData.findIndex((it, index) => {
|
const toCheckItemAtIndex = friendListData.findIndex((it, index) => {
|
||||||
return (
|
return (
|
||||||
index >= cursorToContinueFind &&
|
index >= cursorToContinueFind &&
|
||||||
|
(onlyRemindBossWithoutBlockCompanyName && blockCompanyNameRegExp
|
||||||
|
? !blockCompanyNameRegExp.test(it.brandName)
|
||||||
|
: true) &&
|
||||||
(rechatLimitDay && it.updateTime
|
(rechatLimitDay && it.updateTime
|
||||||
? +new Date() - it.updateTime < rechatLimitDay * 24 * 60 * 60 * 1000
|
? +new Date() - it.updateTime < rechatLimitDay * 24 * 60 * 60 * 1000
|
||||||
: true) &&
|
: true) &&
|
||||||
@@ -605,11 +625,14 @@ export async function runEntry() {
|
|||||||
})
|
})
|
||||||
initPublicIpc()
|
initPublicIpc()
|
||||||
await connectToDaemon()
|
await connectToDaemon()
|
||||||
await sendToDaemon({
|
await sendToDaemon(
|
||||||
type: 'ping'
|
{
|
||||||
}, {
|
type: 'ping'
|
||||||
needCallback: true
|
},
|
||||||
})
|
{
|
||||||
|
needCallback: true
|
||||||
|
}
|
||||||
|
)
|
||||||
sendToDaemon({
|
sendToDaemon({
|
||||||
type: 'worker-to-gui-message',
|
type: 'worker-to-gui-message',
|
||||||
data: {
|
data: {
|
||||||
@@ -690,7 +713,11 @@ export async function runEntry() {
|
|||||||
process.exit(AUTO_CHAT_ERROR_EXIT_CODE.ACCESS_IS_DENIED)
|
process.exit(AUTO_CHAT_ERROR_EXIT_CODE.ACCESS_IS_DENIED)
|
||||||
break
|
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)
|
process.exit(AUTO_CHAT_ERROR_EXIT_CODE.PUPPETEER_IS_NOT_EXECUTABLE)
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
@@ -703,7 +730,7 @@ export async function runEntry() {
|
|||||||
buttons: ['退出']
|
buttons: ['退出']
|
||||||
})
|
})
|
||||||
process.exit(AUTO_CHAT_ERROR_EXIT_CODE.LLM_UNAVAILABLE)
|
process.exit(AUTO_CHAT_ERROR_EXIT_CODE.LLM_UNAVAILABLE)
|
||||||
break;
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
|
|||||||
Reference in New Issue
Block a user