diff --git a/backend/index.js b/backend/index.js index 89b7737..e095296 100644 --- a/backend/index.js +++ b/backend/index.js @@ -199,6 +199,10 @@ app.post('/api/data', authenticateAPIKey, async (req, res) => { })(); }); +// In-memory Waiting Room for WhatsApp Marketing +const waitingRoom = {}; +const N8N_WHATSAPP_TRIGGER_URL = process.env.N8N_WHATSAPP_TRIGGER_URL || 'http://localhost:5678/webhook/whatsapp'; + // POST stock (for n8n) app.post('/api/stock', authenticateAPIKey, async (req, res) => { res.status(201).json({ message: 'Stock data received, processing in background' }); @@ -225,13 +229,91 @@ app.post('/api/stock', authenticateAPIKey, async (req, res) => { const idProduto = item.idProduto || item.ID_Produto || ''; if (!idProduto) continue; + const delta = parseInt(item.delta_estoque) || 0; + const nomeStr = item.nome || item.Descricao_Produto || 'Unknown'; + const values = [ String(idProduto), - item.nome || item.Descricao_Produto || 'Unknown', + nomeStr, parseInt(item.saldo) || 0, - parseInt(item.delta_estoque) || 0 + delta ]; await client.query(insertQuery, values); + + // Waiting Room / Debounce Logic + if (delta >= 100) { + const baseProductName = nomeStr.split(' TAMANHO')[0].trim(); + + if (!waitingRoom[baseProductName]) { + console.log(`[Waiting Room] Nova entrada: ${baseProductName}. Iniciando timer de 30m...`); + waitingRoom[baseProductName] = { + total_delta: 0, + items: [], + timeout: null + }; + } else { + console.log(`[Waiting Room] Atualização: ${baseProductName}. Timer reiniciado (30m).`); + } + + waitingRoom[baseProductName].total_delta += delta; + waitingRoom[baseProductName].items.push({ + id: String(idProduto), + nome: nomeStr, + delta: delta, + saldo: parseInt(item.saldo) || 0 + }); + + if (waitingRoom[baseProductName].timeout) { + clearTimeout(waitingRoom[baseProductName].timeout); + } + + waitingRoom[baseProductName].timeout = setTimeout(async () => { + try { + const aggData = waitingRoom[baseProductName]; + delete waitingRoom[baseProductName]; // Clear from waiting room + + console.log(`[Waiting Room] Timer finalizado para ${baseProductName}. Buscando top buyers...`); + + // Find Top 100 buyers for this Base Product + const topBuyersQuery = ` + SELECT + MAX(cliente_nome) as nome, + cliente_fone as fone, + SUM(quantidade) as total_comprado + FROM orders + WHERE produto_descricao LIKE $1 + AND cliente_fone IS NOT NULL + AND cliente_fone != '' + GROUP BY cliente_fone + ORDER BY total_comprado DESC + LIMIT 100; + `; + const topBuyersResult = await pool.query(topBuyersQuery, [`${baseProductName}%`]); + + // Only trigger if we actually have buyers + if (topBuyersResult.rows.length > 0) { + console.log(`[Waiting Room] Disparando webhook do WhatsApp para ${topBuyersResult.rows.length} clientes (${baseProductName})...`); + fetch(N8N_WHATSAPP_TRIGGER_URL, { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ + baseProduct: baseProductName, + total_delta: aggData.total_delta, + sizes: aggData.items, + customers: topBuyersResult.rows + }) + }).then(res => { + if(res.ok) console.log(`[Waiting Room] Sucesso! Webhook disparado.`); + else console.log(`[Waiting Room] Aviso: Webhook retornou status ${res.status}`); + }).catch(err => console.error("Failed to trigger WhatsApp webhook:", err)); + } else { + console.log(`[Waiting Room] Nenhum cliente encontrado com telefone válido para ${baseProductName}. Webhook cancelado.`); + } + } catch (err) { + console.error("Error in Waiting Room timeout:", err); + } + }, 1800000); // 30 minutes + } } await client.query('COMMIT');