feat: add observability logs to stock waiting room for easier debugging in Portainer
All checks were successful
Build and Deploy / build-and-deploy (push) Successful in 2m8s
All checks were successful
Build and Deploy / build-and-deploy (push) Successful in 2m8s
This commit is contained in:
@@ -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');
|
||||
|
||||
Reference in New Issue
Block a user