add onlyRemindBossWithExpectJobType option for autoReminder

This commit is contained in:
geekgeekrun
2025-05-06 06:31:14 +08:00
parent 10cd1cf11e
commit b5c3116c01
8 changed files with 91 additions and 8 deletions

View File

@@ -16,6 +16,7 @@
"geminiApiKey": "",
"rechatContentSource": 1,
"recentMessageQuantityForLlm": 8,
"rechatLlmFallback": 1
"rechatLlmFallback": 1,
"onlyRemindBossWithExpectJobType": true
}
}

View File

@@ -39,6 +39,7 @@
"diff": "^7.0.0",
"electron-updater": "^6.1.7",
"minimist": "^1.2.8",
"mitt": "^3.0.1",
"node-machine-id": "^1.1.12",
"pinia": "^3.0.2",
"puppeteer": "20.1.0",

View File

@@ -510,16 +510,15 @@ export default function initIpc() {
ipcMain.handle('save-resume-content', saveResumeHandler)
resumeEditorWindow?.once('closed', () => {
ipcMain.removeHandler('save-resume-content')
ipcMain.removeHandler('fetch-resume-content')
defer.reject(new Error('cancel'))
})
ipcMain.handle('fetch-resume-content', async () => {
const res = (await readConfigFile('resumes.json'))?.[0]
return res?.content ?? null
})
return defer.promise
})
ipcMain.handle('fetch-resume-content', async () => {
const res = (await readConfigFile('resumes.json'))?.[0]
return res?.content ?? null
})
ipcMain.on('no-reply-reminder-prompt-edit', async () => {
const template = await readStorageFile(autoReminderPromptTemplateFileName, { isJson: false })
if (!template) {

View File

@@ -32,6 +32,10 @@ const rechatLlmFallback =
readConfigFile('boss.json').autoReminder?.rechatLlmFallback ??
RECHAT_LLM_FALLBACK.SEND_LOOK_FORWARD_EMOTION
const expectJobTypeRegExpStr = readConfigFile('boss.json').expectJobTypeRegExpStr
const onlyRemindBossWithExpectJobType =
readConfigFile('boss.json').autoReminder?.onlyRemindBossWithExpectJobType ?? !!expectJobTypeRegExpStr
const dbInitPromise = initDb(getPublicDbFilePath())
export const pageMapByName: {
@@ -267,6 +271,24 @@ const mainLoop = async () => {
})
}
await sleepWithRandomDelay(1500)
// check if expect job type match
let isExpectJobTypeMatch = true
if (onlyRemindBossWithExpectJobType) {
const selectedFriendInfo = await pageMapByName.boss?.evaluate(
`document.querySelector('.chat-conversation')?.__vue__?.selectedFriend$`
)
if (!selectedFriendInfo) {
isExpectJobTypeMatch = false
} else {
const jobType = selectedFriendInfo?.positionName
if (!jobType) {
isExpectJobTypeMatch = false
} else {
const regExp = new RegExp(expectJobTypeRegExpStr)
isExpectJobTypeMatch = regExp.test(jobType)
}
}
}
const conversationInfo = await pageMapByName.boss?.evaluate(
`document.querySelector('.chat-conversation .chat-im.chat-editor')?.__vue__?.conversation$`
)
@@ -280,6 +302,7 @@ const mainLoop = async () => {
const lastGeekMessageSendTime = historyMessageList.findLast((it) => it.isSelf)?.time ?? 0
if (
isExpectJobTypeMatch &&
historyMessageList[historyMessageList.length - 1].isSelf &&
historyMessageList[historyMessageList.length - 1].status === MsgStatus.HAS_READ &&
((conversationInfo &&

View File

@@ -133,7 +133,7 @@
</el-form-item>
<div mb10px font-size-12px flex flex-justify-center></div>
<el-form-item mb0 prop="expectJobTypeRegExpStr">
<div font-size-12px>职位类型正则不区分大小写</div>
<div font-size-12px>职位类型正则推荐填写不区分大小写</div>
<el-input
v-model="formContent.expectJobTypeRegExpStr"
@blur="
@@ -323,6 +323,7 @@ import defaultTargetCompanyListConf from '@geekgeekrun/geek-auto-start-chat-with
import { ArrowDown } from '@element-plus/icons-vue'
import { MarkAsNotSuitOp } from '@geekgeekrun/sqlite-plugin/src/enums'
import { debounce } from 'lodash-es'
import mittBus from '../../utils/mitt'
const router = useRouter()
@@ -470,6 +471,7 @@ const handleSubmit = async () => {
return
}
await electron.ipcRenderer.invoke('save-config-file-from-ui', JSON.stringify(formContent.value))
mittBus.emit('auto-start-chat-with-boss-config-saved')
router.replace({
path: '/geekAutoStartChatWithBoss/prepareRun',
query: { flow: 'geek-auto-start-chat-with-boss' }
@@ -494,6 +496,7 @@ const handleSave = async () => {
return
}
await electron.ipcRenderer.invoke('save-config-file-from-ui', JSON.stringify(formContent.value))
mittBus.emit('auto-start-chat-with-boss-config-saved')
ElMessage.success('配置保存成功')
gtagRenderer('config_saved')
}

View File

@@ -11,6 +11,30 @@
>编辑Cookie</el-button
>
</el-form-item>
<el-form-item>
<div>
<el-checkbox v-if="!expectJobTypeRegExpStr?.trim()" :model-value="false" disabled>
发送提醒消息前先按照Boss炸弹-职位类型正则校验正在与Boss沟通的岗位是否满足期望校验通过后再提醒
</el-checkbox>
<template v-else>
<el-checkbox v-model="formContent.autoReminder.onlyRemindBossWithExpectJobType">
发送提醒消息前先按照Boss炸弹-职位类型正则校验正在与Boss沟通的岗位是否满足期望校验通过后再提醒
</el-checkbox>
<div ml1.5em color-gray>
<div>当前职位类型正则{{ expectJobTypeRegExpStr?.trim() }}</div>
<template
v-if="
formContent.autoReminder.rechatContentSource ===
RECHAT_CONTENT_SOURCE.GEMINI_WITH_CHAT_CONTEXT
"
>
<div>当前简历中填写的期望职位:{{ resumeContent?.expectJob ?? '-' }}</div>
<div color-orange>请确保上方二者信息匹配</div>
</template>
</div>
</template>
</div>
</el-form-item>
<el-form-item class="mb0" label="跟进话术 - 当发现已读不回的Boss时将要向Boss发出">
<el-radio-group v-model="formContent.autoReminder.rechatContentSource">
<div>
@@ -184,6 +208,7 @@ import {
RECHAT_LLM_FALLBACK
} from '../../../../common/enums/auto-start-chat'
import { gtagRenderer } from '@renderer/utils/gtag'
import mittBus from '../../utils/mitt'
const router = useRouter()
const formContent = ref({
@@ -192,7 +217,8 @@ const formContent = ref({
rechatLimitDay: 21,
rechatContentSource: 1,
recentMessageQuantityForLlm: 8,
rechatLlmFallback: RECHAT_LLM_FALLBACK.SEND_LOOK_FORWARD_EMOTION
rechatLlmFallback: RECHAT_LLM_FALLBACK.SEND_LOOK_FORWARD_EMOTION,
onlyRemindBossWithExpectJobType: true
}
})
@@ -224,10 +250,32 @@ electron.ipcRenderer.invoke('fetch-config-file-content').then((res) => {
? 8
: parseInt(conf.recentMessageQuantityForLlm)
: 8
conf.onlyRemindBossWithExpectJobType = conf.onlyRemindBossWithExpectJobType ?? true
conf.rechatLlmFallback = conf.rechatLlmFallback ?? RECHAT_LLM_FALLBACK.SEND_LOOK_FORWARD_EMOTION
formContent.value.autoReminder = conf
})
const expectJobTypeRegExpStr = ref('')
async function fetchExpectJobTypeRegExpStr() {
await electron.ipcRenderer.invoke('fetch-config-file-content').then((res) => {
expectJobTypeRegExpStr.value = res.config['boss.json']?.expectJobTypeRegExpStr
})
}
fetchExpectJobTypeRegExpStr()
mittBus.on('auto-start-chat-with-boss-config-saved', fetchExpectJobTypeRegExpStr)
onUnmounted(() => {
mittBus.off('auto-start-chat-with-boss-config-saved', fetchExpectJobTypeRegExpStr)
})
const resumeContent = ref(null)
async function fetchResumeContent() {
await electron.ipcRenderer.invoke('fetch-resume-content').then((res) => {
resumeContent.value = res
})
}
fetchResumeContent()
const formRules = {
throttleIntervalMinutes: {
validator(_, value, cb) {
@@ -274,6 +322,7 @@ async function checkIsCanRun() {
gtagRenderer('invalid_rc_dialog_click_confirm')
try {
await electron.ipcRenderer.invoke('resume-edit')
await fetchResumeContent()
} catch (err) {
console.log(err)
}
@@ -449,6 +498,7 @@ const handleClickEditResume = async () => {
gtagRenderer('edit_resume_clicked')
try {
await electron.ipcRenderer.invoke('resume-edit')
await fetchResumeContent()
} catch (err) {
console.log(err)
}

View File

@@ -0,0 +1,3 @@
import mitt from 'mitt'
const mittBus = mitt()
export default mittBus

3
pnpm-lock.yaml generated
View File

@@ -132,6 +132,9 @@ importers:
minimist:
specifier: ^1.2.8
version: 1.2.8
mitt:
specifier: ^3.0.1
version: 3.0.1
node-machine-id:
specifier: ^1.1.12
version: 1.1.12