From 7b10e97fa84a69bff5cf58ce662ba45e8cac4977 Mon Sep 17 00:00:00 2001 From: geekgeekrun Date: Sun, 13 Jul 2025 18:40:59 +0800 Subject: [PATCH] collect jobSource when manual startup chat running; add jobSource in gtag both auto or manual --- .../constant.mjs | 6 +- .../geek-auto-start-chat-with-boss/index.mjs | 11 ++-- .../src/main/flow/LAUNCH_BOSS_SITE/index.ts | 64 +++++++++++++++++-- packages/ui/src/main/utils/gtag/GtagPlugin.ts | 27 ++++---- 4 files changed, 85 insertions(+), 23 deletions(-) diff --git a/packages/geek-auto-start-chat-with-boss/constant.mjs b/packages/geek-auto-start-chat-with-boss/constant.mjs index 0e1662f..f7e54d6 100644 --- a/packages/geek-auto-start-chat-with-boss/constant.mjs +++ b/packages/geek-auto-start-chat-with-boss/constant.mjs @@ -1,3 +1,7 @@ export const activeDescList = [ '', "半年前活跃","近半年活跃","5月内活跃","4月内活跃","3月内活跃","2月内活跃","本月活跃","2周内活跃","本周活跃","3日内活跃","昨日活跃","今日活跃","刚刚活跃" -] \ No newline at end of file +] + +export const RECOMMEND_JOB_ENTRY_SELECTOR = `.c-expect-select a[ka="jobs_recommend_tab_click"]` +export const USER_SET_EXPECT_JOB_ENTRIES_SELECTOR = `.c-expect-select .expect-list .expect-item` +export const SEARCH_BOX_SELECTOR = `.c-search-input .search-input-box` \ No newline at end of file diff --git a/packages/geek-auto-start-chat-with-boss/index.mjs b/packages/geek-auto-start-chat-with-boss/index.mjs index ad6341a..4324203 100644 --- a/packages/geek-auto-start-chat-with-boss/index.mjs +++ b/packages/geek-auto-start-chat-with-boss/index.mjs @@ -21,7 +21,12 @@ import { default as jobFilterConditions } from './internal-config/job-filter-con import { default as rawIndustryFilterExemption } from './internal-config/job-filter-industry-filter-exemption-20241002.json' import { ChatStartupFrom } from '@geekgeekrun/sqlite-plugin/dist/entity/ChatStartupLog' import { MarkAsNotSuitReason, MarkAsNotSuitOp, StrategyScopeOptionWhenMarkJobNotMatch, SalaryCalculateWay, JobDetailRegExpMatchLogic, JobSource } from '@geekgeekrun/sqlite-plugin/dist/enums' -import { activeDescList } from './constant.mjs' +import { + activeDescList, + RECOMMEND_JOB_ENTRY_SELECTOR, + USER_SET_EXPECT_JOB_ENTRIES_SELECTOR, + SEARCH_BOX_SELECTOR, +} from './constant.mjs' import { parseSalary } from "@geekgeekrun/sqlite-plugin/dist/utils/parser" const jobFilterConditionsMapByCode = {} Object.values(jobFilterConditions).forEach(arr => { @@ -534,10 +539,6 @@ async function toRecommendPage (hooks) { } } - const RECOMMEND_JOB_ENTRY_SELECTOR = `.c-expect-select a[ka="jobs_recommend_tab_click"]` - const USER_SET_EXPECT_JOB_ENTRIES_SELECTOR = `.c-expect-select .expect-list .expect-item` - const SEARCH_BOX_SELECTOR = `.c-search-input .search-input-box` - const computedSourceList = [] for (const source of normalizedJobSource) { switch (source.type) { diff --git a/packages/ui/src/main/flow/LAUNCH_BOSS_SITE/index.ts b/packages/ui/src/main/flow/LAUNCH_BOSS_SITE/index.ts index 38895f2..eed4c86 100644 --- a/packages/ui/src/main/flow/LAUNCH_BOSS_SITE/index.ts +++ b/packages/ui/src/main/flow/LAUNCH_BOSS_SITE/index.ts @@ -4,6 +4,10 @@ import { readStorageFile, writeStorageFile } from '@geekgeekrun/geek-auto-start-chat-with-boss/runtime-file-utils.mjs' +import { + RECOMMEND_JOB_ENTRY_SELECTOR, + USER_SET_EXPECT_JOB_ENTRIES_SELECTOR, +} from '@geekgeekrun/geek-auto-start-chat-with-boss/constant.mjs' import { setDomainLocalStorage } from '@geekgeekrun/utils/puppeteer/local-storage.mjs' import { saveJobInfoFromRecommendPage, @@ -13,7 +17,7 @@ import { } from '@geekgeekrun/sqlite-plugin/dist/handlers' import { initDb } from '@geekgeekrun/sqlite-plugin' import { getPublicDbFilePath } from '@geekgeekrun/geek-auto-start-chat-with-boss/runtime-file-utils.mjs' -import { MarkAsNotSuitReason } from '@geekgeekrun/sqlite-plugin/dist/enums' +import { MarkAsNotSuitReason, JobSource } from '@geekgeekrun/sqlite-plugin/dist/enums' import fs from 'node:fs' import { Target } from 'puppeteer' @@ -38,6 +42,49 @@ const attachRequestsListener = async (target: Target) => { if (!page) { return } + async function getCurrentJobSource() { + const methodMap = { + async recommend() { + return await page.evaluate( + ({ RECOMMEND_JOB_ENTRY_SELECTOR }) => { + return document.querySelector(RECOMMEND_JOB_ENTRY_SELECTOR).classList.contains('active') + }, + { + RECOMMEND_JOB_ENTRY_SELECTOR + } + ) + }, + async expect() { + return await page.evaluate( + ({ USER_SET_EXPECT_JOB_ENTRIES_SELECTOR }) => { + return [...document.querySelectorAll(USER_SET_EXPECT_JOB_ENTRIES_SELECTOR)].some((el) => + el.classList.contains('active') + ) + }, + { + USER_SET_EXPECT_JOB_ENTRIES_SELECTOR + } + ) + }, + async search() { + const elHandle = await page.$(`.page-jobs-main`) + const currentKeyWord = await elHandle?.evaluate((el) => { + return el?.__vue__?.formData?.query + }) + return !!currentKeyWord + } + } + for (const [type, func] of Object.entries(methodMap)) { + try { + if (await func()) { + return type + } + } catch (err) { + console.error('encounter error when get job source') + } + } + return null + } page.on('response', async (response) => { if (response.url().startsWith('https://www.zhipin.com/wapi/zpgeek/job/detail.json')) { @@ -81,7 +128,7 @@ const attachRequestsListener = async (target: Target) => { const reasonCodeToTextMap = await readStorageFile( 'job-not-suit-reason-code-to-text-cache.json' ) - + const jobSource = await getCurrentJobSource() const markDetail = { markFrom: ChatStartupFrom.ManuallyFromRecommendList, extInfo: { @@ -90,12 +137,14 @@ const attachRequestsListener = async (target: Target) => { text: reasonCodeToTextMap[chosenCode] } }, - markReason: MarkAsNotSuitReason.USER_MANUAL_OPERATION_WITH_UNKNOWN_REASON + markReason: MarkAsNotSuitReason.USER_MANUAL_OPERATION_WITH_UNKNOWN_REASON, + jobSource: JobSource[jobSource] } gtag('job_marked_as_not_suit', { markFrom: markDetail.markFrom, bossActiveTimeDesc: currentJobData?.bossInfo?.activeTimeDesc, - encryptJobId: currentJobData?.jobInfo?.encryptId + encryptJobId: currentJobData?.jobInfo?.encryptId, + jobSource: JobSource[jobSource] }) if (reasonCodeToTextMap[chosenCode]?.includes('活跃度低')) { markDetail.markReason = MarkAsNotSuitReason.BOSS_INACTIVE @@ -131,9 +180,11 @@ const attachRequestsListener = async (target: Target) => { const currentUserInfo = await page.evaluate( 'document.querySelector(".job-detail-box").__vue__.$store.state.userInfo' ) + const jobSource = await getCurrentJobSource() gtag('new_chat_startup', { chatStartupFrom: ChatStartupFrom.ManuallyFromRecommendList, - encryptJobId: currentJobData?.jobInfo?.encryptId + encryptJobId: currentJobData?.jobInfo?.encryptId, + jobSource: JobSource[jobSource] }) await saveChatStartupRecord( await dbInitPromise, @@ -142,7 +193,8 @@ const attachRequestsListener = async (target: Target) => { encryptUserId: currentUserInfo.encryptUserId }, { - chatStartupFrom: ChatStartupFrom.ManuallyFromRecommendList + chatStartupFrom: ChatStartupFrom.ManuallyFromRecommendList, + jobSource: JobSource[jobSource] } ) } else if ( diff --git a/packages/ui/src/main/utils/gtag/GtagPlugin.ts b/packages/ui/src/main/utils/gtag/GtagPlugin.ts index a0ab201..de3c28e 100644 --- a/packages/ui/src/main/utils/gtag/GtagPlugin.ts +++ b/packages/ui/src/main/utils/gtag/GtagPlugin.ts @@ -2,21 +2,26 @@ import gtag from '.' export default class GtagPlugin { apply(hooks) { - hooks.newChatStartup.tap('GtagPlugin', (jobData, { chatStartupFrom }) => { + hooks.newChatStartup.tap('GtagPlugin', (jobData, { chatStartupFrom, jobSource }) => { gtag('new_chat_startup', { chatStartupFrom, - encryptJobId: jobData.jobInfo.encryptId - }) - }) - hooks.jobMarkedAsNotSuit.tap('GtagPlugin', (jobData, { markFrom, markOp, markReason }) => { - gtag('job_marked_as_not_suit', { - markFrom, - markOp, - markReason, - bossActiveTimeDesc: jobData.bossInfo.activeTimeDesc, - encryptJobId: jobData.jobInfo.encryptId + encryptJobId: jobData.jobInfo.encryptId, + jobSource }) }) + hooks.jobMarkedAsNotSuit.tap( + 'GtagPlugin', + (jobData, { markFrom, markOp, markReason, jobSource }) => { + gtag('job_marked_as_not_suit', { + markFrom, + markOp, + markReason, + bossActiveTimeDesc: jobData.bossInfo.activeTimeDesc, + encryptJobId: jobData.jobInfo.encryptId, + jobSource + }) + } + ) hooks.noPositionFoundForCurrentJob.tap('GtagPlugin', () => { gtag('no_position_found_for_current_job') })