Want to know instantly when someone comments on your blog or beats your game high score? Here's how I built a zero-cost notification system that sends alerts straight to Telegramโno third-party services, no monthly fees, just a simple Python script and Linux cron.
๐ Before You Start
- Your blog already saves comments/high scores to JSON files (e.g.,
~/blog-comments/data/) - You have SSH access to your VPS
- You can create a Telegram bot (or reuse an existing one)
- Basic comfort with copying/pasting commands
The Architecture
The script doesn't constantly watch the files. Every 2 minutes cron wakes it up, it compares the file's last-modified time against a hidden .last-check file, and only sends a message if something new appeared.
Why This Design?
- Zero API costs: Only HTTP calls to Telegram (free). No external services.
- Self-hosted: Everything runs on your VPS. No third-party notification services.
- Simple: File timestamp checking is fast and cheap. No database polling.
- Secure: Bot token stored in a config file, never in code.
The Setup
1. Create a Telegram Bot
- Open Telegram, search for
@BotFather - Send
/newbotand follow prompts - Copy your bot token (looks like:
123456789:ABCdef...)
2. Get Your Chat ID
This is the number the bot will message. The easiest way:
- In Telegram, search for
@getmyid_bot(or@userinfobot) - Tap Start
- The bot will instantly reply with your Chat ID (a number like
123456789)
๐ก Pro tip: If you already use OpenClaw with Telegram, your chat ID is already saved in ~/.openclaw/.env. Just open that file and copy the TELEGRAM_CHAT_ID value. It's the same ID for every bot you create.
3. Store Credentials Securely
# Create/edit the config file
nano ~/.openclaw/.env
# Add these lines:
TELEGRAM_BOT_TOKEN=your_token_here
TELEGRAM_CHAT_ID=your_chat_id_here
# Set permissions (only you can read it)
chmod 600 ~/.openclaw/.env
๐ Security: Never commit this file to git. Add it to your .gitignore. The token gives full control of your bot to anyone who has it.
4. The Notification Script
Here's the core logic that runs every 2 minutes:
#!/usr/bin/env python3
"""Check for new comments/highscores and notify via Telegram."""
import os
import json
from datetime import datetime
COMMENTS_FILE = "~/blog-comments/data/comments.json"
LAST_CHECK_FILE = "~/blog-comments/data/.last-check"
def check_for_updates():
if not os.path.exists(LAST_CHECK_FILE):
return False # First run initialization
last_check = os.path.getmtime(LAST_CHECK_FILE)
json_mtime = os.path.getmtime(COMMENTS_FILE)
if json_mtime <= last_check:
return False # No changes
# Read and find new comments
with open(COMMENTS_FILE) as f:
comments = json.load(f)
new_items = [c for c in comments
if parse_timestamp(c['timestamp']) > last_check]
if new_items:
send_telegram_notification(new_items)
# Update timestamp
os.utime(LAST_CHECK_FILE, None)
return True
๐ Note: The code above is simplified core logic. The full working script (including the parse_timestamp() and send_telegram_notification() helper functions) is available in ~/blog-comments/scripts/check_new.py. The version shown here focuses on the key ideas.
5. Add the Cron Job
# Edit crontab
crontab -e
# Add this line (runs every 2 minutes)
# IMPORTANT: Use full path, not ~/
*/2 * * * * /usr/bin/python3 /home/yourusername/blog-comments/scripts/check_new.py >> /tmp/notifications.log 2>&1
Tip: Replace /home/yourusername with your actual home path (type echo $HOME to check). The log file in /tmp/ auto-clears on rebootโperfect for testing.
Testing It Works
- Post a test comment on any blog post
- Wait 2 minutes (or run manually:
python3 ~/blog-comments/scripts/check_new.py) - Check Telegram for notification
Expected comment notification:
๐ฌ New Comment
๐ ๐ Blog: Telegram Notifications Setup
Username: Great article! Very helpful...
๐ ๐ Book: Zero to One
Reader: Loved this book review!
Expected high score notification:
๐ New High Score
๐ฎ 2048
Player1: 25,000 pts
๐ฎ Crypto Breakout
Gamer42: 15,500 pts
Check logs: tail -f /tmp/notifications.log
Cost Breakdown
- Cron execution: Free (system scheduler)
- File I/O: Free (local disk)
- Telegram API: Free (standard HTTP requests)
- Total cost: $0.00
Managing Comments
Comments are stored in ~/blog-comments/data/comments.json. I created an admin script to manage them:
# List all comments
python3 ~/blog-comments/scripts/admin_comments.py list
# Filter by type
python3 ~/blog-comments/scripts/admin_comments.py list --type blog
# Search for text
python3 ~/blog-comments/scripts/admin_comments.py search "inappropriate"
# Delete by ID
python3 ~/blog-comments/scripts/admin_comments.py delete abc123
# Show statistics
python3 ~/blog-comments/scripts/admin_comments.py stats
To manually delete:
# Backup first
cp ~/blog-comments/data/comments.json ~/blog-comments/data/comments.json.bak
# Delete by ID
python3 -c "
import json
with open('$HOME/blog-comments/data/comments.json') as f:
data = json.load(f)
data = [c for c in data if c['id'] != 'THE_ID']
with open('$HOME/blog-comments/data/comments.json', 'w') as f:
json.dump(data, f, indent=2)
"
๐ก Note: Deleting comments doesn't affect the notification script. It simply reads the file each time it runs.
Extending It
- Add high score notifications (same pattern)
- Send digests instead of instant alerts
- Add filtering (only notify on certain content types)
- Integrate with other services (Discord, Slack webhooks)
Troubleshooting
- No notification after 2 minutes? โ Run the script manually:
python3 ~/blog-comments/scripts/check_new.py - Check logs:
tail -f /tmp/notifications.log - Still nothing? โ Make sure the
.envfile is readable by the cron user and contains the correctTELEGRAM_CHAT_ID - Wrong chat ID? โ Message
@getmyid_botagain to confirm your ID
Summary
This setup gives you instant notifications for zero cost. It's completely self-hosted, uses no external AI APIs, and runs entirely on your existing VPS infrastructure.
The patternโfile timestamp checking with cronโis useful for any event-driven notification system. Same approach works for: log monitoring, file uploads, backup completion, certificate expiration, and more.
๐ฌ Comments