DouBao2Api/README_EN.md

11 KiB
Raw Blame History

DouBao2Api

A Dockerized solution that converts the web version of Doubao (doubao.com) into an OpenAI-compatible API. It uses VNC + Playwright to simulate real human browser interaction — sending messages indirectly and capturing replies — while exposing a standard /v1/chat/completions endpoint.

How It Works

┌──────────────────────────────────────────────────────────┐
│                   Docker Container (RockyLinux 9)         │
│                                                          │
│  ┌─────────┐   ┌──────────┐   ┌──────────┐   ┌────────┐ │
│  │  Xvfb   │──│  openbox  │──│ Chromium  │──│Playwright│ │
│  │ Virtual  │  │ Window Mgr │  │ Browser   │  │ Automation│ │
│  │ Display  │  └──────────┘   └──────────┘   └────────┘ │
│  └─────────┘                                          │   │
│       │          ┌──────────┐                        │   │
│       └──────────│  x11vnc  │◄───────────────────────┘   │
│                  │ VNC Server│                            │
│                  └────┬─────┘                            │
│                       │                                  │
│                  ┌────┴─────┐    ┌──────────┐           │
│                  │websockify│──│  noVNC   │           │
│                  │  Proxy    │  │ Web Client│           │
│                  └──────────┘  └──────────┘           │
│                                                          │
│                  ┌──────────────────────┐               │
│                  │  FastAPI (port 8000)   │               │
│                  │  OpenAI-compatible API  │               │
│                  └──────────────────────┘               │
└──────────────────────────────────────────────────────────┘
      │              │              │
      ▼              ▼              ▼
  API :8000     VNC :5900      noVNC :6080

Core flow: API receives request → Playwright operates the Doubao page in Chromium (type message, press Enter) → DOM polling captures streaming reply → returned as SSE or JSON.

Features

  • OpenAI-compatible: Standard /v1/chat/completions endpoint with both streaming (SSE) and non-streaming responses
  • VNC visualization: Real-time browser view via noVNC web client, with view-only/interactive toggle
  • Anti-detection: Playwright stealth script hides webdriver flags, simulates human typing delays
  • Session persistence: Login state saved via storage_state to a Docker volume — no re-login after restart
  • Chat reuse: Reuses the current chat session by default to reduce risk control triggers; supports on-demand new chat creation
  • Debug endpoint: /inspect returns page DOM structure for easy selector adaptation

Quick Start

1. Build & Start

docker compose build
docker compose up -d

2. Login to Doubao

After the container starts, open noVNC in your browser:

http://localhost:6080/vnc.html

VNC password: doubao123 (configurable via VNC_PASSWORD in docker-compose.yml)

noVNC defaults to view-only mode (to prevent accidental interaction). Uncheck "View Only" in the left sidebar settings to switch to interactive mode.

Log in to your Doubao account in the Chromium browser within VNC. Make sure you can see the chat input box.

3. Save Login State

curl -X POST http://localhost:8000/login/save

4. Call the API

# Non-streaming
curl http://localhost:8000/v1/chat/completions \
  -H "Authorization: Bearer sk-your-api-key-here" \
  -H "Content-Type: application/json" \
  -d '{"model":"doubao-pro","messages":[{"role":"user","content":"Hello"}]}'

# Streaming
curl http://localhost:8000/v1/chat/completions \
  -H "Authorization: Bearer sk-your-api-key-here" \
  -H "Content-Type: application/json" \
  -d '{"model":"doubao-pro","messages":[{"role":"user","content":"Hello"}],"stream":true}'

Configuration

All settings are configured via environment variables in docker-compose.yml or .env:

Variable Default Description
API_KEY sk-your-api-key-here API authentication key; clients must send Authorization: Bearer <key> header
API_PORT 8000 API service port
VNC_PASSWORD doubao123 VNC connection password
VNC_VIEW_ONLY false Force x11vnc server-side view-only (true blocks all input even if noVNC unchecks View Only)
VNC_PORT 5900 Direct VNC port
NOVNC_PORT 6080 noVNC web client port
DOUBAO_URL https://www.doubao.com/chat/ Doubao chat page URL
BROWSER_HEADLESS false Run browser in headless mode (must be false for VNC)
RESPONSE_TIMEOUT 120 Response timeout in seconds
TYPING_DELAY_MIN 30 Minimum typing delay (ms per character)
TYPING_DELAY_MAX 80 Maximum typing delay (ms per character)
INTER_MESSAGE_DELAY 0.5 Delay before sending message (seconds)
SCREEN_WIDTH 1280 Virtual screen width
SCREEN_HEIGHT 720 Virtual screen height
SCREEN_DEPTH 24 Virtual screen color depth
LOG_LEVEL INFO Log level

