Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion config.example.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"mail.google.com",
"accounts.google.com"
],
"script_id": "YOUR_APPS_SCRIPT_DEPLOYMENT_ID",
"script_id": "YOUR_APPS_SCRIPT_DEPLOYMENT_ID", // Or a list for round-robin: ["ID1", "ID2"],
"auth_key": "CHANGE_ME_TO_A_STRONG_SECRET",
"listen_host": "127.0.0.1",
"http_port": 8085,
Expand Down
2 changes: 1 addition & 1 deletion docs/ARCHITECTURE.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ The network sees a Google-facing connection. The relay request carries the real
- Warm TLS connection pool for H1 fallback.
- HTTP/2 multiplexing when the `h2` package is installed.
- Batching for static sub-resource bursts.
- Optional multiple `script_ids` for load balancing.
- Optional multiple `script_id` for round-robin load balancing.
- Optional range-parallel download acceleration for large files.
- Optional exit node for destinations that block Google egress.

Expand Down
5 changes: 2 additions & 3 deletions docs/CONFIGURATION.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,10 @@ Most users only need `script_id`, `auth_key`, and the default local ports. This

| Setting | Meaning |
|---------|---------|
| `script_id` | Your Google Apps Script Deployment ID. Use this for one deployment. |
| `script_ids` | Array of Deployment IDs for load balancing. Use instead of `script_id`. |
| `script_id` | Your Google Apps Script Deployment ID. Can be a single string or an array of strings for round-robin load balancing. |
| `auth_key` | Shared password. Must match `AUTH_KEY` inside [apps_script/Code.gs](../apps_script/Code.gs). |

If you use `script_ids`, every deployed copy of [apps_script/Code.gs](../apps_script/Code.gs) must use the same `AUTH_KEY`.
If you use multiple IDs in `script_id`, every deployed copy of [apps_script/Code.gs](../apps_script/Code.gs) must use the same `AUTH_KEY`.

## Proxy Binding

Expand Down
4 changes: 2 additions & 2 deletions docs/TROUBLESHOOTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ Fix:
1. Create a new Apps Script deployment.
2. Copy the new Deployment ID into `config.json`.
3. Confirm the deployment is a Web App with **Execute as: Me** and **Who has access: Anyone**.
4. If quota is exhausted, wait for the quota reset or add more deployments with `script_ids`.
4. If quota is exhausted, wait for the quota reset or add more deployments by providing a list of IDs in `script_id`.

## Page Looks Like Random Characters

Expand Down Expand Up @@ -105,7 +105,7 @@ Try these in order:

1. Install all dependencies from [requirements.txt](../requirements.txt), especially `h2`.
2. Run `python main.py --scan` and update `google_ip`.
3. Deploy multiple Apps Script projects and use `script_ids`.
3. Deploy multiple Apps Script projects and use a list of IDs in `script_id`.
4. Keep `log_level` at `INFO` unless debugging.
5. Use an exit node only when needed, because it adds another hop.

Expand Down
2 changes: 1 addition & 1 deletion docs/fa/ARCHITECTURE.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ Browser یا app
- pool گرم اتصال TLS برای fallback H1.
- HTTP/2 multiplexing وقتی package `h2` نصب باشد.
- batch کردن درخواست‌های static در burst ها.
- چند `script_ids` اختیاری برای load balancing.
- چند `script_id` اختیاری برای load balancing به صورت round-robin.
- دانلود موازی range برای فایل‌های بزرگ.
- Exit Node اختیاری برای مقصدهایی که خروجی Google را مسدود می‌کنند.

Expand Down
5 changes: 2 additions & 3 deletions docs/fa/CONFIGURATION.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,10 @@

| تنظیم | معنی |
|-------|------|
| `script_id` | Deployment ID مربوط به Google Apps Script. برای یک deployment استفاده می‌شود. |
| `script_ids` | آرایه‌ای از چند Deployment ID برای load balancing. به جای `script_id` استفاده می‌شود. |
| `script_id` | Deployment ID مربوط به Google Apps Script. می‌تواند یک رشته متنی باشد یا آرایه‌ای از رشته‌ها برای load balancing به صورت round-robin. |
| `auth_key` | رمز مشترک. باید دقیقا با `AUTH_KEY` داخل [apps_script/Code.gs](../../apps_script/Code.gs) یکی باشد. |

اگر از `script_ids` استفاده می‌کنید، همه deployment ها باید `AUTH_KEY` یکسان داشته باشند.
اگر از چندین ID در `script_id` استفاده می‌کنید، همه deployment ها باید `AUTH_KEY` یکسان داشته باشند.

## اتصال پراکسی

Expand Down
16 changes: 12 additions & 4 deletions main.py
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,8 @@ def main():
if os.environ.get("DFT_AUTH_KEY"):
config["auth_key"] = os.environ["DFT_AUTH_KEY"]
if os.environ.get("DFT_SCRIPT_ID"):
config["script_id"] = os.environ["DFT_SCRIPT_ID"]
val = os.environ["DFT_SCRIPT_ID"]
config["script_id"] = [x.strip() for x in val.split(",") if x.strip()] if "," in val else val

# CLI argument overrides
if args.port is not None:
Expand Down Expand Up @@ -218,7 +219,14 @@ def main():

# Always Apps Script mode — force-set for backward-compat configs.
config["mode"] = "apps_script"
sid = config.get("script_ids") or config.get("script_id")

# Consolidate script_id and script_ids into a single smart field.
sids = config.get("script_ids") or config.get("script_id")
if sids:
config["script_id"] = sids
config.pop("script_ids", None)

sid = config.get("script_id")
if not sid or (isinstance(sid, str) and sid == "YOUR_APPS_SCRIPT_DEPLOYMENT_ID"):
print("Missing 'script_id' in config.")
print("Deploy the Apps Script from Code.gs and paste the Deployment ID.")
Expand All @@ -241,9 +249,9 @@ def main():

log.info("Apps Script relay : SNI=%s → script.google.com",
config.get("front_domain", "www.google.com"))
script_ids = config.get("script_ids") or config.get("script_id")
script_ids = config.get("script_id")
if isinstance(script_ids, list):
log.info("Script IDs : %d scripts (sticky per-host)", len(script_ids))
log.info("Script IDs : %d scripts (round-robin)", len(script_ids))
for i, sid in enumerate(script_ids):
_s = str(sid)
masked = f"{_s[:6]}…{_s[-4:]}" if len(_s) > 12 else _s
Expand Down
8 changes: 4 additions & 4 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -111,10 +111,10 @@ def configure_apps_script(cfg: dict) -> dict:
ids = [x.strip() for x in ids_raw.split(",") if x.strip()]
if len(ids) == 1:
cfg["script_id"] = ids[0]
cfg.pop("script_ids", None)
else:
cfg["script_ids"] = ids
cfg.pop("script_id", None)
elif len(ids) > 1:
cfg["script_id"] = ids

cfg.pop("script_ids", None)
return cfg


Expand Down
Loading