--- name: Smiles via VM solver ADV-22 (porta 9091) 2026-05-02 description: Smiles funcionando via Chrome real na VM ADV-22 (Tailscale, IP residencial BH). Bypassa Akamai. SwiftShader + sem headless + Xvfb :99 = chave do sucesso. type: project originSessionId: da5514be-fbd6-46e5-a3de-cf03a5dda20d --- # Smiles Solver na VM ADV-22 — 2026-05-02 ## Problema Saída direta de internet do servidor 173.208.187.154 caiu (todos bridges :40500/40502/40504/40506/40508 timeout). Smiles 100% quebrada porque Camoufox precisava bridge proxy-seller. Bridge VM :40520 (tinyproxy) funcionava mas Akamai retornava 406 mesmo com cookies/headers/JA3 perfeitos. ## Descoberta-chave do Jesiel "Na VM funciona corretamente" — quando ele abria Chrome real DENTRO da VM (via VNC), Smiles aceitava. Confirmou que **IP não está bloqueado**, e sim que **Chrome puppeteer + tinyproxy** tem fingerprint diferente do Chrome navegando direto. Diferença está em pilha TCP/TLS/WebGL fingerprint, NÃO no IP. ## Solução implementada **1. Smiles Solver na VM ADV-22** (`/opt/smiles-solver/smiles-solver.mjs`) - Espelha arquitetura do tap-solver: `chromium.connectOverCDP` em Chrome stable filho - HTTP server porta **9091** (bind 0.0.0.0, alcançável via Tailscale) - Serviço systemd `smiles-solver.service` (ativo, restart auto) - Logs `/var/log/smiles-solver.log` - Cache 60min, MAX_CONCURRENT=4 **Flags Chrome cruciais:** ``` --remote-debugging-port=9224 --user-data-dir=/home/customer/smiles-chrome-profile --use-gl=swiftshader ← essencial: Akamai exige WebGL fingerprint --enable-unsafe-swiftshader --ignore-gpu-blocklist --enable-webgl --disable-blink-features=AutomationControlled --no-sandbox --lang=pt-BR --window-size=1920,1080 # SEM --headless (usa Xvfb :99) ``` Env: `DISPLAY=:99` **Fluxo searchSmiles:** 1. `page.goto('https://www.smiles.com.br')` warm-up 2. 3 ciclos de mouse/scroll humano (~5s) p/ validar `_abck~0~` 3. `page.goto(SPA_URL)` com params (`/mfe/emissao-passagem/?adults=...&originAirport=...`) 4. `page.on('response')` intercepta `api-air-flightsearch.../v1/airlines/search` 200 5. Retorna body cru ao caller, cache 60min **autoWarmup background**: setInterval mantém sessão quente (TTL 30min, refresh 8min). `_abck` permanece `~-1~` mesmo após sucesso, então usa `lastWarmupAt` timestamp. **Block resources** via `page.route`: image, font, media + datadog/voxus/zopim/hotjar/amplitude/optanon/googletagmanager/google-analytics/doubleclick. **2. Scraper Smiles servidor** (`/opt/skymilhas/scrapers/smiles/index.js`) `searchSmilesViaVMSolver(params)` chama `100.91.20.22:9091/search?...` e passa body cru para `parseSmilesResponse()` (parser intacto). Se `SMILES_USE_VM_SOLVER === '1'`: usa VM solver. Em prod: `SMILES_USE_VM_SOLVER=1 SMILES_VM_FALLBACK=0 SMILES_VM_TIMEOUT_MS=300000`. Backup `index.js.bak-pre-vmsolver-1777751900`. ## Performance V3 (versão atual) - 1ª busca pós-boot: 10s, 5 voos - OW (warm): 10s - RT ida+volta: 16s, 21 voos - Multi-pax 2A+1C+1I: 10s, 12 voos - OW intl GRU-MIA: 30s, 19 voos - Cache hit: 21ms - Stress 30 paralelas distintas com max=4: 100% sucesso ## Rollback ```bash sudo env SMILES_USE_VM_SOLVER=0 pm2 restart scraper-smiles-gol --update-env sudo cp /opt/skymilhas/scrapers/smiles/index.js.bak-pre-vmsolver-1777751900 /opt/skymilhas/scrapers/smiles/index.js sudo pm2 restart scraper-smiles-gol ``` ## Pendência **Saída direta servidor caída** (root cause não corrigida). Outros scrapers que dependem dos bridges proxy-seller estão timeout. Solução definitiva: arrumar saída direta (Hivelocity datacenter). **How to apply:** Para qualquer scraper futuro com Akamai/Cloudflare blocking proxy mas funcionando em Chrome real, criar solver dedicado na VM no padrão tap-solver/smiles-solver/gol-solver.