/** * Connect to Chrome CDP relay, navigate to DIA medios-de-pago-y-promociones, * and capture ALL network responses looking for promo/legal data. */ 'use strict'; const WS_URL = 'ws://127.0.0.1:18792/cdp'; const TOKEN = '0537d84a67f2e43b525964bb43d93f6dfae1ec1b50946455'; const TARGET_URL = 'https://diaonline.supermercadosdia.com.ar/medios-de-pago-y-promociones'; const ws_mod = require('/usr/lib/node_modules/openclaw/node_modules/ws'); const WS = ws_mod.WebSocket || ws_mod; const ws = new WS(WS_URL, { headers: { 'x-openclaw-relay-token': TOKEN } }); let msgId = 1; function send(sessionId, method, params = {}) { const msg = { id: msgId++, method, params }; if (sessionId) msg.sessionId = sessionId; ws.send(JSON.stringify(msg)); } let sessionId = null; const pending = new Map(); // requestId → request info const captured = []; ws.on('open', () => { console.log('Relay connected'); // Get list of targets send(null, 'Target.getTargets'); }); ws.on('message', raw => { const msg = JSON.parse(raw); const sid = msg.sessionId || null; // Response to getTargets → find a page target and attach if (msg.id === 1 && msg.result?.targetInfos) { const pages = msg.result.targetInfos.filter(t => t.type === 'page'); console.log('Pages:', pages.map(p => p.url).join(' | ')); const target = pages[0]; if (!target) { console.log('No page target!'); ws.close(); return; } send(null, 'Target.attachToTarget', { targetId: target.targetId, flatten: true }); return; } // Attached → enable Network + Page if (msg.result?.sessionId && !sessionId) { sessionId = msg.result.sessionId; console.log('Attached, sessionId:', sessionId); send(sessionId, 'Network.enable'); send(sessionId, 'Page.enable'); // Navigate to DIA promo page send(sessionId, 'Page.navigate', { url: TARGET_URL }); return; } if (!msg.method) return; // Track request start if (msg.method === 'Network.requestWillBeSent') { const { requestId, request, type } = msg.params; const url = request.url; const skip = ['analytics','gtm','facebook','hotjar','amplitude','segment', '.js?','chunk-','common.min','.css','.png','.jpg','.svg','.woff', 'vtexassets','vteximg','cloudfront']; if (!skip.some(s => url.includes(s))) { pending.set(requestId, { url, method: request.method, type }); } return; } // Capture responses if (msg.method === 'Network.responseReceived') { const { requestId, response } = msg.params; const req = pending.get(requestId); if (!req) return; const ct = response.headers['content-type'] || response.headers['Content-Type'] || ''; if (ct.includes('json') || req.url.includes('graphql') || req.url.includes('/api/')) { // Get body send(sessionId, 'Network.getResponseBody', { requestId }); pending.set(requestId, { ...req, responseId: msgId - 1, status: response.status }); } return; } // Collect body if (msg.result?.body !== undefined) { // Match to a pending request — find by correlating (bodies come back in order) // We'll just stash by checking all pending const body = msg.result.body; if (!body || body.length < 20) return; const lower = body.toLowerCase(); const kws = ['descuento','discount','promo','banco','tarjeta','reintegro','cuota','vigencia','legal','bancari','titular','oferta','medio']; const hits = kws.filter(w => lower.includes(w)).length; captured.push({ body, hits, len: body.length, base64: msg.result.base64Encoded }); return; } // Page loaded → wait 5s then dump if (msg.method === 'Page.loadEventFired') { console.log('Page loaded, waiting 5s for async requests...'); setTimeout(() => { // Also try clicking "ver legales" buttons send(sessionId, 'Runtime.evaluate', { expression: ` // Find all "ver legales" buttons and click the first const btns = [...document.querySelectorAll('button,a,[role="button"]')] .filter(el => el.textContent.toLowerCase().includes('legal') || el.textContent.toLowerCase().includes('ver más')); console.log('Found', btns.length, 'legal buttons'); btns.slice(0,3).forEach(b => b.click()); btns.length + ' buttons clicked: ' + btns.slice(0,3).map(b=>b.textContent.trim().slice(0,30)).join(' | ') `, returnByValue: true }); setTimeout(dump, 3000); }, 5000); return; } if (msg.method === 'Runtime.consoleAPICalled') { console.log('[browser console]', msg.params.args.map(a => a.value || a.description || '').join(' ')); } if (msg.result?.result?.value !== undefined) { console.log('[eval result]', msg.result.result.value); } }); function dump() { console.log('\n=== CAPTURED', captured.length, 'JSON responses ==='); const interesting = captured.filter(c => c.hits >= 2).sort((a,b) => b.hits - a.hits); console.log('Responses with 2+ keyword hits:', interesting.length); interesting.forEach((c, i) => { console.log(`\n--- Response ${i+1} (hits=${c.hits}, len=${c.len}) ---`); const preview = c.base64 ? Buffer.from(c.body, 'base64').toString('utf8') : c.body; console.log(preview.slice(0, 800)); }); ws.close(); } ws.on('error', e => console.error('WS error:', e.message)); ws.on('close', () => { console.log('Relay closed'); process.exit(0); }); // Safety timeout setTimeout(() => { dump(); }, 30000);