From 526ff646af8399ae40c42c4f5a7d82dd9a45a79d Mon Sep 17 00:00:00 2001 From: dave Date: Sat, 9 May 2026 00:00:14 +0800 Subject: [PATCH] Add CPA session token output --- README.md | 8 ++++++-- docs/index.html | 24 +++++++++++++----------- 2 files changed, 19 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index b5b4b2e..4fe7bbe 100644 --- a/README.md +++ b/README.md @@ -6,13 +6,17 @@ ### [**》》 点我直接使用 《《**](https://gtxx3600.github.io/GPTSession2CPAandSub2API/) +## 使用提示 + +Plus 号可以用此方式导入中转站使用;Free 号的 access token 不能用于调用接口。 + ## 支持输入 支持粘贴或拖入 ChatGPT Web session JSON,例如包含: - `user.email` -- `user.name` - `accessToken` +- `sessionToken` - `expires` - `account.id` - `account.planType` @@ -21,7 +25,7 @@ ## 输出格式 -- `CPA`:生成最小 Codex CPA JSON,包含 `type: "codex"`、`access_token`、`email`、`name`、过期时间等可推导字段。 +- `CPA`:生成最小 Codex CPA JSON,包含 `type: "codex"`、`access_token`、`session_token`、`email`、`name`、过期时间等可推导字段。 - `sub2api`:生成参考 `CPA2sub2API` 项目的 `exported_at/proxies/accounts` 结构,账号平台为 `openai`,类型为 `oauth`。 ChatGPT Web session 通常不包含 CPA OAuth 文件里常见的 `refresh_token` 和 `id_token`,因此 CPA 输出不会伪造这些字段。 diff --git a/docs/index.html b/docs/index.html index 86b32d1..aee3df2 100644 --- a/docs/index.html +++ b/docs/index.html @@ -573,7 +573,7 @@ https://chatgpt.com/api/auth/session ,复制页面显示的整段 JSON,粘贴到下方输入框。

-

这段 JSON 包含 accessToken,等同敏感登录凭证,不要发给别人。

+

这段 JSON 包含 accessToken 和 sessionToken,等同敏感登录凭证,不要发给别人。

@@ -590,7 +590,7 @@
等待输入。
@@ -692,15 +692,15 @@ const exampleSession = { user: { id: "user-example", - name: "Mark Anderson", email: "mark@example.com", }, expires: "2026-08-06T14:29:36.155Z", account: { id: "00000000-0000-4000-9000-000000000000", - planType: "free", + planType: "plus", }, accessToken: "paste-real-access-token-here", + sessionToken: "paste-real-session-token-here", authProvider: "openai", }; @@ -948,6 +948,13 @@ if (!accessToken) { throw new Error("缺少 accessToken"); } + const sessionToken = firstNonEmpty( + record.sessionToken, + record.session_token, + record.token?.sessionToken, + record.token?.session_token, + record.credentials?.session_token, + ); const payload = parseJwtPayload(accessToken); const auth = getOpenAIAuthSection(payload); @@ -965,13 +972,6 @@ profile.email, payload?.email, ); - const name = firstNonEmpty( - record.user?.name, - record.name, - profile.name, - email, - "ChatGPT Account", - ); const accountId = firstNonEmpty( record.account?.id, record.account_id, @@ -994,10 +994,12 @@ const exportedAt = normalizeTimestamp(options.now || new Date()); const expiresIn = getExpiresIn(expiresAt, options.now || new Date()); const sourceName = firstNonEmpty(options.sourceName, "pasted-json"); + const name = firstNonEmpty(email, sourceName, "ChatGPT Account"); const cpa = stripUnavailable({ type: "codex", access_token: accessToken, + session_token: sessionToken, account_id: accountId, email, name,