enhance ux login flow of auto start chat

This commit is contained in:
geekgeekrun
2026-01-24 04:26:51 +08:00
parent 60dee6f435
commit 204e15b5d8
7 changed files with 117 additions and 51 deletions
@@ -100,9 +100,6 @@ export async function initPuppeteer () {
} }
} }
const bossCookies = readStorageFile('boss-cookies.json')
const bossLocalStorage = readStorageFile('boss-local-storage.json')
const targetCompanyList = readConfigFile('target-company-list.json').filter(it => !!it.trim()); const targetCompanyList = readConfigFile('target-company-list.json').filter(it => !!it.trim());
const combineRecommendJobFilterType = readConfigFile('boss.json').combineRecommendJobFilterType ?? CombineRecommendJobFilterType.ANY_COMBINE const combineRecommendJobFilterType = readConfigFile('boss.json').combineRecommendJobFilterType ?? CombineRecommendJobFilterType.ANY_COMBINE
@@ -1476,7 +1473,9 @@ export async function mainLoop (hooks) {
page = (await browser.pages())[0] page = (await browser.pages())[0]
hooks.pageGotten?.call(page) hooks.pageGotten?.call(page)
//set cookies //set cookies
hooks.cookieWillSet?.call(bossCookies) const bossCookies = readStorageFile('boss-cookies.json')
const bossLocalStorage = readStorageFile('boss-local-storage.json')
await hooks.cookieWillSet?.promise(bossCookies)
for(let i = 0; i < bossCookies.length; i++){ for(let i = 0; i < bossCookies.length; i++){
await page.setCookie(bossCookies[i]); await page.setCookie(bossCookies[i]);
} }
@@ -1,29 +0,0 @@
import { sendToDaemon } from "../flow/OPEN_SETTING_WINDOW/connect-to-daemon"
import minimist from 'minimist'
const runRecordId = minimist(process.argv.slice(2))['run-record-id'] ?? null
export function pushUserInfoValidStatus (userInfoResponse) {
sendToDaemon({
type: 'worker-to-gui-message',
data: {
type: 'prerequisite-step-by-step-checkstep-by-step-check',
step: {
id: 'login-status-check',
status: userInfoResponse.code === 0 ? 'fulfilled' : 'rejected'
},
runRecordId
}
})
}
export class UserResponseInfoPlugin {
apply(hooks) {
hooks.userInfoResponse.tapPromise(
"UserResponseInfoPlugin",
(userInfoResponse) => {
pushUserInfoValidStatus(userInfoResponse)
return Promise.resolve()
}
)
}
}
@@ -0,0 +1,93 @@
import { sendToDaemon } from '../flow/OPEN_SETTING_WINDOW/connect-to-daemon'
import minimist from 'minimist'
import { loginWithCookieAssistant } from './login-with-cookie-assistant'
import { checkCookieListFormat } from '../../common/utils/cookie'
import { sleep } from '@geekgeekrun/utils/sleep.mjs'
import { readStorageFile } from '@geekgeekrun/geek-auto-start-chat-with-boss/runtime-file-utils.mjs'
const runRecordId = minimist(process.argv.slice(2))['run-record-id'] ?? null
export class CookieInvalidHandlePlugin {
apply(hooks) {
hooks.cookieWillSet.tapPromise('CookieInvalidHandlePlugin', async (cookies) => {
let isValid = checkCookieListFormat(cookies)
while (!isValid) {
try {
// popup login dialog, then update login status
await loginWithCookieAssistant()
await sleep(2000)
const newCookies = readStorageFile('boss-cookies.json')
isValid = checkCookieListFormat(newCookies)
if (isValid) {
cookies.length = 0
for (const cookie of newCookies) {
cookies.push(cookie)
}
}
} catch (e) {
if (e?.message === 'USER_CANCELLED_LOGIN') {
sendToDaemon({
type: 'worker-to-gui-message',
data: {
type: 'prerequisite-step-by-step-checkstep-by-step-check',
step: {
id: 'basic-cookie-check',
status: 'rejected'
},
runRecordId
}
})
throw new Error('LOGIN_STATUS_INVALID')
}
}
}
sendToDaemon({
type: 'worker-to-gui-message',
data: {
type: 'prerequisite-step-by-step-checkstep-by-step-check',
step: {
id: 'basic-cookie-check',
status: 'fulfilled'
},
runRecordId
}
})
})
hooks.userInfoResponse.tapPromise('CookieInvalidHandlePlugin', async (userInfoResponse) => {
if (userInfoResponse.code === 0) {
sendToDaemon({
type: 'worker-to-gui-message',
data: {
type: 'prerequisite-step-by-step-checkstep-by-step-check',
step: {
id: 'login-status-check',
status: 'fulfilled'
},
runRecordId
}
})
return
}
try {
// popup login dialog, then update login status
await loginWithCookieAssistant()
} catch (e) {
if (e?.message === 'USER_CANCELLED_LOGIN') {
sendToDaemon({
type: 'worker-to-gui-message',
data: {
type: 'prerequisite-step-by-step-checkstep-by-step-check',
step: {
id: 'login-status-check',
status: 'rejected'
},
runRecordId
}
})
throw new Error('LOGIN_STATUS_INVALID')
}
}
// throw new Error('THROW_FOR_RETRY')
return Promise.reject(new Error('THROW_FOR_RETRY'))
})
}
}
@@ -14,7 +14,7 @@ export async function loginWithCookieAssistant({ windowOption } = {}) {
if (processDone) { if (processDone) {
resolve(true) resolve(true)
} else { } else {
reject(new Error('User cancelled login')) reject(new Error('USER_CANCELLED_LOGIN'))
} }
}) })
}) })
@@ -17,9 +17,15 @@ import GtagPlugin from '../../utils/gtag/GtagPlugin'
import { connectToDaemon, sendToDaemon } from '../OPEN_SETTING_WINDOW/connect-to-daemon' import { connectToDaemon, sendToDaemon } from '../OPEN_SETTING_WINDOW/connect-to-daemon'
// import { PeriodPushCurrentPageScreenshotPlugin } from '../../utils/screenshot' // import { PeriodPushCurrentPageScreenshotPlugin } from '../../utils/screenshot'
import { checkShouldExit } from '../../utils/worker' import { checkShouldExit } from '../../utils/worker'
import { UserResponseInfoPlugin } from '../../features/boss-user-info-response-plugin' import { CookieInvalidHandlePlugin } from '../../features/cookie-invalid-handle-plugin'
import initPublicIpc from '../../utils/initPublicIpc'
const { default: SqlitePlugin } = SqlitePluginModule const { default: SqlitePlugin } = SqlitePluginModule
process.on('SIGTERM', () => {
console.log('收到SIGTERM信号,正在退出')
process.exit(0)
})
const rerunInterval = (() => { const rerunInterval = (() => {
let v = Number(process.env.MAIN_BOSSGEEKGO_RERUN_INTERVAL) let v = Number(process.env.MAIN_BOSSGEEKGO_RERUN_INTERVAL)
if (isNaN(v)) { if (isNaN(v)) {
@@ -36,7 +42,7 @@ const initPlugins = (hooks) => {
new SqlitePlugin(getPublicDbFilePath()).apply(hooks) new SqlitePlugin(getPublicDbFilePath()).apply(hooks)
new GtagPlugin().apply(hooks) new GtagPlugin().apply(hooks)
// new PeriodPushCurrentPageScreenshotPlugin().apply(hooks) // new PeriodPushCurrentPageScreenshotPlugin().apply(hooks)
new UserResponseInfoPlugin().apply(hooks) new CookieInvalidHandlePlugin().apply(hooks)
} }
const runRecordId = minimist(process.argv.slice(2))['run-record-id'] ?? null const runRecordId = minimist(process.argv.slice(2))['run-record-id'] ?? null
@@ -83,7 +89,7 @@ const runAutoChat = async () => {
puppeteerLaunched: new SyncHook(['browser']), puppeteerLaunched: new SyncHook(['browser']),
pageGotten: new SyncHook(['page']), pageGotten: new SyncHook(['page']),
pageLoaded: new SyncHook(), pageLoaded: new SyncHook(),
cookieWillSet: new SyncHook(['cookies']), cookieWillSet: new AsyncSeriesHook(['cookies']),
userInfoResponse: new AsyncSeriesHook(['userInfo']), userInfoResponse: new AsyncSeriesHook(['userInfo']),
mainFlowWillLaunch: new AsyncSeriesHook(['args']), mainFlowWillLaunch: new AsyncSeriesHook(['args']),
jobDetailIsGetFromRecommendList: new AsyncSeriesHook(['userInfo']), jobDetailIsGetFromRecommendList: new AsyncSeriesHook(['userInfo']),
@@ -147,6 +153,11 @@ const runAutoChat = async () => {
} }
export const waitForProcessHandShakeAndRunAutoChat = async () => { export const waitForProcessHandShakeAndRunAutoChat = async () => {
await app.whenReady()
app.on('window-all-closed', (e) => {
e.preventDefault()
})
initPublicIpc()
await connectToDaemon() await connectToDaemon()
await sendToDaemon( await sendToDaemon(
{ {
@@ -2,11 +2,9 @@ import { randomUUID } from "node:crypto";
import { EventEmitter } from "node:events"; import { EventEmitter } from "node:events";
import { tmpdir } from "node:os"; import { tmpdir } from "node:os";
import path from "node:path"; import path from "node:path";
import fs from "node:fs";
const net = require('net'); const net = require('net');
const split2 = require('split2'); const split2 = require('split2');
const { app } = require('electron');
let daemonClient = null; let daemonClient = null;
export const daemonEE = new EventEmitter() export const daemonEE = new EventEmitter()
@@ -138,14 +136,6 @@ export function sendToDaemon(message, {
// sendToDaemon({ type: 'start-worker', workerId, command, args, env }); // sendToDaemon({ type: 'start-worker', workerId, command, args, env });
// }); // });
app.on('window-all-closed', () => { export function closeDaemonClient() {
if (daemonClient) { daemonClient?.destroy()
daemonClient.destroy(); }
}
});
app.on('before-quit', () => {
if (daemonClient) {
daemonClient.destroy();
}
});
@@ -6,7 +6,7 @@ import initIpc from './ipc'
import gtag from '../../utils/gtag' import gtag from '../../utils/gtag'
import initPublicIpc from '../../utils/initPublicIpc' import initPublicIpc from '../../utils/initPublicIpc'
import { launchDaemon } from './launch-daemon' import { launchDaemon } from './launch-daemon'
import { connectToDaemon, sendToDaemon } from './connect-to-daemon' import { connectToDaemon, sendToDaemon, closeDaemonClient } from './connect-to-daemon'
import { sleep } from "@geekgeekrun/utils/sleep.mjs" import { sleep } from "@geekgeekrun/utils/sleep.mjs"
export function openSettingWindow() { export function openSettingWindow() {
@@ -91,4 +91,6 @@ export function openSettingWindow() {
} }
) )
}) })
app.on('window-all-closed', closeDaemonClient)
app.on('before-quit', closeDaemonClient)
} }