Overview
The Price Tracker Bot is built as a single-threaded Node.js application that combines multiple components:- Telegram Bot Interface (node-telegram-bot-api)
- Web Scraper (Playwright with Chromium)
- Scheduled Tasks (node-cron)
- File-based Persistence (JSON storage)
- Chart Generation (Chart.js + Playwright)
Core Components
1. Bot Initialization
The bot initializes using the Telegram Bot API with long polling:index.mjs:11-17
The bot uses environment variables for configuration. If
TELEGRAM_TOKEN is missing, the process exits with an error.2. Event Handlers
The bot registers several event handlers for user commands:| Command | Handler Location | Description |
|---|---|---|
/start | index.mjs:359-381 | Welcome message and chat registration |
/add [url] | index.mjs:398-467 | Add product to tracking |
/check | index.mjs:470-486 | Force immediate price check |
/list | index.mjs:489 | Display tracked products |
/remove [url] | index.mjs:520-542 | Remove product from tracking |
/edit [old] [new] | index.mjs:545-610 | Update product URL |
/chart [url] | index.mjs:613-623 | Generate price history chart |
/stats | index.mjs:492-517 | Display tracking statistics |
Callback Query Handler
Inline keyboard buttons trigger callback queries processed atindex.mjs:626-702:
3. Cron Jobs
Two scheduled tasks run automatically:Daily Summary (20:00)
index.mjs:720-730
Automatic Price Checks (Every 2 hours)
index.mjs:733-740
Cron expressions use server timezone. Adjust according to deployment environment.
4. Persistence Layer
Data is stored in a single JSON file (prices.json):
index.mjs:20-50
Data is loaded on startup (
index.mjs:50) and saved after every mutation.5. Web Scraper
The scraper uses Playwright with Chromium in headless mode:index.mjs:73-136
See Web Scraping for detailed implementation.
6. Chart Generator
Charts are generated using Chart.js rendered in a headless browser:index.mjs:253-307
Data Flow
Adding a Product
Flow steps:- User sends
/add [url] - URL is sanitized using
sanitizeAmazonURL()(index.mjs:53-61) - Check if product already tracked
- Launch temporary browser instance
- Scrape product using
scrapeProduct()(index.mjs:73-136) - Create product object with initial history entry
- Save to
priceDataand persist to disk - Send confirmation to user
Price Check Cycle
Flow steps (index.mjs:139-250):
- Launch single browser instance (reused for all products)
- Iterate through all tracked products
- Scrape current price for each product
- Compare
scraped.pricewithstored.price - If price dropped:
- Calculate savings and percentage
- Build notification message
- Send to all registered chats
- Update product data:
- Append to
historyarray - Update
lowestPriceif applicable - Update
lastCheckedtimestamp
- Append to
- Save data to disk
- Close browser
The bot processes products sequentially with 900ms delays to avoid rate limiting (
index.mjs:214).Error Handling
Scraping Errors
When scraping fails, the function returns an error object:index.mjs:165-172
Bot Errors
Global error handlers prevent crashes:index.mjs:715-716
Graceful Shutdown
index.mjs:743-750
Performance Considerations
Browser Instance Management
Single vs Multiple Browsers
Single vs Multiple Browsers
During price checks: A single browser instance is launched and reused for all products to reduce overhead.For user commands: Temporary browsers are launched per request and closed immediately after.
Rate Limiting
Delays are inserted between operations:- Between products during checks: 900ms (
index.mjs:214) - Between notifications: 500ms (
index.mjs:242) - Between daily summaries: 400ms (
index.mjs:725)
Memory Management
- History limit: Only the last 120 price points are kept per product (
index.mjs:69) - Browser cleanup: All browser instances are explicitly closed after use
- Data persistence: In-memory data is immediately synced to disk
Utility Functions
URL Sanitization
Removes query parameters and hash fragments:index.mjs:53-61
Example:
Markdown Escaping
Prevents Telegram markdown parsing errors:index.mjs:64-66
All user-facing text containing product titles or prices is escaped before sending to Telegram.
Configuration
Environment Variables
TELEGRAM_TOKEN(required): Bot token from BotFather
Constants
Chromium Launch Arguments
Deployment Considerations
Production Checklist
Production Checklist
- Set
TELEGRAM_TOKENenvironment variable - Install Playwright browsers:
npx playwright install chromium - Ensure write permissions for
prices.json - Configure timezone for cron jobs
- Monitor memory usage (Chromium instances)
- Set up process manager (PM2, systemd)
- Enable logging (consider Winston or Pino)
- Implement backup strategy for
prices.json
Extension Points
Adding New Commands
Register command handlers using regex patterns:Supporting Other E-commerce Sites
ModifyscrapeProduct() to detect domain and use appropriate selectors:
Alternative Storage Backends
ReplaceloadData() and saveData() with database operations: