204 lines
6.9 KiB
TypeScript
204 lines
6.9 KiB
TypeScript
// Monitor Templates - Pre-configured monitoring setups for popular sites
|
|
|
|
export interface MonitorTemplate {
|
|
id: string;
|
|
name: string;
|
|
description: string;
|
|
category: 'ecommerce' | 'social' | 'news' | 'dev' | 'business' | 'other';
|
|
icon: string;
|
|
urlPattern: string; // Regex pattern for URL matching
|
|
urlPlaceholder: string; // Example URL with placeholder
|
|
selector?: string;
|
|
ignoreRules: Array<{
|
|
type: 'css' | 'regex' | 'text';
|
|
value: string;
|
|
description?: string;
|
|
}>;
|
|
keywordRules?: Array<{
|
|
keyword: string;
|
|
type: 'appears' | 'disappears' | 'count_increases' | 'count_decreases';
|
|
}>;
|
|
frequency: number; // in minutes
|
|
}
|
|
|
|
export const monitorTemplates: MonitorTemplate[] = [
|
|
// E-Commerce
|
|
{
|
|
id: 'amazon-price',
|
|
name: 'Amazon Product Price',
|
|
description: 'Track price changes on Amazon product pages',
|
|
category: 'ecommerce',
|
|
icon: '🛒',
|
|
urlPattern: 'amazon\\.(com|de|co\\.uk|fr|es|it)/.*dp/[A-Z0-9]+',
|
|
urlPlaceholder: 'https://amazon.com/dp/PRODUCTID',
|
|
selector: '#priceblock_ourprice, .a-price .a-offscreen, #corePrice_feature_div .a-price-whole',
|
|
ignoreRules: [
|
|
{ type: 'css', value: '#nav, #rhf, #navFooter', description: 'Navigation and footer' },
|
|
{ type: 'css', value: '.a-carousel, #recommendations', description: 'Recommendations' },
|
|
{ type: 'regex', value: '\\d+ customer reviews?', description: 'Review count changes' }
|
|
],
|
|
frequency: 60
|
|
},
|
|
{
|
|
id: 'ebay-price',
|
|
name: 'eBay Listing Price',
|
|
description: 'Monitor eBay listing prices and availability',
|
|
category: 'ecommerce',
|
|
icon: '🏷️',
|
|
urlPattern: 'ebay\\.(com|de|co\\.uk)/itm/',
|
|
urlPlaceholder: 'https://www.ebay.com/itm/ITEMID',
|
|
selector: '.x-price-primary',
|
|
ignoreRules: [
|
|
{ type: 'css', value: '#vi-VR, #STORE_INFORMATION', description: 'Store info' }
|
|
],
|
|
frequency: 30
|
|
},
|
|
|
|
// Developer Tools
|
|
{
|
|
id: 'github-releases',
|
|
name: 'GitHub Releases',
|
|
description: 'Get notified when new releases are published',
|
|
category: 'dev',
|
|
icon: '📦',
|
|
urlPattern: 'github\\.com/[\\w-]+/[\\w-]+/releases',
|
|
urlPlaceholder: 'https://github.com/owner/repo/releases',
|
|
selector: '.release, [data-hpc] .Box-row',
|
|
ignoreRules: [
|
|
{ type: 'css', value: 'footer, .js-stale-session-flash', description: 'Footer' }
|
|
],
|
|
keywordRules: [
|
|
{ keyword: 'Latest', type: 'appears' }
|
|
],
|
|
frequency: 360 // 6 hours
|
|
},
|
|
{
|
|
id: 'npm-package',
|
|
name: 'NPM Package',
|
|
description: 'Track new versions of NPM packages',
|
|
category: 'dev',
|
|
icon: '📦',
|
|
urlPattern: 'npmjs\\.com/package/[\\w@/-]+',
|
|
urlPlaceholder: 'https://www.npmjs.com/package/package-name',
|
|
selector: '#top h3, .css-1t74l4c',
|
|
ignoreRules: [
|
|
{ type: 'css', value: 'footer, .downloads', description: 'Footer and download stats' }
|
|
],
|
|
frequency: 1440 // Daily
|
|
},
|
|
|
|
// News & Content
|
|
{
|
|
id: 'reddit-thread',
|
|
name: 'Reddit Thread',
|
|
description: 'Monitor a Reddit thread for new comments',
|
|
category: 'social',
|
|
icon: '📰',
|
|
urlPattern: 'reddit\\.com/r/\\w+/comments/',
|
|
urlPlaceholder: 'https://www.reddit.com/r/subreddit/comments/...',
|
|
ignoreRules: [
|
|
{ type: 'regex', value: '\\d+ points?', description: 'Vote counts' },
|
|
{ type: 'regex', value: '\\d+ (minute|hour|day)s? ago', description: 'Timestamps' }
|
|
],
|
|
frequency: 30
|
|
},
|
|
{
|
|
id: 'hackernews-front',
|
|
name: 'Hacker News Front Page',
|
|
description: 'Track top stories on Hacker News',
|
|
category: 'news',
|
|
icon: '📰',
|
|
urlPattern: 'news\\.ycombinator\\.com/?$',
|
|
urlPlaceholder: 'https://news.ycombinator.com/',
|
|
selector: '.titleline',
|
|
ignoreRules: [
|
|
{ type: 'regex', value: '\\d+ points?', description: 'Points' },
|
|
{ type: 'regex', value: '\\d+ comments?', description: 'Comment count' }
|
|
],
|
|
frequency: 60
|
|
},
|
|
|
|
// Business & Jobs
|
|
{
|
|
id: 'job-board',
|
|
name: 'Job Board',
|
|
description: 'Monitor job postings on a company career page',
|
|
category: 'business',
|
|
icon: '💼',
|
|
urlPattern: '.*/(careers?|jobs?)/?$',
|
|
urlPlaceholder: 'https://company.com/careers',
|
|
ignoreRules: [
|
|
{ type: 'css', value: 'footer, nav, header', description: 'Navigation' }
|
|
],
|
|
keywordRules: [
|
|
{ keyword: 'Senior', type: 'appears' },
|
|
{ keyword: 'Remote', type: 'appears' }
|
|
],
|
|
frequency: 360 // 6 hours
|
|
},
|
|
{
|
|
id: 'competitor-pricing',
|
|
name: 'Competitor Pricing',
|
|
description: 'Track competitor pricing page changes',
|
|
category: 'business',
|
|
icon: '💰',
|
|
urlPattern: '.*/pricing/?$',
|
|
urlPlaceholder: 'https://competitor.com/pricing',
|
|
selector: '.price, .pricing-card, [class*="price"]',
|
|
ignoreRules: [
|
|
{ type: 'css', value: 'footer, nav', description: 'Navigation' }
|
|
],
|
|
frequency: 1440 // Daily
|
|
},
|
|
|
|
// Generic
|
|
{
|
|
id: 'generic-page',
|
|
name: 'Generic Web Page',
|
|
description: 'Monitor any web page for changes',
|
|
category: 'other',
|
|
icon: '🌐',
|
|
urlPattern: '.*',
|
|
urlPlaceholder: 'https://example.com/page',
|
|
ignoreRules: [
|
|
{ type: 'css', value: 'script, style, noscript', description: 'Scripts' }
|
|
],
|
|
frequency: 60
|
|
}
|
|
];
|
|
|
|
/**
|
|
* Find matching templates for a given URL
|
|
*/
|
|
export function findMatchingTemplates(url: string): MonitorTemplate[] {
|
|
return monitorTemplates.filter(template => {
|
|
try {
|
|
const regex = new RegExp(template.urlPattern, 'i');
|
|
return regex.test(url);
|
|
} catch {
|
|
return false;
|
|
}
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Get templates by category
|
|
*/
|
|
export function getTemplatesByCategory(category: MonitorTemplate['category']): MonitorTemplate[] {
|
|
return monitorTemplates.filter(t => t.category === category);
|
|
}
|
|
|
|
/**
|
|
* Apply a template to create monitor configuration
|
|
*/
|
|
export function applyTemplate(template: MonitorTemplate, url: string) {
|
|
return {
|
|
url,
|
|
name: `${template.name} Monitor`,
|
|
frequency: template.frequency,
|
|
elementSelector: template.selector || null,
|
|
ignoreRules: template.ignoreRules,
|
|
keywordRules: template.keywordRules || [],
|
|
};
|
|
}
|