import { getRedisClient, initNotifiedArticleKeys } from './redis.js'; import { broadcast } from './websocket.js'; import { sendPushNotifications } from './webPush.js'; import { ARTICLE_MONITORING } from '../config/constants.js'; let notifiedArticleKeys = new Set(); let articlesCheckInterval = null; // Función para detectar y enviar artículos nuevos async function checkForNewArticles() { const redisClient = getRedisClient(); if (!redisClient) { return; } try { const currentKeys = await redisClient.keys('notified:*'); const currentKeysSet = new Set(currentKeys); // Encontrar claves nuevas const newKeys = currentKeys.filter(key => !notifiedArticleKeys.has(key)); if (newKeys.length > 0) { // Obtener los artículos nuevos const newArticles = []; for (const key of newKeys) { try { const value = await redisClient.get(key); if (value) { // Intentar parsear como JSON let articleData = {}; try { articleData = JSON.parse(value); } catch (e) { // Si no es JSON válido, extraer información de la key const parts = key.split(':'); if (parts.length >= 3) { articleData = { platform: parts[1], id: parts.slice(2).join(':'), }; } } // Añadir información adicional si está disponible if (articleData.platform && articleData.id) { newArticles.push({ platform: articleData.platform || 'unknown', id: articleData.id || 'unknown', title: articleData.title || null, price: articleData.price || null, currency: articleData.currency || '€', url: articleData.url || null, images: articleData.images || [], }); } } } catch (error) { console.error(`Error obteniendo artículo de Redis (${key}):`, error.message); } } // Enviar artículos nuevos por WebSocket if (newArticles.length > 0) { broadcast({ type: 'new_articles', data: newArticles }); // Enviar notificaciones push para cada artículo nuevo for (const article of newArticles) { await sendPushNotifications({ title: `Nuevo artículo en ${article.platform?.toUpperCase() || 'Wallabicher'}`, body: article.title || 'Artículo nuevo disponible', icon: '/android-chrome-192x192.png', image: article.images?.[0] || null, url: article.url || '/', platform: article.platform, price: article.price, currency: article.currency || '€', id: article.id, }); } } // Actualizar el set de claves notificadas notifiedArticleKeys = currentKeysSet; } } catch (error) { console.error('Error verificando artículos nuevos:', error.message); } } // Inicializar el check de artículos cuando Redis esté listo export async function startArticleMonitoring() { const redisClient = getRedisClient(); if (redisClient) { // Inicializar claves conocidas notifiedArticleKeys = await initNotifiedArticleKeys(); // Iniciar intervalo para verificar nuevos artículos articlesCheckInterval = setInterval(checkForNewArticles, ARTICLE_MONITORING.CHECK_INTERVAL); console.log('✅ Monitoreo de artículos nuevos iniciado'); } } // Detener el monitoreo export function stopArticleMonitoring() { if (articlesCheckInterval) { clearInterval(articlesCheckInterval); articlesCheckInterval = null; } }