enhance error handle(not login, captcha, access denied, network error) of read no reply auto reminder.

This commit is contained in:
geekgeekrun
2024-11-17 11:05:56 +08:00
parent f9122ef92c
commit 719545fb0a
4 changed files with 111 additions and 33 deletions

View File

@@ -168,31 +168,26 @@ export default function initIpc() {
})
// console.log(subProcessOfPuppeteer)
return new Promise((resolve, reject) => {
// subProcessOfPuppeteer!.stdio[3]!.pipe(JSONStream.parse()).on('data', async (raw) => {
// const data = raw
// switch (data.type) {
// case 'AUTO_START_CHAT_DAEMON_PROCESS_STARTUP': {
// subProcessOfPuppeteer!.stdio[3]!.write(
// JSON.stringify({
// type: 'GEEK_AUTO_START_CHAT_CAN_BE_RUN'
// })
// )
// break
// }
// 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
// }
// }
// })
subProcessOfPuppeteer!.stdio[3]!.pipe(JSONStream.parse()).on('data', async (raw) => {
const data = raw
switch (data.type) {
case 'LOGIN_STATUS_INVALID': {
await sleep(500)
mainWindow?.webContents.send('check-boss-zhipin-cookie-file')
return
}
case 'ERR_INTERNET_DISCONNECTED': {
mainWindow?.webContents.send('toast-message', {
type: 'error',
message: '联网失败,请检查网络连接'
})
return
}
default: {
return
}
}
})
subProcessOfPuppeteer!.once('exit', (exitCode) => {
subProcessOfPuppeteer = null
@@ -204,7 +199,7 @@ export default function initIpc() {
}
})
resolve(undefined)
resolve(true)
})
// TODO:
})

View File

@@ -33,7 +33,14 @@ export async function launchBoss(browser: Browser) {
await page.setCookie(bossCookies[i])
}
await setDomainLocalStorage(browser, localStoragePageUrl, bossLocalStorage)
await Promise.all([page.goto(bossChatUiUrl, { timeout: 0 }), page.waitForNavigation()])
try {
await Promise.all([page.goto(bossChatUiUrl, { timeout: 0 }), page.waitForNavigation()])
} catch (error) {
if (error?.message?.startsWith('net::ERR_INTERNET_DISCONNECTED')) {
throw new Error('ERR_INTERNET_DISCONNECTED')
}
throw error
}
pageMapByName['boss'] = page
page.once('close', () => {
pageMapByName['boss'] = null

View File

@@ -9,6 +9,9 @@ import { initDb } from '@geekgeekrun/sqlite-plugin'
import { getPublicDbFilePath } from '@geekgeekrun/geek-auto-start-chat-with-boss/runtime-file-utils.mjs'
import { ChatMessageRecord } from '@geekgeekrun/sqlite-plugin/dist/entity/ChatMessageRecord'
import { saveChatMessageRecord } from '@geekgeekrun/sqlite-plugin/dist/handlers'
import { writeStorageFile } from '@geekgeekrun/geek-auto-start-chat-with-boss/runtime-file-utils.mjs'
import * as fs from 'fs'
import { pipeWriteRegardlessError } from '../utils/pipe'
const dbInitPromise = initDb(getPublicDbFilePath())
@@ -29,7 +32,7 @@ async function saveCurrentChatRecord(page) {
'document.querySelector(".message-content .chat-record").__vue__.records$'
)
)?.filter((msg) => ['received', 'sent'].includes(msg.style)) ?? []
const chatRecordList = rawChatRecordList.map(it => {
const chatRecordList = rawChatRecordList.map((it) => {
const mappedItem = {} as InstanceType<typeof ChatMessageRecord>
mappedItem.mid = it.mid
mappedItem.encryptFromUserId =
@@ -86,6 +89,42 @@ const mainLoop = async () => {
pageMapByName.boss!.bringToFront()
await sleep(2000)
const currentPageUrl = pageMapByName.boss!.url() ?? ''
// #region
if (currentPageUrl.startsWith('https://www.zhipin.com/web/user/')) {
writeStorageFile('boss-cookies.json', [])
throw new Error('LOGIN_STATUS_INVALID')
}
if (
currentPageUrl.startsWith('https://www.zhipin.com/web/common/403.html') ||
currentPageUrl.startsWith('https://www.zhipin.com/web/common/error.html')
) {
throw new Error('ACCESS_IS_DENIED')
}
if (currentPageUrl.startsWith('https://www.zhipin.com/web/user/safe/verify-slider')) {
const validateRes: any = await pageMapByName
.boss!.waitForResponse(
(response) => {
if (
response.url().startsWith('https://www.zhipin.com/wapi/zpAntispam/v2/geetest/validate')
) {
return true
}
return false
},
{
timeout: 0
}
)
.then((res) => {
return res.json()
})
if (validateRes.code === 0) {
await storeStorage(pageMapByName.boss)
throw new Error('CAPTCHA_PASSED_AND_NEED_RESTART')
}
}
// #endregion
// check set security question tip modal
let setSecurityQuestionTipModelProxy = await pageMapByName.boss!.$(
'.dialog-wrap.dialog-account-safe'
@@ -230,6 +269,13 @@ const rerunInterval = (() => {
return v
})()
let pipe
try {
pipe = fs.createWriteStream(null, { fd: 3 })
} catch {
console.warn('pipe is not available')
}
export async function runEntry() {
process.on('disconnect', () => {
app.exit()
@@ -246,6 +292,21 @@ export async function runEntry() {
} catch {
//
}
// handle error
if (
err instanceof Error &&
['LOGIN_STATUS_INVALID', 'ACCESS_IS_DENIED', 'ERR_INTERNET_DISCONNECTED'].includes(
err.message
)
) {
pipeWriteRegardlessError(
pipe,
JSON.stringify({
type: err.message
}) + '\r\n'
)
process.exit(1)
}
} finally {
pageMapByName['boss'] = null
await sleep(rerunInterval)
@@ -265,3 +326,18 @@ process.once('unhandledRejection', (error) => {
console.log('unhandledRejection', error)
process.exit(1)
})
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

@@ -1,5 +1,5 @@
import { createApp } from 'vue'
import ElementPlus from 'element-plus'
import ElementPlus, { ElMessage } from 'element-plus'
import App from './App.vue'
import router from './router'
import 'normalize.css'
@@ -8,7 +8,7 @@ import 'element-plus/dist/index.css'
import 'virtual:uno.css'
import 'animate.css'
createApp(App)
.use(router)
.use(ElementPlus)
.mount('#app')
createApp(App).use(router).use(ElementPlus).mount('#app')
electron.ipcRenderer.on('toast-message', (_, payload) => {
ElMessage(payload)
})