116 lines
3.8 KiB
JavaScript
116 lines
3.8 KiB
JavaScript
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;
|
|
}
|
|
}
|
|
|
|
|