ChatGPT2API

repository·main·Indexed 26 days ago

https://github.com/basketikun/chatgpt2api

A reverse-engineered wrapper for ChatGPT's official web capabilities providing OpenAI-compatible APIs for image generation, editing, and multi-image composition. It features an integrated web workbench, account pool management with automated maintenance, and support for multiple storage backends including JSON, SQLite, Postgres, and Git. Deployment options include standard Docker or a specialized WARP and FlareSolverr scheme to bypass Cloudflare interceptions.

Tokens
9.1K
Snippets
26
Records
67
Agent score
91%

What's inside chatgpt2api

  1. Account Pool Management features

    main

    The system includes advanced management for account pools, including:

    • Automated Maintenance: Refreshes account email, type, quota, and recovery time; automatically removes invalid tokens; and performs periodic checks on rate-limited accounts.
    • Polling: Automatically rotates through available accounts for image generation and editing.
    • Import Methods: Supports importing via local CPA JSON files, remote CPA servers, sub2api servers, and access_token imports.
    • Proxy Support: Configurable global HTTP/HTTPS/SOCKS5/SOCKS5H proxies and WARP/FlareSolverr runtime.
  2. Understand the Upstream Conversation SSE Protocol

    main

    The Conversation SSE (Server-Sent Events) protocol is a streaming protocol used for upstream dialogue. Clients must consume JSON payloads sequentially to maintain session state, text content, tool call status, and image result pointers.

    Payload Types:

    • "v1": Protocol version marker.
    • [DONE]: End of the SSE stream.
    • JSON object: Events, messages, or patches used to update session state.
    • JSON string: Short text patches or protocol markers.
    • Non-JSON content: Raw content to be preserved as raw events.
  3. Process Text Incremental Updates (Patches)

    main

    Text output is typically delivered via multiple patch events. Follow these rules to reconstruct the text:

    • Append: If p == "/message/content/parts/0" and o == "append", append the value v to the current text.
    • Replace: If o == "replace", replace the target field with the new value v.
    • Batch Patch: If o == "patch" and v is an array, process the patches in the array sequentially.
    • Implicit Text: If the payload only contains v as a string, treat it as a text increment for the current stream.
    {"p":"/message/content/parts/0","o":"append","v":"Hello"}
    {"v":" world"}
    {"p":"","o":"patch","v":[
      {"p":"/message/content/parts/0","o":"append","v":"!”},
      {"p":"/message/status","o":"replace","v":"finished_successfully"},
      {"p":"/message/end_turn","o":"replace","v":true}
    ]}
  4. Deploy ChatGPT2API with WARP and FlareSolverr

    main

    Use this method if upstream requests are frequently blocked by Cloudflare. This deployment includes warp-proxy, privoxy, flaresolverr, init-config, and the app.

    1. Clone the repository and enter the directory.
    2. Copy the environment template: cp .env.example .env.
    3. Set CHATGPT2API_AUTH_KEY in the .env file.
    4. Start the deployment using the specific WARP compose file: docker compose -f docker-compose.warp.yml up -d --build

    FlareSolverr configurations can be viewed and tested in the FlareSolverr tab of the admin settings page.

    cp .env.example .env
    # Edit .env to set CHATGPT2API_AUTH_KEY
    docker compose -f docker-compose.warp.yml up -d --build
  5. Upgrade ChatGPT2API

    main

    Follow these steps to upgrade your deployment. Always perform a backup first.

    Standard Docker Upgrade:

    1. git pull
    2. docker compose pull
    3. docker compose up -d

    WARP / FlareSolverr Upgrade:

    1. git pull
    2. docker compose -f docker-compose.warp.yml up -d --build

    Source Code Upgrade:

    1. git pull
    2. uv sync
    3. (Optional) Rebuild frontend: cd web && bun install && bun run build
    4. Restart your backend process manager.
  6. Handle Session Startup Events

    main

    The upstream service typically starts by returning a recovery or session token. Use the conversation_id to identify the session. Note that the token should be kept internal and not exposed to downstream users.

    {
      "type": "resume_conversation_token",
      "kind": "topic",
      "token": "...",
      "conversation_id": "..."
    }
  7. Handle Policy Refusals and Moderation

    main

    When a request is refused by policy or moderation, the behavior is as follows:

    Policy Refusal:

    • Often returns a standard assistant text refusal (e.g., "I can't assist with that request...").
    • May include a title_generation event with a title like Request Denied.
    • metadata.tool_invoked will be false.

    Moderation:

    • Returns a moderation event where moderation_response.blocked == true.
    • If blocked, prioritize returning the assistant text if available; otherwise, return an appropriate error message.
    {
      "type": "moderation",
      "moderation_response": {
        "blocked": true
      },
      "conversation_id": "..."
    }
  8. Deploy with WARP and FlareSolverr for stable proxying

    main

    If you encounter Cloudflare interceptions during image generation, use the WARP + Privoxy + FlareSolverr deployment scheme. This setup includes:

    • warp-proxy: Provides a WARP SOCKS5 exit.
    • privoxy: Converts WARP SOCKS5 to an HTTP proxy.
    • flaresolverr: Refreshes Cloudflare clearance.
    • init-config: Writes default proxy_runtime configuration.
    • app: The main ChatGPT2API service.

    By default, only upstream OpenAI/ChatGPT requests use the stable proxy. Account email and CPA auxiliary links are not forced through it. Proxy priority: Account-specific proxy > Stable proxy runtime > Explicit proxy > Old global proxy. You can adjust ports and parameters in .env or via the 'Stable Proxy Runtime' panel in the web settings.

    cp .env.example .env
    docker compose -f docker-compose.warp.yml up -d --build
  9. Deploy ChatGPT2API using standard Docker

    main

    Use this method if you do not require WARP or FlareSolverr to bypass Cloudflare protections.

    1. Clone the repository: git clone git@github.com:basketikun/chatgpt2api.git cd chatgpt2api
    2. Configure your authentication key. You can set auth-key in config.json or via the CHATGPT2API_AUTH_KEY environment variable in docker-compose.yml.
    3. Start the service: docker compose up -d

    Access the UI at http://localhost:3000 and the API at http://localhost:3000/v1.

    git clone git@github.com:basketikun/chatgpt2api.git
    cd chatgpt2api
    # Configure CHATGPT2API_AUTH_KEY in docker-compose.yml
    docker compose up -d
  10. Run ChatGPT2API from source

    main

    Suitable for local development or temporary debugging.

    Backend Setup: Requires uv for dependency management.

    git clone git@github.com:basketikun/chatgpt2api.git
    cd chatgpt2api
    uv sync
    uv run main.py

    Frontend Development: Requires bun.

    cd web
    bun install
    bun run dev

    When running from source, the backend reads config.json and the data/ directory from the project root.

    # Backend
    uv sync
    uv run main.py
    
    # Frontend
    cd web
    bun install
    bun run dev
  11. Identify Successful Image Generation Outputs

    main

    To avoid misidentifying input attachments as output images, only treat an asset_pointer as a successful image output if all the following conditions are met:

    1. message.author.role == "tool" (The source must be a tool message).
    2. metadata.async_task_type == "image_gen" (The task must be image generation).
    3. The asset_pointer is either file-service://... or sediment://....
    {
      "v": {
        "message": {
          "author": {"role": "tool"},
          "content": {
            "content_type": "multimodal_text",
            "parts": [
              {"asset_pointer": "file-service://file_result"},
              {"asset_pointer": "sediment://file_result"}
            ]
          },
          "metadata": {"async_task_type": "image_gen"}
        }
      },
      "conversation_id": "..."
    }