ai-chatbot/docs/nanobanana-browser-poc.md
Your Name 1fc37c4a8f
Some checks failed
Lint / build (20) (push) Has been cancelled
Playwright Tests / test (push) Has been cancelled
fix: improve style pro generation flow
2026-05-22 20:37:28 +08:00

189 lines
4.8 KiB
Markdown

# Nano Banana Browser POC
This repo includes a small browser-driven POC for inspecting Nano Banana's free-tool flow without trying to bypass Turnstile, login, or rate limits.
## What it does
- Opens the Nano Banana page in a real browser
- Optionally prefills a public image URL
- Optionally clicks the primary action button
- Captures requests and responses for the relevant private endpoints
- Saves screenshots, console logs, downloads, and browser storage state
## What it does not do
- It does not bypass Cloudflare Turnstile
- It does not bypass login
- It does not try to evade rate limits
- It is not a production API adapter
## Commands
Remove background:
```bash
pnpm poc:nanobanana --mode remove-background --auto-submit
```
Upscale:
```bash
pnpm poc:nanobanana --mode upscale --auto-submit
```
Use a custom image URL:
```bash
pnpm poc:nanobanana \
--mode upscale \
--image-url "https://example.com/demo.jpg" \
--auto-submit
```
## Useful flags
- `--locale en`
- `--headless`
- `--no-auto-fill`
- `--auto-submit`
- `--close-on-success`
- `--timeout-ms 300000`
- `--out-dir /absolute/path/to/output`
## Output
By default, artifacts are written to:
```text
playwright/nanobanana-poc/<mode>-<timestamp>/
```
The folder includes:
- `summary.json`
- `session-plan.json`
- `storage-state-initial.json`
- `storage-state-final.json`
- `requests/*.json`
- `responses/*.json`
- `logs/*.json`
- screenshots such as `01-loaded.png` and `99-final.png`
## Current endpoints observed
- `/api/img/rmbg`
- `/api/img/upscale`
- `/api/img/result/{taskId}?type=img`
- `/api/img/image-safety`
- `/api/presigned-urls`
## Current findings (2026-05-21)
These findings were confirmed from the live frontend bundle and manual browser validation.
### Remove background
Frontend schema:
- `imageSource`: `"upload"` or `"url"`
- `imageUrl`: optional string
- `turnstileToken`: optional string
Observed request shape:
```json
{
"imageSource": "url",
"imageUrl": "https://...",
"turnstileToken": "..."
}
```
Observed endpoint behavior:
- `POST /api/img/rmbg`
- `Content-Type: application/json`
- success path reads `response.data` as the final output image URL
- after success the page clears `turnstileToken`
- `403` with `message === "nsfw"` is handled as an NSFW block
Manual validation in the in-app browser produced a successful result and exposed a final image URL hosted on `replicate.delivery`, which suggests the private backend may fan out to third-party storage or processing before returning the final asset URL.
### Image upscaler
Frontend schema:
- `imageSource`: `"upload"` or `"url"`
- `imageUrl`: optional string
- `scale`: number, min `1`, max `8`, default `4`
- `turnstileToken`: optional string
Observed submit request shape:
```json
{
"imageUrl": "https://...",
"scale": "4",
"turnstileToken": "..."
}
```
Upload mode can also send an `image` field populated from the uploaded asset URL.
Observed endpoint behavior:
- `POST /api/img/upscale`
- `Content-Type: application/json`
- success path reads `taskId` from `response.data.taskId` or `response.taskId`
- the frontend then polls `GET /api/img/result/{taskId}?type=img`
- polling treats `code === 1` or `status === 1` as success
- final output is read from `data.imgAfterSrc` or `imgAfterSrc`
- polling treats `code === 2` or `status === 2` as failure
- the polling loop waits 2 seconds and retries up to 60 times
- `402` is handled as an upgrade/paywall condition
- `403` with `message === "nsfw"` is handled as an NSFW block
### Turnstile
Observed Cloudflare site key:
- `0x4AAAAAAAh8CLI0IWTYOWMY`
Observed frontend behavior:
- when `turnstileToken` is missing, the frontend renders or executes Turnstile before submitting
- after a successful request, the frontend clears `turnstileToken`
- this means the free-tool flow is not designed as a stable unattended API
### Upload helper
Observed upload helper behavior:
- `POST /api/presigned-urls` with JSON like `{ "count": 1, "fileType": "<mime>" }`
- response returns `urls`
- the browser `PUT`s the file to the returned presigned URL
- the frontend then derives a public asset URL in the form:
```text
https://temp.videostudioai.com/<key>
```
### Practical takeaway
This is enough to build an internal unofficial wrapper, but not enough to remove the core operational risk:
- the flow still depends on Turnstile
- Turnstile tokens are intentionally short-lived and cleared after use
- the frontend contract may change at any time
- upscaling still appears more likely to require session state than remove-background
## Suggested use
Use this only as an internal validation tool to answer questions like:
- Does the browser session create anonymous or guest state?
- When does Turnstile appear?
- Which cookies or local storage values appear before the request?
- Does upscaling require an authenticated session?
- What request and polling shape does the frontend use today?