Files
travel-app/src/app/api/jobs/trigger-daily-check/route.ts

59 lines
1.8 KiB
TypeScript

import { NextResponse } from 'next/server';
import { query } from '@/lib/db';
export const runtime = 'nodejs';
export const dynamic = 'force-dynamic';
export async function POST() {
try {
const bullmq = typeof window === 'undefined' ? eval('require')('bullmq') : null;
if (!bullmq || !bullmq.Queue) {
throw new Error('BullMQ Queue Klasse konnte nicht geladen werden.');
}
const { Queue } = bullmq;
const connection = {
host: process.env.REDIS_HOST || '172.17.0.1',
port: parseInt(process.env.REDIS_PORT || '6379', 10),
connectTimeout: 5000,
maxRetriesPerRequest: 3,
};
const scrapeQueue = new Queue('scrape-jobs', { connection });
const res = await query('SELECT id, booking_url FROM hotels WHERE is_active = true');
const activeHotels = res.rows;
if (activeHotels.length === 0) {
await scrapeQueue.close();
return NextResponse.json({
success: true,
message: 'Keine aktiven Hotels zum Scrapen gefunden.',
});
}
// Für ALLE aktiven Hotels nur den Preis-Scan anwerfen (OHNE n8n / OHNE LLM)
for (const hotel of activeHotels) {
const appWebhookUrl = `http://172.17.0.1:3002/api/webhooks/scraper?hotelId=${hotel.id}`;
await scrapeQueue.add('scrape-hotel', {
hotelId: hotel.id,
url: hotel.booking_url,
appWebhookUrl, // Speichert den Preis in Postgres
webhookUrl: null, // KEIN n8n -> KOSTENLOS!
});
}
await scrapeQueue.close();
return NextResponse.json({
success: true,
message: `Preis-Scan für ${activeHotels.length} Hotels gestartet.`,
});
} catch (error: any) {
console.error('Fehler beim Starten des Preis-Scans:', error);
return NextResponse.json({ success: false, error: error.message }, { status: 500 });
}
}