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,粘贴到下方输入框。
-
@@ -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,