11
This commit is contained in:
@@ -352,6 +352,110 @@ async function newLoginPage(platform, accountId, cookies = [], startUrl) {
|
||||
return page;
|
||||
}
|
||||
|
||||
/**
|
||||
* 打开账号页:detached Chrome + connect,脚本结束后可保留窗口
|
||||
* @param {string} [startUrl]
|
||||
*/
|
||||
async function newLoginPageKeepOpen(platform, accountId, cookies = [], startUrl) {
|
||||
const key = `login_${contextKey(platform, accountId)}`;
|
||||
const existing = loginBrowsers.get(key);
|
||||
if (existing && existing.isConnected()) {
|
||||
const pages = await existing.pages();
|
||||
let page =
|
||||
pages.find((p) => {
|
||||
try {
|
||||
const u = p.url();
|
||||
return u && u !== "about:blank" && u !== "chrome://newtab/";
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
}) || pages[0];
|
||||
if (page) {
|
||||
await bringPageToFront(page);
|
||||
if (startUrl) {
|
||||
try {
|
||||
const cur = page.url();
|
||||
if (!cur || cur === "about:blank" || !cur.includes("://")) {
|
||||
await page.goto(startUrl, {
|
||||
waitUntil: "domcontentloaded",
|
||||
timeout: 60000,
|
||||
});
|
||||
}
|
||||
} catch {
|
||||
/* ignore */
|
||||
}
|
||||
}
|
||||
return page;
|
||||
}
|
||||
}
|
||||
|
||||
const publishKey = contextKey(platform, accountId);
|
||||
const publishPort = debugPortForKey(publishKey);
|
||||
const loginPort = debugPortForKey(key);
|
||||
await closeLoginBrowser(platform, accountId);
|
||||
await closePublishBrowser(platform, accountId);
|
||||
await forceCloseChromeOnPort(loginPort);
|
||||
await forceCloseChromeOnPort(publishPort);
|
||||
|
||||
const puppeteer = loadPuppeteer();
|
||||
const dir = userDataDir(platform, accountId);
|
||||
if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true });
|
||||
cleanupProfileLocks(dir);
|
||||
|
||||
const executablePath = getChromiumExecutablePath();
|
||||
if (!executablePath) {
|
||||
throw new Error(
|
||||
"未找到 Chrome/Edge,请安装 Google Chrome 或 Microsoft Edge,或设置 AICLIENT_CHROMIUM_PATH",
|
||||
);
|
||||
}
|
||||
|
||||
const openUrl =
|
||||
startUrl && String(startUrl).trim() ? String(startUrl).trim() : "about:blank";
|
||||
|
||||
globalThis.__native?.emitProgress?.("正在打开 Chrome…");
|
||||
await spawnDetachedChrome(executablePath, dir, loginPort, openUrl, { force: true });
|
||||
const browser = await connectPublishBrowser(puppeteer, loginPort);
|
||||
browser.on("disconnected", () => loginBrowsers.delete(key));
|
||||
loginBrowsers.set(key, browser);
|
||||
|
||||
const pages = await browser.pages();
|
||||
let page =
|
||||
pages.find((p) => {
|
||||
try {
|
||||
const u = p.url();
|
||||
return u && u !== "about:blank" && u !== "chrome://newtab/";
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
}) || pages[0] || null;
|
||||
|
||||
if (!page) {
|
||||
page = await browser.newPage();
|
||||
if (startUrl) {
|
||||
await page.goto(startUrl, {
|
||||
waitUntil: "domcontentloaded",
|
||||
timeout: 60000,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
await page.setUserAgent(DEFAULT_USER_AGENT);
|
||||
await page.evaluateOnNewDocument(STEALTH_INIT_SCRIPT);
|
||||
page.setDefaultNavigationTimeout(60000);
|
||||
page.setDefaultTimeout(60000);
|
||||
|
||||
if (Array.isArray(cookies) && cookies.length) {
|
||||
try {
|
||||
await page.setCookie(...cookies);
|
||||
} catch (e) {
|
||||
console.warn("setCookie 失败:", e.message);
|
||||
}
|
||||
}
|
||||
|
||||
await bringPageToFront(page);
|
||||
return page;
|
||||
}
|
||||
|
||||
async function closeLoginBrowser(platform, accountId) {
|
||||
const key = `login_${contextKey(platform, accountId)}`;
|
||||
const port = debugPortForKey(key);
|
||||
@@ -381,9 +485,15 @@ async function detachLoginBrowser(platform, accountId) {
|
||||
if (!browser) return;
|
||||
loginBrowsers.delete(key);
|
||||
try {
|
||||
if (!browser.isConnected()) return;
|
||||
// puppeteer.connect:disconnect 后 Chrome 独立进程继续运行
|
||||
if (typeof browser.disconnect === "function") {
|
||||
await browser.disconnect();
|
||||
return;
|
||||
}
|
||||
// puppeteer.launch:仅 unref 子进程,勿 close/disconnect
|
||||
const proc = typeof browser.process === "function" ? browser.process() : null;
|
||||
if (proc && typeof proc.unref === "function") proc.unref();
|
||||
if (browser.isConnected()) await browser.disconnect();
|
||||
} catch (e) {
|
||||
console.warn("detachLoginBrowser:", e.message);
|
||||
}
|
||||
@@ -465,6 +575,7 @@ module.exports = {
|
||||
getLoginBrowser,
|
||||
newPublishPage,
|
||||
newLoginPage,
|
||||
newLoginPageKeepOpen,
|
||||
userDataDir,
|
||||
LOGIN_URLS,
|
||||
getChromiumExecutablePath,
|
||||
@@ -472,6 +583,7 @@ module.exports = {
|
||||
closeLoginBrowser,
|
||||
detachLoginBrowser,
|
||||
detachPublishBrowser,
|
||||
bringPageToFront,
|
||||
debugPortForKey,
|
||||
contextKey,
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user