operator_template.js 1.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162
  1. /*
  2. Sub-Store operator (production-friendly)
  3. - Pull dynamic domain from your current_domain.json
  4. - Replace vmess server field for matched nodes
  5. */
  6. const DOMAIN_JSON_URL = "https://your-host.example.com/current_domain.json";
  7. const NODE_NAME_REGEX = /(argo|cf|vm|优选)/i;
  8. const CACHE_KEY = "vmess-domain-rotator:current";
  9. const CACHE_TTL_MS = 5 * 60 * 1000;
  10. async function fetchDomainViaSubStore() {
  11. const $ = $substore;
  12. const { body, statusCode } = await $.http.get({
  13. url: DOMAIN_JSON_URL,
  14. headers: {
  15. Accept: "application/json",
  16. "Cache-Control": "no-cache"
  17. },
  18. timeout: 5000
  19. });
  20. if (statusCode < 200 || statusCode >= 300) {
  21. throw new Error(`http status ${statusCode}`);
  22. }
  23. const obj = JSON.parse(body || "{}");
  24. const domain = String(obj.domain || "").trim().toLowerCase();
  25. if (!domain) {
  26. throw new Error("empty domain field");
  27. }
  28. return domain;
  29. }
  30. async function operator(proxies = [], targetPlatform, context) {
  31. const cache = scriptResourceCache;
  32. let domain = cache.get(CACHE_KEY);
  33. if (!domain) {
  34. try {
  35. domain = await fetchDomainViaSubStore();
  36. cache.set(CACHE_KEY, domain, CACHE_TTL_MS);
  37. } catch (e) {
  38. console.log(`[vmess-domain-rotator] fetch failed: ${e.message}`);
  39. return proxies;
  40. }
  41. }
  42. let updated = 0;
  43. for (const p of proxies) {
  44. if (!p || p.type !== "vmess") continue;
  45. if (!NODE_NAME_REGEX.test(p.name || "")) continue;
  46. if (p.server !== domain) {
  47. p.server = domain;
  48. updated += 1;
  49. }
  50. }
  51. console.log(`[vmess-domain-rotator] domain=${domain}, updated=${updated}, total=${proxies.length}, target=${targetPlatform}`);
  52. return proxies;
  53. }