refactor shared flow settings and runtime cleanup
This commit is contained in:
@@ -4,6 +4,8 @@
|
||||
const GROK_SIGNUP_URL = 'https://accounts.x.ai/sign-up?redirect=grok-com';
|
||||
const GROK_REGISTER_PAGE_SOURCE_ID = 'grok-register-page';
|
||||
const DEFAULT_GROK_PAGE_TIMEOUT_MS = 90 * 1000;
|
||||
const GROK_VERIFICATION_PAGE_STATE = 'verification_code_entry';
|
||||
const GROK_VERIFICATION_READY_TIMEOUT_MS = 90 * 1000;
|
||||
const GROK_POST_PROFILE_CF_WAIT_MS = 20 * 1000;
|
||||
const GROK_PRE_SSO_EXTRACT_WAIT_MS = 10 * 1000;
|
||||
const MAIL_2925_FILTER_LOOKBACK_MS = 10 * 60 * 1000;
|
||||
@@ -191,6 +193,50 @@
|
||||
return result || {};
|
||||
}
|
||||
|
||||
async function getGrokRegisterPageState(options = {}) {
|
||||
return sendGrokCommand('GET_PAGE_STATE', {}, {
|
||||
step: options.step || 0,
|
||||
timeoutMs: options.timeoutMs || 15000,
|
||||
logMessage: options.logMessage || '',
|
||||
});
|
||||
}
|
||||
|
||||
async function waitForGrokVerificationPageReady(tabId, options = {}) {
|
||||
const timeoutMs = Math.max(1000, Number(options.timeoutMs) || GROK_VERIFICATION_READY_TIMEOUT_MS);
|
||||
const intervalMs = Math.max(250, Number(options.intervalMs) || 1000);
|
||||
const deadline = Date.now() + timeoutMs;
|
||||
let lastState = null;
|
||||
let lastError = '';
|
||||
|
||||
while (Date.now() <= deadline) {
|
||||
throwIfStopped();
|
||||
try {
|
||||
await ensureContentReady(tabId, {
|
||||
timeoutMs: Math.min(DEFAULT_GROK_PAGE_TIMEOUT_MS, Math.max(5000, intervalMs + 3000)),
|
||||
stableMs: 500,
|
||||
initialDelayMs: 0,
|
||||
logMessage: options.logMessage || '',
|
||||
});
|
||||
lastState = await getGrokRegisterPageState({
|
||||
step: options.step || 0,
|
||||
timeoutMs: Math.max(5000, intervalMs + 3000),
|
||||
});
|
||||
lastError = '';
|
||||
if (lastState?.state === GROK_VERIFICATION_PAGE_STATE) {
|
||||
return lastState;
|
||||
}
|
||||
} catch (error) {
|
||||
lastError = getErrorMessage(error);
|
||||
}
|
||||
await sleepWithStop(Math.min(intervalMs, Math.max(0, deadline - Date.now())));
|
||||
}
|
||||
|
||||
const stateLabel = cleanString(lastState?.state) || 'unknown';
|
||||
const urlLabel = cleanString(lastState?.url);
|
||||
const errorLabel = lastError ? `,最后通信错误:${lastError}` : '';
|
||||
throw new Error(`Grok 邮箱提交后尚未进入验证码页面,当前状态:${stateLabel}${urlLabel ? `,URL:${urlLabel}` : ''}${errorLabel}。`);
|
||||
}
|
||||
|
||||
function shouldClearGrokCookie(cookie = {}) {
|
||||
const domain = cleanString(cookie.domain).replace(/^\.+/, '').toLowerCase();
|
||||
return GROK_COOKIE_CLEAR_DOMAINS.some((target) => (
|
||||
@@ -395,8 +441,12 @@
|
||||
});
|
||||
const result = await sendGrokCommand(nodeId, { email }, {
|
||||
step: 2,
|
||||
timeoutMs: GROK_VERIFICATION_READY_TIMEOUT_MS + 15000,
|
||||
logMessage: '步骤 2:正在提交 Grok 注册邮箱...',
|
||||
});
|
||||
if (result.state !== GROK_VERIFICATION_PAGE_STATE) {
|
||||
throw new Error(`Grok 邮箱提交后尚未进入验证码页面,当前状态:${cleanString(result.state) || 'unknown'}${cleanString(result.url) ? `,URL:${cleanString(result.url)}` : ''}。`);
|
||||
}
|
||||
await log(`步骤 2:已提交 Grok 注册邮箱 ${email}。`, 'ok', nodeId);
|
||||
await completeNode(nodeId, {
|
||||
grokEmail: email,
|
||||
@@ -456,6 +506,23 @@
|
||||
|| currentState.runtimeState?.flowState?.grok?.register?.email
|
||||
|| currentState.email
|
||||
).toLowerCase();
|
||||
const tabId = await ensureGrokRegisterTab(currentState, { openIfMissing: false });
|
||||
await activateTab(tabId);
|
||||
const readyState = await waitForGrokVerificationPageReady(tabId, {
|
||||
step: 3,
|
||||
logMessage: '步骤 3:正在等待 Grok 验证码页面就绪...',
|
||||
});
|
||||
await persistState({
|
||||
grokPageState: readyState.state || '',
|
||||
grokPageUrl: readyState.url || '',
|
||||
...buildGrokRuntimePatch({
|
||||
session: {
|
||||
pageState: readyState.state || '',
|
||||
pageUrl: readyState.url || '',
|
||||
lastError: '',
|
||||
},
|
||||
}),
|
||||
});
|
||||
const pollResult = await pollFlowVerificationCode({
|
||||
actionLabel: 'Grok 验证码',
|
||||
filterAfterTimestamp,
|
||||
@@ -478,7 +545,6 @@
|
||||
if (!code) {
|
||||
throw new Error('未能获取到 xAI 邮箱验证码。');
|
||||
}
|
||||
const tabId = await ensureGrokRegisterTab(currentState, { openIfMissing: false });
|
||||
await activateTab(tabId);
|
||||
await ensureContentReady(tabId);
|
||||
const result = await sendGrokCommand(nodeId, { code }, {
|
||||
|
||||
@@ -5,6 +5,7 @@ const GROK_SIGNUP_URL = 'https://accounts.x.ai/sign-up?redirect=grok-com';
|
||||
const GROK_EMAIL_SIGNUP_TEXT_PATTERN = /使用邮箱注册|sign\s*up\s*with\s*email|continue\s*with\s*email|email/i;
|
||||
const GROK_CONTINUE_TEXT_PATTERN = /continue|next|sign\s*up|submit|verify|继续|下一步|注册|提交|验证/i;
|
||||
const GROK_PROFILE_TEXT_PATTERN = /given\s*name|family\s*name|first\s*name|last\s*name|password|名字|姓氏|密码/i;
|
||||
const GROK_EMAIL_VERIFICATION_READY_TIMEOUT_MS = 90 * 1000;
|
||||
const GROK_PROFILE_SUBMIT_PRE_CLICK_DELAY_MS = 2000;
|
||||
|
||||
function isVisibleGrokElement(element) {
|
||||
@@ -174,6 +175,29 @@ function getGrokEmailErrorText() {
|
||||
return '';
|
||||
}
|
||||
|
||||
async function waitForGrokVerificationPageAfterEmailSubmit() {
|
||||
const settledState = await waitForGrok(() => {
|
||||
const errorText = getGrokEmailErrorText();
|
||||
if (errorText) return { state: 'email_error', error: errorText, url: location.href };
|
||||
const state = getGrokPageState();
|
||||
return state === 'verification_code_entry' ? { state, url: location.href } : null;
|
||||
}, { timeoutMs: GROK_EMAIL_VERIFICATION_READY_TIMEOUT_MS, intervalMs: 500 });
|
||||
|
||||
if (settledState?.error) {
|
||||
throw new Error(settledState.error);
|
||||
}
|
||||
if (settledState?.state === 'verification_code_entry') {
|
||||
return settledState;
|
||||
}
|
||||
|
||||
const errorText = getGrokEmailErrorText();
|
||||
if (errorText) {
|
||||
throw new Error(errorText);
|
||||
}
|
||||
const finalState = getGrokPageState();
|
||||
throw new Error(`提交 Grok 注册邮箱后未进入验证码页面,当前页面状态:${finalState || 'unknown'}。请确认页面已跳转到“验证您的邮箱”后再继续。`);
|
||||
}
|
||||
|
||||
async function submitGrokEmail(payload = {}) {
|
||||
const email = String(payload.email || '').trim();
|
||||
if (!email) throw new Error('缺少 Grok 注册邮箱。');
|
||||
@@ -189,7 +213,8 @@ async function submitGrokEmail(payload = {}) {
|
||||
if (errorText) {
|
||||
throw new Error(errorText);
|
||||
}
|
||||
return { submitted: true, state: getGrokPageState(), url: location.href };
|
||||
const readyState = await waitForGrokVerificationPageAfterEmailSubmit();
|
||||
return { submitted: true, state: readyState.state, url: readyState.url || location.href };
|
||||
}
|
||||
|
||||
function getGrokVerificationErrorText() {
|
||||
|
||||
+1
-1
@@ -35,7 +35,7 @@
|
||||
stepDefinitionMode: 'grok',
|
||||
targetSelectorLabel: '来源',
|
||||
},
|
||||
baseGroups: ['grok-runtime-status'],
|
||||
baseGroups: ['grok-runtime-status', 'shared-auto-run', 'shared-settings-actions'],
|
||||
targets: {
|
||||
webchat2api: {
|
||||
id: 'webchat2api',
|
||||
|
||||
+7
-1
@@ -40,12 +40,18 @@
|
||||
"targetSelectorLabel": "来源"
|
||||
},
|
||||
"baseGroups": [
|
||||
"kiro-runtime-status"
|
||||
"kiro-runtime-status",
|
||||
"shared-auto-run",
|
||||
"shared-settings-actions"
|
||||
],
|
||||
"targets": {
|
||||
"kiro-rs": {
|
||||
"id": "kiro-rs",
|
||||
"label": "kiro.rs",
|
||||
"defaultState": {
|
||||
"baseUrl": "",
|
||||
"apiKey": ""
|
||||
},
|
||||
"groups": [
|
||||
"kiro-target-kiro-rs"
|
||||
]
|
||||
|
||||
+48
-2
@@ -46,13 +46,20 @@
|
||||
"baseGroups": [
|
||||
"openai-plus",
|
||||
"openai-phone",
|
||||
"shared-auto-run",
|
||||
"openai-oauth",
|
||||
"openai-step6"
|
||||
"openai-step6",
|
||||
"shared-settings-actions"
|
||||
],
|
||||
"targets": {
|
||||
"cpa": {
|
||||
"id": "cpa",
|
||||
"label": "CPA 面板",
|
||||
"defaultState": {
|
||||
"vpsUrl": "",
|
||||
"vpsPassword": "",
|
||||
"localCpaStep9Mode": "submit"
|
||||
},
|
||||
"groups": [
|
||||
"openai-target-cpa"
|
||||
]
|
||||
@@ -60,6 +67,18 @@
|
||||
"sub2api": {
|
||||
"id": "sub2api",
|
||||
"label": "SUB2API",
|
||||
"defaultState": {
|
||||
"sub2apiUrl": "",
|
||||
"sub2apiEmail": "",
|
||||
"sub2apiPassword": "",
|
||||
"sub2apiGroupName": "codex",
|
||||
"sub2apiGroupNames": [
|
||||
"codex",
|
||||
"openai-plus"
|
||||
],
|
||||
"sub2apiAccountPriority": 1,
|
||||
"sub2apiDefaultProxyName": ""
|
||||
},
|
||||
"groups": [
|
||||
"openai-target-sub2api"
|
||||
]
|
||||
@@ -67,11 +86,37 @@
|
||||
"codex2api": {
|
||||
"id": "codex2api",
|
||||
"label": "Codex2API",
|
||||
"defaultState": {
|
||||
"codex2apiUrl": "",
|
||||
"codex2apiAdminKey": ""
|
||||
},
|
||||
"groups": [
|
||||
"openai-target-codex2api"
|
||||
]
|
||||
}
|
||||
},
|
||||
"settingsDefaults": {
|
||||
"signup": {
|
||||
"signupMethod": "email",
|
||||
"phoneVerificationEnabled": false,
|
||||
"phoneSignupReloginAfterBindEmailEnabled": false
|
||||
},
|
||||
"plus": {
|
||||
"plusModeEnabled": false,
|
||||
"plusPaymentMethod": "paypal-hosted",
|
||||
"plusAccountAccessStrategy": "oauth",
|
||||
"hostedCheckoutVerificationUrl": "",
|
||||
"hostedCheckoutPhoneNumber": "",
|
||||
"plusHostedCheckoutOauthDelaySeconds": 3
|
||||
},
|
||||
"autoRun": {
|
||||
"stepExecutionRange": {
|
||||
"enabled": false,
|
||||
"fromStep": 1,
|
||||
"toStep": 11
|
||||
}
|
||||
}
|
||||
},
|
||||
"runtimeSources": {
|
||||
"openai-auth": {
|
||||
"flowId": "openai",
|
||||
@@ -383,7 +428,8 @@
|
||||
"label": "OAuth",
|
||||
"rowIds": [
|
||||
"row-oauth-flow-timeout",
|
||||
"row-oauth-display"
|
||||
"row-oauth-display",
|
||||
"row-oauth-callback"
|
||||
]
|
||||
},
|
||||
"openai-step6": {
|
||||
|
||||
Reference in New Issue
Block a user