combine ready products in campaign payload
All checks were successful
Build and Deploy / build-and-deploy (push) Successful in 46s
All checks were successful
Build and Deploy / build-and-deploy (push) Successful in 46s
This commit is contained in:
@@ -111,21 +111,51 @@ const updateCampaignItemsStatus = async (ids, status, errorMessage = null) => {
|
|||||||
`, [status, errorMessage, ids]);
|
`, [status, errorMessage, ids]);
|
||||||
};
|
};
|
||||||
|
|
||||||
const sendWhatsappCampaign = async (baseProductName, items, customers) => {
|
const formatProductList = (productNames) => {
|
||||||
const totalDelta = items.reduce((sum, item) => sum + Number(item.delta_estoque || 0), 0);
|
if (productNames.length <= 2) {
|
||||||
|
return productNames.join(' e ');
|
||||||
|
}
|
||||||
|
|
||||||
const response = await fetch(N8N_WHATSAPP_TRIGGER_URL, {
|
return `${productNames.slice(0, -1).join(', ')} e ${productNames[productNames.length - 1]}`;
|
||||||
method: 'POST',
|
};
|
||||||
headers: { 'Content-Type': 'application/json' },
|
|
||||||
body: JSON.stringify({
|
const mapCampaignProducts = (groups) => {
|
||||||
|
return Object.entries(groups)
|
||||||
|
.sort(([, aItems], [, bItems]) => {
|
||||||
|
return new Date(aItems[0].created_at).getTime() - new Date(bItems[0].created_at).getTime();
|
||||||
|
})
|
||||||
|
.map(([baseProductName, items]) => {
|
||||||
|
const sortedItems = [...items].sort((a, b) => String(a.nome).localeCompare(String(b.nome), 'pt-BR'));
|
||||||
|
|
||||||
|
return {
|
||||||
baseProduct: baseProductName,
|
baseProduct: baseProductName,
|
||||||
total_delta: totalDelta,
|
total_delta: sortedItems.reduce((sum, item) => sum + Number(item.delta_estoque || 0), 0),
|
||||||
sizes: items.map(item => ({
|
sizes: sortedItems.map(item => ({
|
||||||
id: item.produto_id,
|
id: item.produto_id,
|
||||||
nome: item.nome,
|
nome: item.nome,
|
||||||
delta: item.delta_estoque,
|
delta: item.delta_estoque,
|
||||||
saldo: item.saldo
|
saldo: item.saldo
|
||||||
})),
|
})),
|
||||||
|
itemIds: sortedItems.map(item => item.id)
|
||||||
|
};
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const sendWhatsappCampaign = async (products, customers) => {
|
||||||
|
const productNames = products.map(product => product.baseProduct);
|
||||||
|
const productsText = formatProductList(productNames);
|
||||||
|
const allSizes = products.flatMap(product => product.sizes);
|
||||||
|
const totalDelta = products.reduce((sum, product) => sum + product.total_delta, 0);
|
||||||
|
|
||||||
|
const response = await fetch(N8N_WHATSAPP_TRIGGER_URL, {
|
||||||
|
method: 'POST',
|
||||||
|
headers: { 'Content-Type': 'application/json' },
|
||||||
|
body: JSON.stringify({
|
||||||
|
baseProduct: productsText,
|
||||||
|
productsText,
|
||||||
|
total_delta: totalDelta,
|
||||||
|
sizes: allSizes,
|
||||||
|
products: products.map(({ itemIds, ...product }) => product),
|
||||||
customers
|
customers
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
@@ -149,32 +179,30 @@ const processPendingStockCampaigns = async () => {
|
|||||||
return summary;
|
return summary;
|
||||||
}
|
}
|
||||||
|
|
||||||
const customers = await getTopBuyersAllTime();
|
|
||||||
const groups = rows.reduce((acc, row) => {
|
const groups = rows.reduce((acc, row) => {
|
||||||
if (!acc[row.base_product_name]) acc[row.base_product_name] = [];
|
if (!acc[row.base_product_name]) acc[row.base_product_name] = [];
|
||||||
acc[row.base_product_name].push(row);
|
acc[row.base_product_name].push(row);
|
||||||
return acc;
|
return acc;
|
||||||
}, {});
|
}, {});
|
||||||
|
const products = mapCampaignProducts(groups);
|
||||||
for (const [baseProductName, items] of Object.entries(groups)) {
|
const ids = products.flatMap(product => product.itemIds);
|
||||||
const ids = items.map(item => item.id);
|
const customers = await getTopBuyersAllTime();
|
||||||
|
|
||||||
if (!customers.length) {
|
if (!customers.length) {
|
||||||
await updateCampaignItemsStatus(ids, 'skipped', 'No customers with valid phone numbers found.');
|
await updateCampaignItemsStatus(ids, 'skipped', 'No customers with valid phone numbers found.');
|
||||||
summary.skippedGroups += 1;
|
summary.skippedGroups = products.length;
|
||||||
continue;
|
return summary;
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await sendWhatsappCampaign(baseProductName, items, customers);
|
await sendWhatsappCampaign(products, customers);
|
||||||
await updateCampaignItemsStatus(ids, 'sent');
|
await updateCampaignItemsStatus(ids, 'sent');
|
||||||
summary.sentGroups += 1;
|
summary.sentGroups = products.length;
|
||||||
console.log(`[Campaign Queue] Sent ${baseProductName} campaign to ${customers.length} all-time top buyers.`);
|
console.log(`[Campaign Queue] Sent one campaign with ${products.length} products to ${customers.length} all-time top buyers.`);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
await updateCampaignItemsStatus(ids, 'failed', error.message);
|
await updateCampaignItemsStatus(ids, 'failed', error.message);
|
||||||
summary.failedGroups += 1;
|
summary.failedGroups = products.length;
|
||||||
console.error(`[Campaign Queue] Failed to send ${baseProductName} campaign:`, error);
|
console.error('[Campaign Queue] Failed to send product list campaign:', error);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return summary;
|
return summary;
|
||||||
|
|||||||
Reference in New Issue
Block a user