Sem descrição

vmess-domain-rotator 2fc33ff524 chore: rotate preferred domain to cf.1o.ee (2026-04-14T10:55:49Z) há 3 semanas atrás
runtime 2fc33ff524 chore: rotate preferred domain to cf.1o.ee (2026-04-14T10:55:49Z) há 3 semanas atrás
scripts 81fffdf9bf fix: for auto submit há 3 semanas atrás
substore 80f5aedc5a fix: change link for domain.json há 3 semanas atrás
systemd 5fe072703d first init há 3 semanas atrás
AGENTS.md 5fe072703d first init há 3 semanas atrás
README.md 81fffdf9bf fix: for auto submit há 3 semanas atrás
config.json 08edadfe49 fix: change logical selection há 3 semanas atrás

README.md

vmess-domain-rotator

This repo provides a first working version of an automated pipeline:

  1. Pull preferred domains from an API (like vps789).
  2. Validate and optionally health-check candidates.
  3. Pick the best domain automatically.
  4. Export runtime files for Sub-Store and V2Ray integration.

Quick start

  1. Edit config.json directly (single runtime config file).

For your sample response (data.good[].ip), parser config can be:

"parser": {
  "field_paths": ["data.good[].ip"],
  "json_paths": [],
  "regex": "[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}"
}

For vps789 Top20 ranking, if you want "directly use first ranked domain":

"scoring": {
  "enabled": true,
  "records_path": "data.good[]",
  "ip_field": "ip",
  "created_time_field": "createdTime",
  "within_hours": 24,
  "use_api_order": true
}

Then set:

"healthcheck": { "enabled": false }
  1. Run once:

    python3 scripts/domain_updater.py --config config.json
    
  2. Check output files:

  • runtime/current_domain.txt
  • runtime/current_domain.json
  • runtime/state.json

What the script exports

  • current_domain.txt: plain text domain.
  • current_domain.json: machine-readable payload:

    {
    "domain": "best.example.com",
    "updated_at": "2026-04-13T07:00:00Z",
    "status": "ok",
    "source_count": 15,
    "checked_count": 10
    }
    
  • state.json: includes last_good_domain for automatic fallback.

If you need Sub-Store to fetch these files over HTTP, you can expose runtime/ via nginx or caddy.

How to connect with Sub-Store

Two practical modes:

  1. Recommended: run updater externally and let Sub-Store operator fetch current_domain.json.
  2. Keep Sub-Store static and update V2Ray template directly (token replacement).

substore/operator_template.js is a starter operator script showing how to replace VMess server fields by regex match on node names.

Minimal smoke test (local):

python3 -m http.server 8080 --directory runtime

Then test:

curl http://127.0.0.1:8080/current_domain.json

How to connect with V2Ray

If you maintain a template config (containing __AUTO_DOMAIN__ token), this script can render a real config file with the selected domain.

Then reload service:

systemctl reload v2ray

Update Base64 VMess links

If your node list uses vmess://<base64-json>, use:

python3 scripts/update_vmess_links.py \
  --input ./nodes.txt \
  --output ./nodes.updated.txt \
  --domain-file ./runtime/current_domain.txt

Only update specific node names (ps) by regex:

python3 scripts/update_vmess_links.py \
  --input ./nodes.txt \
  --output ./nodes.updated.txt \
  --domain-file ./runtime/current_domain.txt \
  --name-regex "(argo|cf|vm)"

If the whole subscription file is itself base64-encoded, add:

--subscription-base64

Scheduling

Cron

0 */12 * * * /bin/bash /opt/vmess-domain-rotator/scripts/run_update_and_commit.sh /opt/vmess-domain-rotator/config.json >> /var/log/vmess-domain-rotator.log 2>&1

systemd timer

Use files under systemd/ and adjust paths/user. Default timer interval in this repo is 12h.

Debian install/uninstall scripts

Install on a Debian server (creates systemd service+timer):

sudo bash scripts/install_debian.sh

If you run this inside a git clone, installer now defaults to in-place mode (service uses current repo path), so auto-commit writes to your real repo. To force copy deployment under /opt, set --app-dir explicitly.

This installer also initializes a git repo under app dir (if missing) and configures the service to auto-commit only when selected domain changes.

Uninstall:

sudo bash scripts/uninstall_debian.sh

Useful options:

sudo bash scripts/install_debian.sh --user root --group root --interval 5min
sudo bash scripts/install_debian.sh --app-dir /opt/vmess-domain-rotator
sudo bash scripts/uninstall_debian.sh --keep-app-dir

Config notes

  • API response formats differ. Use one of:
    • parser.json_paths (preferred)
    • parser.regex fallback
  • If API has occasional bad results, keep healthcheck.enabled=true.
  • If API may return IPv4 addresses, consider healthcheck.tls_verify=false.
  • If all checks fail, script falls back to last known good domain.

About Sub-Store "config file location"

If you use Sub-Store web UI, rules are usually stored in backend data storage (sqlite/json), not a simple editable config file.

Common deployment cases:

  • Docker: check mounted volume path, then back up that volume.
  • Node/PM2: check app directory data/ or database file.

In practice, you can avoid touching backend db files directly:

  1. Keep your node logic in Sub-Store operator script (web UI).
  2. Let operator fetch current_domain.json from this project.
  3. Dynamic replacement happens at subscription processing time.

Security and reliability

  • Do not commit API tokens.
  • Use reverse proxy auth if exposing current_domain.json publicly.
  • Keep runtime/state.json persisted (for fallback).