diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000000000000000000000000000000000000..c66c3f8b6280b59f75bdc258366070ef6896fdf4 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,14 @@ +.git +.gitignore +.idea +.venv +__pycache__ +*.pyc +*.pyo +*.pyd + +web/.next +web/node_modules + +assets +README.md diff --git a/.env.example b/.env.example new file mode 100644 index 0000000000000000000000000000000000000000..a8eb2763e242c01b10d59680c7f03b53f8cfebf9 --- /dev/null +++ b/.env.example @@ -0,0 +1,48 @@ +# ============================================ +# ChatGPT2API 环境变量配置示例 +# ============================================ + +# 认证密钥(必填) +CHATGPT2API_AUTH_KEY=your_secret_key_here + +# 基础 URL(可选,用于生成图片 URL) +# CHATGPT2API_BASE_URL=https://your-domain.com + +# ============================================ +# 存储后端配置 +# ============================================ + +# 存储后端类型(可选值: json, sqlite, postgres, git) +# 默认: json +STORAGE_BACKEND=json + +# ============================================ +# 数据库配置(当 STORAGE_BACKEND=sqlite/postgres 时使用) +# ============================================ + +# PostgreSQL 示例 +# DATABASE_URL=postgresql://user:password@localhost:5432/chatgpt2api + +# Supabase 示例 +# DATABASE_URL=postgresql://postgres.xxx:password@aws-1-us-west-1.pooler.supabase.com:5432/postgres + +# SQLite 示例(不指定时自动使用 data/accounts.db) +# DATABASE_URL=sqlite:///app/data/accounts.db + +# ============================================ +# Git 仓库配置(当 STORAGE_BACKEND=git 时使用) +# ============================================ + +# Git 仓库地址(必填) +# GIT_REPO_URL=https://github.com/your-username/your-private-repo.git + +# Git 访问令牌(必填) +# GitHub: ghp_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +# GitLab: glpat-xxxxxxxxxxxxxxxxxxxx +# GIT_TOKEN=your_git_token_here + +# Git 分支(可选,默认: main) +# GIT_BRANCH=main + +# Git 仓库中的文件路径(可选,默认: accounts.json) +# GIT_FILE_PATH=accounts.json diff --git a/.github/workflows/docker-publish.yml b/.github/workflows/docker-publish.yml new file mode 100644 index 0000000000000000000000000000000000000000..f7bdd844802ca267ba5343d1865ada80e28a3d63 --- /dev/null +++ b/.github/workflows/docker-publish.yml @@ -0,0 +1,61 @@ +name: Publish Docker Image + +on: + push: + tags: + - "v*" + workflow_dispatch: + +env: + IMAGE_NAME: chatgpt2api + +jobs: + docker: + runs-on: ubuntu-latest + permissions: + contents: read + packages: write + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Set up QEMU + uses: docker/setup-qemu-action@v3 + with: + platforms: arm64 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Log in to GHCR + uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Extract Docker metadata + id: meta + uses: docker/metadata-action@v5 + with: + images: ghcr.io/${{ github.repository_owner }}/${{ env.IMAGE_NAME }} + tags: | + type=raw,value=latest,enable=${{ startsWith(github.ref, 'refs/tags/v') }} + type=ref,event=tag + type=sha + type=semver,pattern={{version}} + type=semver,pattern={{major}}.{{minor}} + + - name: Build and push image + uses: docker/build-push-action@v6 + with: + context: . + file: ./Dockerfile + target: app + platforms: linux/amd64,linux/arm64 + push: true + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} + cache-from: type=gha + cache-to: type=gha,mode=max diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..936bbbc9817d511ec635c6bd46c6324ac4fbd50f --- /dev/null +++ b/.gitignore @@ -0,0 +1,30 @@ +# Python-generated files +__pycache__/ +*.py[oc] +build/ +dist/ +wheels/ +*.egg-info +web_dist +# Virtual environments +.venv +.idea +data +config.json +edit + +docker-compose-local.yml + +.claude/settings.local.json + +# Environment variables +.env +.env.local + +# Database files +*.db +*.sqlite +*.sqlite3 + +# Git cache +git_cache/ \ No newline at end of file diff --git a/.python-version b/.python-version new file mode 100644 index 0000000000000000000000000000000000000000..24ee5b1be9961e38a503c8e764b7385dbb6ba124 --- /dev/null +++ b/.python-version @@ -0,0 +1 @@ +3.13 diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000000000000000000000000000000000000..c7d5e6279c5ac7ee881f891c03f0aef7f71ace1e --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,20 @@ +# Changelog + +## Unreleased + +## 1.2.3 - 2026-05-29 + ++ [新增] 新增账号级代理。 ++ [修复] 修复503异常信息、前端邮箱换行问题。 + +## 1.2.2 - 2026-05-29 + ++ [新增] 新增Codex链路生图、支持2k,4k。 ++ [新增] 支持RT刷新账号信息。 + +## 1.2.0 - 2026-05-28 + ++ [新增] 当前版本基线,包含 Web 面板、画图、号池管理、注册机、图片管理、日志管理和设置能力。 ++ [新增] 前端版本号支持点击查看版本更新弹窗,展示当前版本、最新版本和更新日志。 ++ [优化] 优化注册机效率,成功率大幅提高。 ++ [优化] 优化生图页面配置选项。 diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000000000000000000000000000000000000..32a8fef218f2349e017f46d8b9fad1982d30783e --- /dev/null +++ b/Dockerfile @@ -0,0 +1,56 @@ +ARG BUILDPLATFORM +ARG TARGETPLATFORM +ARG TARGETARCH + +FROM --platform=$BUILDPLATFORM node:22-alpine AS web-build + +WORKDIR /app/web + +COPY web/package.json web/bun.lock ./ +RUN npm install + +COPY VERSION /app/VERSION +COPY CHANGELOG.md /app/CHANGELOG.md +COPY web ./ +RUN NEXT_PUBLIC_APP_VERSION="$(cat /app/VERSION)" npm run build + + +FROM --platform=$TARGETPLATFORM python:3.13-slim AS app + +ARG TARGETPLATFORM +ARG TARGETARCH + +ENV PYTHONDONTWRITEBYTECODE=1 \ + PYTHONUNBUFFERED=1 \ + UV_LINK_MODE=copy + +WORKDIR /app + +# 安装系统依赖 +# - git: Git 存储后端需要 +# - libpq-dev: PostgreSQL 客户端库 +# - gcc: 编译 psycopg2-binary 需要 +RUN apt-get update && apt-get install -y --no-install-recommends \ + git \ + libpq-dev \ + gcc \ + openssl \ + && rm -rf /var/lib/apt/lists/* + +RUN pip install --no-cache-dir uv + +COPY pyproject.toml uv.lock ./ +RUN uv sync --frozen --no-dev --no-install-project + +COPY main.py ./ +COPY config.json ./ +COPY VERSION ./ +COPY api ./api +COPY services ./services +COPY utils ./utils +COPY scripts ./scripts +COPY --from=web-build /app/web/out ./web_dist + +EXPOSE 80 + +CMD ["uv", "run", "uvicorn", "main:app", "--host", "0.0.0.0", "--port", "80", "--access-log"] diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000000000000000000000000000000000000..58e8f6506556e2827432bd52cc9fbf3d13b5bd70 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2026 kunkun + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000000000000000000000000000000000000..436e0f4597baf3586a92f20cd5636052859bc2b1 --- /dev/null +++ b/README.md @@ -0,0 +1,336 @@ +
ChatGPT2API 主要是对 ChatGPT 官网相关能力进行逆向整理与封装,提供面向 ChatGPT 图片生成、图片编辑、多图组图编辑场景的 OpenAI 兼容图片 API / 代理,并集成在线画图、号池管理、多种账号导入方式与 Docker 自托管部署能力。
+ +> [!WARNING] +> 免责声明: +> +> 本项目涉及对 ChatGPT 官网文本生成、图片生成与图片编辑等相关接口的逆向研究,仅供个人学习、技术研究与非商业性技术交流使用。 +> +> - 严禁将本项目用于任何商业用途、盈利性使用、批量操作、自动化滥用或规模化调用。 +> - 严禁将本项目用于破坏市场秩序、恶意竞争、套利倒卖、二次售卖相关服务,以及任何违反 OpenAI 服务条款或当地法律法规的行为。 +> - 严禁将本项目用于生成、传播或协助生成违法、暴力、色情、未成年人相关内容,或用于诈骗、欺诈、骚扰等非法或不当用途。 +> - 使用者应自行承担全部风险,包括但不限于账号被限制、临时封禁或永久封禁以及因违规使用等所导致的法律责任。 +> - 使用本项目即视为你已充分理解并同意本免责声明全部内容;如因滥用、违规或违法使用造成任何后果,均由使用者自行承担。 +> - 本项目基于对 ChatGPT 官网相关能力的逆向研究实现,存在账号受限、临时封禁或永久封禁的风险。请勿使用你自己的重要账号、常用账号或高价值账号进行测试。 + +## 快速开始 + +已发布镜像支持 `linux/amd64` 与 `linux/arm64`,在 x86 服务器和 Apple Silicon / ARM Linux 设备上都会自动拉取匹配架构的版本。 + +### Docker 运行 + +```bash +git clone git@github.com:basketikun/chatgpt2api.git +cd chatgpt2api +docker compose up -d +``` + +启动前请先在 `config.json` 中设置 `auth-key`,也可以在 `docker-compose.yml` 中通过 `CHATGPT2API_AUTH_KEY` 覆盖。 + +- Web 面板:`http://localhost:3000` +- API 地址:`http://localhost:3000/v1` +- 数据目录:`./data` + +### 本地开发 + +启动后端: + +```bash +git clone git@github.com:basketikun/chatgpt2api.git +cd chatgpt2api +uv sync +uv run main.py +``` + +启动前端: + +```bash +cd chatgpt2api/web +bun install +bun run dev +``` + +后续更新新版本: + +```bash +docker pull ghcr.io/basketikun/chatgpt2api:latest +docker-compose down +docker-compose up -d + +``` + +### 存储后端配置 + +支持通过环境变量 `STORAGE_BACKEND` 切换存储方式: + +- `json` - 本地 JSON 文件(默认) +- `sqlite` - 本地 SQLite 数据库 +- `postgres` - 外部 PostgreSQL(需配置 `DATABASE_URL`) +- `git` - Git 私有仓库(需配置 `GIT_REPO_URL` 和 `GIT_TOKEN`) + +示例:使用 PostgreSQL + +```yaml +environment: + - STORAGE_BACKEND=postgres + - DATABASE_URL=postgresql://user:password@host:5432/dbname +``` + +## 功能 + +### API 兼容能力 + +- 兼容 `POST /v1/images/generations` 图片生成接口 +- 兼容 `POST /v1/images/edits` 图片编辑接口 +- 兼容面向图片场景的 `POST /v1/chat/completions` +- 兼容面向图片场景的 `POST /v1/responses` +- `GET /v1/models` 返回 `gpt-image-2`、`codex-gpt-image-2`、`auto`、`gpt-5`、`gpt-5-1`、`gpt-5-2`、`gpt-5-3`、`gpt-5-3-mini`、 + `gpt-5-mini` +- 支持通过 `n` 返回多张生成结果 +- 支持 Codex 中的画图接口逆向,仅 `Plus` / `Team` / `Pro` 订阅可用,模型别名为 `codex-gpt-image-2`,如有需要可自行在其他场景映射回 + `gpt-image-2`,用于和官网画图区分;也就意味着同一账号会同时有官网和 Codex 两份生图额度 + +### 在线画图功能 + +- 内置在线画图工作台,支持生成、图片编辑与多图组图编辑 +- 支持 `gpt-image-2`、`codex-gpt-image-2`、`auto`、`gpt-5`、`gpt-5-1`、`gpt-5-2`、`gpt-5-3`、`gpt-5-3-mini`、`gpt-5-mini` 模型选择 +- 编辑模式支持参考图上传 +- 前端支持多图生成交互 +- 本地保存图片会话历史,支持回看、删除和清空 +- 支持服务端缓存图片URL + +### 号池管理功能 + +- 自动刷新账号邮箱、类型、额度和恢复时间 +- 轮询可用账号执行图片生成与图片编辑 +- 遇到 Token 失效类错误时自动剔除无效 Token +- 定时检查限流账号并自动刷新 +- 支持网页端配置全局 HTTP / HTTPS / SOCKS5 / SOCKS5H 代理 +- 支持搜索、筛选、批量刷新、导出、手动编辑和清理账号 +- 支持四种导入方式:本地 CPA JSON 文件导入、远程 CPA 服务器导入、`sub2api` 服务器导入、`access_token` 导入 +- 支持在设置页配置 `sub2api` 服务器,筛选并批量导入其中的 OpenAI OAuth 账号 + +### 实验性 / 规划中 + +- `/v1/complete` 文本补全与流式输出已实现,但仍在测试,目前会出现对话重复的问题,请谨慎测试使用 +- `/v1/chat/completions` 文本链路支持短 TTL 缓存、重复请求合并与相邻重复消息清理,可通过 `chat_completion_cache` 配置调整 +- 详细状态说明见:[功能清单](./docs/feature-status.en.md) + +## 效果展示 + +![]() |
+ ![]() |
+
![]() |
+ ![]() |
+
![]() |
+
GET /v1/modelsPOST /v1/images/generationsPOST /v1/images/editsPOST /v1/chat/completionsPOST /v1/responses| 类型 | 数量 |
|---|---|
| {t} | {c} |
platform.openai.com/auth/callback?code=...。立刻从地址栏复制整段 URL(或开 F12 在 Network 里抓到 callback 那一行,右键 Copy → Copy URL)。正在加载账户
+从后端同步账号列表和状态。
+|
+ |
+ token | +类型 | +来源 | +状态 | +账号信息 | +创建时间 | +额度 | +恢复时间 | +成功 | +失败 | +操作 | +
|---|---|---|---|---|---|---|---|---|---|---|---|
|
+ |
+
+
+
+ {maskToken(account.access_token)}
+
+
+
+ |
+
+ |
+
+ |
+
+ |
+
+ {account.email ?? "—"}
+ |
+ + {(() => { + const raw = (account as any).created_at; + if (!raw) return "—"; + try { + const d = new Date(raw + "Z"); + if (isNaN(d.getTime())) return String(raw).slice(0, 10); + return d.toLocaleDateString("zh-CN", { month: "2-digit", day: "2-digit", hour: "2-digit", minute: "2-digit" }); + } catch { return String(raw).slice(0, 10); } + })()} + | +
+ |
+
+ {(() => {
+ const restore = formatRestoreAt(account.restore_at);
+ return (
+
+ {restore.relative ?
+ );
+ })()}
+ {restore.relative} : null}
+ {restore.absolute}
+ |
+ {account.success} | +{account.fail} | +
+
+
+
+
+
+ |
+
没有匹配的账户
+调整筛选条件或搜索关键字后重试。
++ 在同一窗口里保留本地历史与任务状态,并从已有结果图继续发起新的无状态编辑。 +
+{turn.status === "queued" ? "排队中" : "处理中"}
+输入密钥后继续使用账号管理和图片生成功能。
+可配置多个 provider,按启用顺序轮换。
+使用说明
+Authorization: BearerSSE 实时推送当前状态。
+遇到 HTTP 状态码 400 等错误,基本是邮箱滥用被封,需要更换新的域名邮箱。
+将关键数据定时备份到 Cloudflare R2,支持可选加密、轮替、手动执行与历史清理。
+R2 内对象前缀,例如 `backups/prod`。
+单位分钟,服务启动后会按此间隔自动轮询执行。
+成功上传后自动删除更旧的备份。填 `0` 表示不自动轮替。
+仅在启用加密时使用。请妥善保管,否则无法解密备份内容。
+按组件勾选需要进入备份包的数据。
+支持查看对象信息并直接删除远端备份。
+设置 `CHATGPT2API_BASE_URL` 的本地配置值,保存后立即生效。
+留空则使用环境变量或默认值,保存时会自动去掉首尾空格。
+单位分钟,控制账号自动刷新频率。
+留空表示不使用代理。
+ {proxyTestResult ? ( +用于生成图片结果的访问前缀地址。
+自动删除多少天前的本地图片。
+单位秒,等待上游图片结果的最长时间。
+限制每个账号同时处理的图片请求数量,默认 3。
+不选择时使用默认 info / warning / error。
++ 生成时只处理本次新图片;全量同步用于把已有本地图片补传到 WebDAV。 +
+留空时返回本应用 /images/... 代理地址;填入后直接返回公开图片地址。
++ 开启后会在请求进入生图账号前先调用审核模型,审核不通过会直接拒绝,减少违规提示词触达账号造成风控或封号的风险。 +
+先配置连接,再按需查询远程账号并选择导入到本地号池。
+暂无 CPA 连接
+点击「添加连接」保存你的 CLIProxyAPI 信息。
+使用说明
+为系统中的出站请求配置统一代理,保存后会立即生效。
++ 留空表示不使用代理。请按完整地址填写,例如 `http://127.0.0.1:7890`、`http://用户名:密码@127.0.0.1:7890` 或 `socks5://127.0.0.1:7890`。 +
++ 为 chatgpt.com 的请求配置出网代理,适合国内服务器部署;Sub2API / CPA 请求不受影响。 +
+http / https / socks4 / socks5 / socks5h。
+ + 配置 Sub2API 服务器后,可查询其中的 OpenAI OAuth 账号并批量导入本地号池。 +
+暂无 Sub2API 连接
+点击「添加连接」保存你的 Sub2API 信息。
+使用说明
+为普通用户创建专用密钥;普通用户只能进入画图页,不能查看设置和号池。
+{revealedKey}
+
+