← back to Watches
crawler-with-notifications.js
104 lines
#!/usr/bin/env node
/**
* Slow Crawler with Steve Notifications
* Runs continuously, notifies CEO on every successful crawl
*/
import SlowCrawler from './utils/slow-crawler.js';
import fs from 'fs';
import path from 'path';
import { fileURLToPath } from 'url';
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
const STEVE_WEBHOOK = 'http://localhost:9800/api/webhook/message';
const MUSEUM_URL = 'http://45.61.58.125:7600/museum/';
const PROGRESS_FILE = path.join(__dirname, 'museum/crawl-data/progress.json');
let lastNotifiedCount = 0;
async function notifySteve(progress) {
try {
const totalResults = progress.results?.length || 0;
// Only notify if we have new results
if (totalResults === 0 || totalResults === lastNotifiedCount) {
return;
}
const totalValue = progress.results.reduce((sum, r) => sum + (r.price || 0), 0);
const message = {
from: 'Omega Watch Museum Crawler',
type: 'success',
priority: 'normal',
subject: `🏛️ Museum Update: ${totalResults} Omega Watches Found`,
body: `
**Slow Crawler Progress Update**
✅ **${totalResults} museum-quality pieces** cataloged
💰 **Total value:** $${totalValue.toLocaleString()}
📊 **Pages crawled:** ${progress.currentPage}
🔗 **View museum:** ${MUSEUM_URL}
**Top 5 Most Expensive:**
${progress.results
.sort((a, b) => b.price - a.price)
.slice(0, 5)
.map((w, i) => `${i + 1}. ${w.title.substring(0, 60)}... - $${w.price.toLocaleString()} (${w.source})`)
.join('\n')}
Updated: ${new Date(progress.lastUpdate).toLocaleString()}
`.trim(),
timestamp: new Date().toISOString()
};
const response = await fetch(STEVE_WEBHOOK, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(message)
});
if (response.ok) {
console.log(`✅ Notified Steve: ${totalResults} results, $${totalValue.toLocaleString()} total`);
lastNotifiedCount = totalResults;
}
} catch (error) {
console.error('⚠️ Failed to notify Steve:', error.message);
}
}
async function startCrawlerWithNotifications() {
const crawler = new SlowCrawler({
interval: 60000, // 60 seconds between requests
maxPages: 500 // Crawl 500 pages
});
// Override saveProgress to add notifications
const originalSaveProgress = crawler.saveProgress.bind(crawler);
crawler.saveProgress = function() {
originalSaveProgress();
// Read the saved progress and notify Steve
if (fs.existsSync(PROGRESS_FILE)) {
const progress = JSON.parse(fs.readFileSync(PROGRESS_FILE, 'utf8'));
notifySteve(progress).catch(console.error);
}
};
console.log('🏛️ Starting Museum Crawler with Steve Notifications');
console.log(`📨 Will notify Steve at: ${STEVE_WEBHOOK}`);
console.log(`🌐 Museum URL: ${MUSEUM_URL}\n`);
try {
await crawler.startSlowCrawl();
console.log('\n✅ Crawler completed successfully!');
} catch (error) {
console.error('\n❌ Crawler failed:', error);
process.exit(1);
}
}
startCrawlerWithNotifications();