add logic to detect and handle login invalid - will exit auto start chat and show cookie assistant. add the logic to store cookie and local storage while auto start chat running.

This commit is contained in:
geekgeekrun
2024-03-03 23:28:36 +08:00
parent 6a7b402101
commit a25e7aedb9
7 changed files with 106 additions and 18 deletions

View File

@@ -8,13 +8,16 @@ import os from 'node:os'
import { get__dirname } from '@geekgeekrun/utils/legacy-path.mjs';
import path from 'node:path';
import JSON5 from 'json5'
import { EventEmitter } from 'node:events'
import { setDomainLocalStorage } from '@geekgeekrun/utils/puppeteer/local-storage.mjs'
import { readConfigFile, ensureConfigFileExist, readStorageFile, ensureStorageFileExist } from './runtime-file-utils.mjs'
import { readConfigFile, writeStorageFile, ensureConfigFileExist, readStorageFile, ensureStorageFileExist } from './runtime-file-utils.mjs'
ensureConfigFileExist()
ensureStorageFileExist()
const isRunFromUi = Boolean(process.env.MAIN_BOSSGEEKGO_UI_RUN_MODE)
const isUiDev = process.env.NODE_ENV === 'development'
export const autoStartChatEventBus = new EventEmitter()
let puppeteer, StealthPlugin
export async function initPuppeteer () {
@@ -52,9 +55,11 @@ export async function initPuppeteer () {
}
const bossCookies = readStorageFile('boss-cookies.json')
const bossLocalStorage = readStorageFile('boss-local-storage.json')
const targetCompanyList = readConfigFile('target-company-list.json')
const localStoragePageUrl = `https://www.zhipin.com/desktop/`
const recommendJobPageUrl = `https://www.zhipin.com/web/geek/job-recommend`
const expectCompanySet = new Set(targetCompanyList)
@@ -85,18 +90,40 @@ export async function mainLoop (hooks) {
})
//set cookies
const copiedBossCookies = JSON.parse(JSON.stringify(bossCookies))
hooks.cookieWillSet?.call(copiedBossCookies)
for(let i = 0; i < copiedBossCookies.length; i++){
await page.setCookie(copiedBossCookies[i]);
hooks.cookieWillSet?.call(bossCookies)
for(let i = 0; i < bossCookies.length; i++){
await page.setCookie(bossCookies[i]);
}
await setDomainLocalStorage(browser, localStoragePageUrl, bossLocalStorage)
debugger
let userInfoResponse
await Promise.all([
page.goto(recommendJobPageUrl, { timeout: 0 }),
page.waitForResponse((response) => {
if (response.url().startsWith('https://www.zhipin.com/wapi/zpuser/wap/getUserInfo.json')) {
return true
}
return false
}).then((res) => {
return res.json()
}).then((res) => {
userInfoResponse = res
}),
page.waitForNavigation(),
])
hooks.pageLoaded?.call()
hooks.userInfoResponse?.call(userInfoResponse)
if (userInfoResponse.code !== 0) {
autoStartChatEventBus.emit('LOGIN_STATUS_INVALID', {
userInfoResponse
})
writeStorageFile('boss-cookies.json', [])
throw new Error("LOGIN_STATUS_INVALID")
} else {
await storeStorage().catch(() => void 0)
}
const INIT_START_EXCEPT_JOB_INDEX = 1
let currentExceptJobIndex = INIT_START_EXCEPT_JOB_INDEX
@@ -323,6 +350,23 @@ export async function mainLoop (hooks) {
export async function closeBrowserWindow () {
browser?.close()
browse = null
browser = null
page = null
}
async function storeStorage (page) {
const [
cookies, localStorage
] = await Promise.all([
page.cookies(),
page.evaluate(() => {
return JSON.stringify(window.localStorage)
}).then(res => JSON.parse(res))
])
return Promise.all(
[
writeStorageFile('boss-cookies.json', cookies),
writeStorageFile('boss-local-storage.json', localStorage),
]
)
}

View File

@@ -8,6 +8,7 @@ import defaultBossConf from './default-config-file/boss.json' assert {type: 'jso
import defaultTargetCompanyListConf from './default-config-file/target-company-list.json' assert {type: 'json'}
import defaultBossCookieStorage from './default-storage-file/boss-cookies.json' assert { type: 'json' }
import defaultBossLocalStorageStorage from './default-storage-file/boss-local-storage.json' assert { type: 'json' }
export const configFileNameList = ['boss.json', 'dingtalk.json', 'target-company-list.json']
const defaultConfigFileContentMap = {
@@ -90,7 +91,8 @@ export const storageFilePath = path.join(
export const storageFileNameList = ['boss-cookies.json']
const defaultStorageFileContentMap = {
'boss-cookies.json': JSON.stringify(defaultBossCookieStorage)
'boss-cookies.json': JSON.stringify(defaultBossCookieStorage),
'boss-local-storage.json': JSON.stringify(defaultBossLocalStorageStorage)
}
export const ensureStorageFileExist = () => {
ensureRuntimeFolderPathExist()

View File

@@ -15,7 +15,7 @@ const initPlugins = (hooks) => {
let isParentProcessDisconnect = false
export const runAutoChat = async () => {
const { initPuppeteer, mainLoop, closeBrowserWindow } = await import(
const { initPuppeteer, mainLoop, closeBrowserWindow, autoStartChatEventBus } = await import(
'@geekgeekrun/geek-auto-start-chat-with-boss/index.mjs'
)
process.on('disconnect', () => {
@@ -73,16 +73,27 @@ export const runAutoChat = async () => {
type: 'GEEK_AUTO_START_CHAT_WITH_BOSS_STARTED' //geek-auto-start-chat-with-boss-started
}) + '\r\n'
)
while (!([isParentProcessDisconnect].includes(true))) {
autoStartChatEventBus.once('LOGIN_STATUS_INVALID', () => {
pipeWriteRegardlessError(
pipe,
JSON.stringify({
type: 'LOGIN_STATUS_INVALID' //geek-auto-start-chat-with-boss-started
}) + '\r\n'
)
})
while (![isParentProcessDisconnect].includes(true)) {
try {
await mainLoop(hooks)
} catch (err) {
console.log(err)
// if(err instanceof Error && err.message.includes('ERR_MODULE_NOT_FOUND')) {
// throw err
// } else {
void err
// }
if (err instanceof Error && err.message.includes('LOGIN_STATUS_INVALID')) {
process.exit(2)
break
} else {
throw err
}
}
}
closeBrowserWindow()

View File

@@ -19,6 +19,7 @@ import {
DOWNLOAD_ERROR_EXIT_CODE,
getAnyAvailablePuppeteerExecutable
} from '../flow/CHECK_AND_DOWNLOAD_DEPENDENCIES'
import { sleep } from '@geekgeekrun/utils/sleep.mjs'
let mainWindow: BrowserWindow | null = null
export function createMainWindow(): void {
@@ -123,13 +124,18 @@ export function createMainWindow(): void {
})
console.log(subProcessOfPuppeteer)
return new Promise((resolve, reject) => {
subProcessOfPuppeteer!.stdio[3]!.pipe(JSONStream.parse()).on('data', (raw) => {
subProcessOfPuppeteer!.stdio[3]!.pipe(JSONStream.parse()).on('data', async (raw) => {
const data = raw
switch (data.type) {
case 'GEEK_AUTO_START_CHAT_WITH_BOSS_STARTED': {
resolve(data)
break
}
case 'LOGIN_STATUS_INVALID': {
await sleep(500)
mainWindow?.webContents.send('check-boss-zhipin-cookie-file')
return
}
default: {
return
}

View File

@@ -1,7 +1,7 @@
<template><RouterView /></template>
<script lang="ts" setup>
import { onUnmounted } from 'vue'
import { onMounted, onUnmounted } from 'vue'
import { mountGlobalDialog as mountDependenciesSetupProgressIndicatorDialog } from '@renderer/features/DependenciesSetupProgressIndicatorDialog/operations'
import { mountGlobalDialog as mountWaitForLoginDialog } from '@renderer/features/WaitForLoginDialog/operations'
@@ -14,6 +14,12 @@ onUnmounted(() => {
} catch {}
}
})
onMounted(() => {
electron.ipcRenderer.on('check-boss-zhipin-cookie-file', mountWaitForLoginDialog)
})
onUnmounted(() => {
electron.ipcRenderer.removeListener('check-boss-zhipin-cookie-file', mountWaitForLoginDialog)
})
;(async () => {
const checkDependenciesResult = await electron.ipcRenderer.invoke('check-dependencies')
if (Object.values(checkDependenciesResult).includes(false)) {

View File

@@ -0,0 +1,18 @@
export const setDomainLocalStorage = async (browser, url, kv) => {
const page = await browser.newPage();
await page.setRequestInterception(true);
page.on('request', r => {
r.respond({
status: 200,
contentType: 'text/plain',
body: ':)',
});
});
await page.goto(url);
await page.evaluate(kv => {
Object.keys(kv).forEach(k => {
localStorage.setItem(k, kv[k]);
})
}, kv);
await page.close();
};