const dotenv = require("dotenv"); dotenv.config(); const axios = require("axios"); const { sleep } = require("./sleepService"); // Configure sua API_KEY e COOKIE aqui ou via variáveis de ambiente const API_URL = process.env.API_URL; const API_KEY = process.env.API_KEY; const COOKIE = process.env.COOKIE; const HEADERS = { "api-key": API_KEY, Cookie: COOKIE, }; // small fetch wrapper for external services (ViaCEP etc.) with basic rate-limiting const BASE_BACKOFF_MS = 10; // backoff inicial para retry const MAX_RETRIES = 5; async function getMinDistance(lat, lon) { const radii = [5000, 10000, 20000]; for (const raio of radii) { let attempt = 0; while (attempt < MAX_RETRIES) { try { // observe que aqui enviamos itens[] como string simples (algumas APIs esperam isto) const resp = await axios.get(API_URL, { headers: HEADERS, params: { raio, latitude: lat, longitude: lon, "itens[]": "caixa", consultarPasta: "S", }, timeout: 10000, }); const data = resp.data || {}; const registros = data.registros || []; console.log(data.registros[0]); console.info( `[INFO] API resp. raio=${raio} lat=${lat} lon=${lon} registros=${registros.length}` ); if (registros.length > 0) { // same extraction logic as before const candidates = registros .map((r) => ({ raw: r, distanciaRaw: r && r.distancia })) .map((o) => ({ raw: o.raw, num: o.distanciaRaw !== undefined && o.distanciaRaw !== null && o.distanciaRaw !== "" ? Number(o.distanciaRaw) : null, })) .filter((x) => x.num !== null && !Number.isNaN(x.num)); if (candidates.length) { candidates.sort((a, b) => a.num - b.num); const best = candidates[0]; // Retornamos apenas a distância — a lógica de pasta/sigla foi removida const r = best.raw || {}; return { dist: best.num }; } } else { // log mais detalhado para diagnóstico quando vazio console.debug( `[DEBUG] resposta vazia para raio=${raio} lat=${lat} lon=${lon} -> primeiroFragmento: ${JSON.stringify( Array.isArray(data.registros) ? data.registros.slice(0, 3) : data )}` ); } // sem distancias válidas para este raio -> tenta próximo raio break; } catch (err) { attempt += 1; if (err.response && err.response.status === 429) { const ra = err.response.headers && (err.response.headers["retry-after"] || err.response.headers["Retry-After"]); let waitMs = BASE_BACKOFF_MS * Math.pow(2, attempt - 1); if (ra) { const raSec = parseInt(ra, 10); if (!isNaN(raSec)) waitMs = raSec * 1000; } console.warn( `[WARN] 429 recebido para ${lat},${lon} - aguardando ${waitMs}ms e tentando novamente (attempt ${attempt}/${MAX_RETRIES})` ); await sleep(waitMs); continue; } const waitMs = BASE_BACKOFF_MS * Math.pow(2, attempt - 1); console.warn( `[WARN] Erro ao consultar API para ${lat},${lon}: ${err.message} - backoff ${waitMs}ms (attempt ${attempt}/${MAX_RETRIES})` ); await sleep(waitMs); } } // pequena espera entre mudanças de raio await sleep(50); } console.info(`[INFO] Sem registros válidos para ${lat},${lon} após todos os raios`); return null; } module.exports = { getMinDistance };