# Client-Side Fetch Workaround for Permanent IP Block

When the server's datacenter IP is permanently blocked by WeChat (200013 freq control) and no proxy platform is accessible (Deno/Cloudflare/Vercel all blocked from user's network), the fallback is to run the fetch script on the user's local machine (Windows/Mac), where the residential IP won't be blocked.

## Architecture

```
User's Windows Machine (residential IP ✅)
  │
  ├─ fetches from mp.weixin.qq.com/cgi-bin/appmsgpublish
  │  (uses valid cookie/token from server's Redis)
  │
  └─ POSTs articles to server's import API
     http://120.53.228.229:8650/api/articles/import
```

## Server Side Setup

1. **Import API server** — receives articles and writes to the we-mp-rss database:
   ```bash
   cd ~/project/scripts && python3 article_import_api.py 8650
   ```
   The script listens on `0.0.0.0:8650`, accepts POST with JSON `{"secret": "...", "articles": [...]}`.

2. **Database path**: `/home/ubuntu/project/we-mp-rss-data/db.db`

3. **Secret authentication**: A simple shared secret (`SECRET` variable in both server and client scripts) prevents unauthorized writes.

## Client Script

The Windows script lives at two locations:
- **Source/editing**: `~/project/scripts/fetch_wechat_windows.py`
- **Downloadable copy** (must be placed here to be accessible via `files.gdcjgk.net`): `~/.hermes/fetch_articles.py`

The HTTP server on port 8088 (`files.gdcjgk.net` via Cloudflare tunnel) serves from `/home/ubuntu/.hermes/` directly — **not** from `~/.hermes/static/`. Any file placed in `~/.hermes/` is immediately available at `https://files.gdcjgk.net/<filename>`.

Key script behavior:
- Contains hardcoded cookie and token (user must fill in from their own browser's WeChat MP session — server's own cookie/token won't work because the server IP is blocked)
- Fetches from both feeds (中职生, 广东中职菌)
- Up to 5 pages, 5 articles per page
- Random delays between pages (3-6s) and feeds (5-8s)
- Error handling: 200013 = freq control (skip), 200003 = invalid session (skip)
- Uploads results to server import API via POST to `http://120.53.228.229:8650/api/articles/import`
- POST body includes `secret` field required by the import API (`SECRET = "x9k2m8v7pL4q"`)
- **⚠️ Do NOT use `https://api.gdcjgk.net`** — that domain returns 403 from nginx. Use direct IP `http://120.53.228.229:8650` instead.

### Deploying/Updating the Downloadable Script

```bash
# Copy source to the served directory
cp ~/project/scripts/fetch_wechat_windows.py ~/.hermes/fetch_articles.py
# Verify it's accessible
curl -sI https://files.gdcjgk.net/fetch_articles.py | head -3  # should return 200
```

**⚠️ Common pitfall — "打不开" (can't open)**: When a user says they can't open `https://files.gdcjgk.net/<file>`, the most common cause is the file simply doesn't exist at `~/.hermes/<file>`. The HTTP server on port 8088 serves from `~/.hermes/`, so always check: `ls -la ~/.hermes/<file>` before investigating tunnel or network issues.

### User Instructions

1. Install Python 3 from python.org (check "Add Python to PATH")
2. `pip install requests` (in CMD or PowerShell)
3. Download `https://files.gdcjgk.net/fetch_articles.py`
4. **Edit the script** — open in Notepad, replace `COOKIE` and `TOKEN` placeholder values with the user's own WeChat MP browser session credentials (get these from Chrome DevTools → Application → Cookies → mp.weixin.qq.com, and Network tab for the token parameter)
5. Double-click to run
6. Script auto-uploads to server DB

## Verification

After script runs:
```bash
python3 -c "
import sqlite3; db = sqlite3.connect('/home/ubuntu/project/we-mp-rss-data/db.db')
for row in db.execute(\"SELECT f.mp_name, a.title, a.created_at FROM articles a JOIN feeds f ON a.mp_id=f.id ORDER BY a.created_at DESC LIMIT 5\"):
    print(row)
"
```

Check `sync_time` on feeds to confirm update.

## Limitations

- Requires user to run manually (not automated)
- Cookie/token in script expires (user must re-scan QR → regenerate script)
- Not scalable beyond 1-2 users
- Server import API must be accessible from user's network (firewall port 8650 open)

## Preferred Alternative

Deploy a proxy on Deno Deploy or Cloudflare Workers (see `references/china-proxy-platforms.md` and `references/deployctl-cli-deploy.md`). The client-side fetch is a fallback when all proxy platforms are inaccessible.
