From 52a897adc56189685bc3ebb7559ea060a18319ae Mon Sep 17 00:00:00 2001 From: zhangren Date: Sun, 8 Feb 2026 14:06:59 +0800 Subject: [PATCH] fix: support multi-account path prefix in Gemini plugin --- .../core-plugins/src/plugins/gemini/parser.ts | 49 +++++++------------ .../core-plugins/src/plugins/gemini/plugin.ts | 11 ++++- 2 files changed, 29 insertions(+), 31 deletions(-) diff --git a/packages/core-plugins/src/plugins/gemini/parser.ts b/packages/core-plugins/src/plugins/gemini/parser.ts index 6178d6f..dce55b8 100644 --- a/packages/core-plugins/src/plugins/gemini/parser.ts +++ b/packages/core-plugins/src/plugins/gemini/parser.ts @@ -1,8 +1,7 @@ import { createAppError } from "@ctxport/core-schema"; import type { GeminiRuntimeParams } from "./types"; -const BATCH_EXECUTE_ENDPOINT = - "https://gemini.google.com/_/BardChatUi/data/batchexecute"; +const BATCH_EXECUTE_BASE = "https://gemini.google.com"; const GEMINI_IMAGE_URL_PATTERN = /^https:\/\/lh3\.googleusercontent\.com\/gg(?:-dl)?\//; @@ -12,12 +11,13 @@ const GEMINI_IMAGE_URL_PATTERN = export async function fetchConversationPayload( conversationId: string, runtimeParams: GeminiRuntimeParams, + pathPrefix = "", ): Promise { const rpcId = "hNvQHb"; const query = new URLSearchParams({ rpcids: rpcId, - "source-path": `/app/${conversationId}`, + "source-path": `${pathPrefix}/app/${conversationId}`, bl: runtimeParams.bl, "f.sid": runtimeParams.fSid, hl: runtimeParams.hl, @@ -29,16 +29,7 @@ export async function fetchConversationPayload( [ [ rpcId, - JSON.stringify([ - `c_${conversationId}`, - 100, - null, - 1, - [0], - [4], - null, - 1, - ]), + JSON.stringify([`c_${conversationId}`, 10, null, 1, [0], [4], null, 1]), null, "generic", ], @@ -49,24 +40,22 @@ export async function fetchConversationPayload( body.set("at", runtimeParams.at); } - const response = await fetch( - `${BATCH_EXECUTE_ENDPOINT}?${query.toString()}`, - { - method: "POST", - mode: "cors", - credentials: "include", - cache: "no-store", - referrer: `https://gemini.google.com/app/${conversationId}`, - referrerPolicy: "strict-origin-when-cross-origin", - headers: { - Accept: "*/*", - "Content-Type": "application/x-www-form-urlencoded;charset=utf-8", - Origin: "https://gemini.google.com", - "X-Same-Domain": "1", - }, - body: body.toString(), + const endpoint = `${BATCH_EXECUTE_BASE}${pathPrefix}/_/BardChatUi/data/batchexecute`; + const response = await fetch(`${endpoint}?${query.toString()}`, { + method: "POST", + mode: "cors", + credentials: "include", + cache: "no-store", + referrer: `https://gemini.google.com${pathPrefix}/app/${conversationId}`, + referrerPolicy: "strict-origin-when-cross-origin", + headers: { + Accept: "*/*", + "Content-Type": "application/x-www-form-urlencoded;charset=utf-8", + Origin: "https://gemini.google.com", + "X-Same-Domain": "1", }, - ); + body: body.toString(), + }); if (!response.ok) { throw createAppError( diff --git a/packages/core-plugins/src/plugins/gemini/plugin.ts b/packages/core-plugins/src/plugins/gemini/plugin.ts index c626b48..b7f618b 100644 --- a/packages/core-plugins/src/plugins/gemini/plugin.ts +++ b/packages/core-plugins/src/plugins/gemini/plugin.ts @@ -27,21 +27,25 @@ export const geminiPlugin: Plugin = { throw createAppError("E-PARSE-001", "Not a Gemini conversation page"); } + const pathPrefix = extractPathPrefix(ctx.url); const runtimeParams = await resolveRuntimeParams(ctx.document); const payload = await fetchConversationPayload( conversationId, runtimeParams, + pathPrefix, ); return buildContentBundle(payload, ctx.url); }, async fetchById(conversationId: string): Promise { + const pathPrefix = extractPathPrefix(document.location.href); const runtimeParams = await resolveRuntimeParams(document); const payload = await fetchConversationPayload( conversationId, runtimeParams, + pathPrefix, ); - const url = `https://gemini.google.com/app/${conversationId}`; + const url = `https://gemini.google.com${pathPrefix}/app/${conversationId}`; return buildContentBundle(payload, url); }, @@ -81,6 +85,11 @@ function extractConversationId(url: string): string | null { return match?.[1] ?? null; } +function extractPathPrefix(url: string): string { + const match = /^https?:\/\/gemini\.google\.com\/(u\/\d+)\//.exec(url); + return match ? `/${match[1]}` : ""; +} + async function resolveRuntimeParams( doc: Document, ): Promise {