async function checkProduct(product, deps) { const { fetchAndExtractPrice, fetchAndExtractPriceViaBrowser, sendMail, recordCheckSuccess, recordCheckFailure, now, } = deps; let result = await fetchAndExtractPrice(product.url); if ((result.error || result.price == null) && fetchAndExtractPriceViaBrowser) { result = await fetchAndExtractPriceViaBrowser(product.url); } if (result.error) { console.error(`[check] fetch_error "${product.name}" (${product.url}): ${result.error.message}`); recordCheckFailure(product.id, 'fetch_error'); return { status: 'fetch_error' }; } if (result.price == null) { console.error(`[check] not_found "${product.name}" (${product.url}): geen prijs gevonden op de pagina`); recordCheckFailure(product.id, 'not_found'); return { status: 'not_found' }; } const isBaseline = product.last_price == null; const changed = !isBaseline && result.price !== product.last_price; if (changed) { try { await sendMail({ name: product.name, url: product.url, oldPrice: product.last_price, newPrice: result.price, }); } catch (err) { console.error(`[check] mail_error "${product.name}" (${product.url}): ${err && err.message}`); recordCheckFailure(product.id, 'mail_error'); return { status: 'mail_error' }; } } recordCheckSuccess(product.id, { price: result.price, checkedAt: now() }); return { status: 'ok', changed }; } async function checkAllProducts(products, deps) { const results = []; for (const product of products) { try { const result = await checkProduct(product, deps); results.push({ productId: product.id, ...result }); } catch (err) { console.error(`[check] error "${product.name}" (${product.url}): ${err && err.message}`); results.push({ productId: product.id, status: 'error', error: err }); } } return results; } module.exports = { checkProduct, checkAllProducts };