fix(relay): route USNI through residential proxy to bypass Cloudflare 403 (#1909)

Railway datacenter IPs are blocked by USNI's Cloudflare. Reuses the
existing ytFetchViaProxy/parseProxyUrl pattern with OREF_PROXY_AUTH.
Falls back to direct fetch when proxy is not configured (dev/local).

Replaces curl+proxy approach which failed because curl is not available
in Railway's Node.js container (ENOENT).
This commit is contained in:
Elie Habib
2026-03-20 10:33:18 +04:00
committed by GitHub
parent 95874c0582
commit b9f39bb8f3

View File

@@ -4389,12 +4389,23 @@ async function seedUsniFleet() {
console.log('[USNI] Fetching fleet tracker...');
const t0 = Date.now();
try {
const res = await fetch(USNI_URL, {
headers: { 'User-Agent': CHROME_UA, 'Accept': 'application/json' },
signal: AbortSignal.timeout(15000),
});
if (!res.ok) throw new Error(`HTTP ${res.status}`);
const wpData = await res.json();
// USNI (WordPress) returns 403 from Railway datacenter IPs via Cloudflare.
// Route through the residential proxy when available; fall back to direct for dev.
const proxyAuth = process.env.OREF_PROXY_AUTH || OREF_PROXY_AUTH;
let wpData;
if (proxyAuth) {
const proxy = parseProxyUrl(`http://${proxyAuth}`);
const result = proxy ? await ytFetchViaProxy(USNI_URL, proxy) : null;
if (!result || !result.ok) throw new Error(`proxy HTTP ${result?.status ?? 'unavailable'}`);
wpData = JSON.parse(result.body);
} else {
const res = await fetch(USNI_URL, {
headers: { 'User-Agent': CHROME_UA, 'Accept': 'application/json' },
signal: AbortSignal.timeout(15000),
});
if (!res.ok) throw new Error(`HTTP ${res.status}`);
wpData = await res.json();
}
if (!Array.isArray(wpData) || !wpData.length) throw new Error('No fleet tracker articles');
const post = wpData[0];