API Reference

POST /v1/chat/completions

OpenAI-compatible chat endpoint.

Parameter Type Default Description
model string doubao-pro Model name
messages array required Message array, same format as OpenAI
stream bool false Enable SSE streaming response
new_chat bool false Start a new chat session (custom extension field)

GET /v1/models

Returns the list of supported models.

GET /login/status

Check current Doubao login status.

POST /login/save

Persist current browser state (cookies, storage) to disk.

POST /chat/new

Explicitly start a new Doubao chat session.

GET /inspect

Return current page DOM structure for debugging selectors.

GET /vnc/mode

Get current VNC mode (viewonly or interactive).

POST /vnc/mode

Switch VNC mode (server-side enforcement):

# Switch to interactive mode
curl -X POST http://localhost:8000/vnc/mode \
  -H "Authorization: Bearer sk-your-api-key-here" \
  -H "Content-Type: application/json" \
  -d '{"mode":"interactive"}'

# Switch to view-only mode
curl -X POST http://localhost:8000/vnc/mode \
  -H "Authorization: Bearer sk-your-api-key-here" \
  -H "Content-Type: application/json" \
  -d '{"mode":"viewonly"}'

POST /browser/restart

Restart the browser session.

GET /health

Health check endpoint.

VNC Modes

Two layers of view-only control:

Layer Control Default Description
Client noVNC sidebar "View Only" checkbox Checked (read-only) Uncheck to switch to interactive instantly; refresh restores read-only
Server API POST /vnc/mode interactive viewonly mode makes x11vnc reject all input, even if the client unchecks View Only

For daily use, the client layer is sufficient. For stronger enforcement (prevent any VNC client from interacting), use the API to switch the server-side mode.

Project Structure

DouBao2Api/
├── Dockerfile                 # Docker image build file
├── docker-compose.yml         # Container orchestration
├── requirements.txt            # Python dependencies
├── .env.example               # Environment variable template
├── app/
│   ├── __init__.py
│   ├── config.py              # Configuration management (pydantic-settings)
│   ├── models.py              # OpenAI-compatible data models
│   ├── browser_manager.py     # Playwright browser management
│   ├── doubao.py              # Doubao page interaction logic
│   └── main.py                # FastAPI service entry point
└── scripts/
    ├── entrypoint.sh          # Container entrypoint script
    ├── supervisord.conf       # Process management config
    ├── start_wm.sh            # Window manager startup script
    └── start_x11vnc.sh        # x11vnc startup script (view-only/interactive toggle)

Process Architecture

Five processes managed by supervisord inside the container, started by priority:

Priority Process Description
10 Xvfb Virtual framebuffer X server
20 openbox Lightweight window manager
30 x11vnc VNC server, maps Xvfb display
40 websockify WebSocket proxy, provides noVNC web access
50 uvicorn FastAPI application server

Troubleshooting

Build failure: package not found

This project is based on RockyLinux 9. RHEL 10 / RockyLinux 10 removed X11 server packages and does not support this approach. Docker containers are independent of the host OS — running an RL9 container on an RL10 host is fully compatible.

API returns empty response

Doubao frontend updates may break CSS selectors. Call GET /inspect to view the current DOM structure, then update the selector constants in app/doubao.py.

"Not logged in" error

You must first log in to Doubao through the VNC browser, then call POST /login/save to persist the state. Use GET /login/status to check login status.

VNC cannot interact

Make sure "View Only" is unchecked in the noVNC sidebar. If still unable to interact, check server-side mode: GET /vnc/mode. If it returns viewonly, use the API to switch to interactive.

Tech Stack

  • RockyLinux 9 — Container base OS
  • Xvfb + x11vnc + noVNC — Virtual display and remote viewing
  • Playwright — Browser automation
  • FastAPI + Uvicorn — API service
  • Supervisor — Process management
  • websockify — VNC over WebSocket proxy

Disclaimer

This project is for educational and research purposes only. Please ensure compliance with Doubao's terms of service before use. The author is not responsible for any direct or indirect consequences arising from the use of this project.