Skip to content

AmmarSalmi/slavewatch

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

SlaveWatch — Reddit-to-Telegram Notification Bot

A production-ready Telegram bot that monitors subreddits and pushes new post notifications to subscribed users, with per-user keyword filtering.


Features

  • 🔍 Subreddit monitoring — Admins add/remove subreddits; the bot polls them every N minutes via APScheduler.
  • 📬 Per-user keyword filters — Each user independently chooses:
    • Inclusive mode — receive posts only if the title contains one of their keywords.
    • Exclusive mode — receive all posts except those matching blocked keywords.
    • No filter — receive everything (default).
  • 🔄 Duplicate guard — A seen_posts table prevents the same post being sent twice.
  • Fully asyncaiosqlite for DB, asyncio.to_thread() for PRAW, AsyncIOScheduler for polling.
  • 🛡️ Graceful shutdown — Catches SIGINT/SIGTERM, stops the scheduler, closes the DB cleanly.

Tech Stack

Component Library
Telegram python-telegram-bot v21 (async)
Reddit PRAW 7
Database SQLite via aiosqlite
Scheduler APScheduler 3 (AsyncIOScheduler)
Config python-dotenv

Project Structure

slavewatch/
├── bot/
│   ├── main.py          ← entry point, bot setup, scheduler
│   ├── config.py        ← env vars and constants
│   ├── db.py            ← SQLite schema + async DB helpers
│   ├── reddit.py        ← PRAW wrapper + polling logic
│   ├── handlers.py      ← Telegram command/callback handlers
│   ├── filters.py       ← keyword filter matching (pure functions)
│   └── notifications.py ← format and send post alerts
├── requirements.txt
├── .env.example
└── README.md

Setup

1. Clone and create a virtual environment

git clone <repo-url> slavewatch
cd slavewatch
python3.11 -m venv .venv
source .venv/bin/activate

2. Install dependencies

pip install -r requirements.txt

3. Create a Telegram bot

  1. Open Telegram and start a chat with @BotFather.
  2. Send /newbot and follow the prompts.
  3. Copy the bot token.

4. Create a Reddit application

  1. Go to https://www.reddit.com/prefs/apps.
  2. Click "Create App" → choose "script".
  3. Fill in any name and redirect URI (http://localhost).
  4. Copy the client ID (under the app name) and client secret.

5. Configure environment variables

cp .env.example .env

Edit .env with your credentials:

TELEGRAM_BOT_TOKEN=your_telegram_bot_token
REDDIT_CLIENT_ID=your_client_id
REDDIT_CLIENT_SECRET=your_client_secret
REDDIT_USER_AGENT=SlaveWatch:v1.0 (by /u/YourUsername)
ADMIN_IDS=123456789           # your Telegram user ID
POLL_INTERVAL=5               # minutes between polls
REDDIT_FETCH_LIMIT=25
DATABASE_URL=bot.db

💡 Find your Telegram user ID by messaging @userinfobot.

6. Run the bot

cd bot
python main.py

The bot will initialise the SQLite database, start polling Reddit, and begin accepting Telegram commands.


Bot Commands

User commands

Command Description
/start Register and see the welcome message
/filter Open the filter settings menu
/mystatus Show your current filter mode and keywords
/done Finish adding keywords during a filter session

Admin commands

Command Description
/addsubreddit <name> Start monitoring a subreddit
/removesubreddit <name> Stop monitoring a subreddit
/listsubreddits List all monitored subreddits

Admin privileges are granted by adding Telegram user IDs to ADMIN_IDS in .env.


Filter System

A user can be in one of three states:

State Behaviour
No filter Receive every new post from all monitored subreddits
Inclusive mode Receive posts only if the title contains ≥1 of their keywords
Exclusive mode Receive posts unless the title contains any of their blocked words

Important: Switching modes clears all existing keywords — a user can only be in one mode at a time.

Filter flow example

  1. User sends /filter.
  2. Inline keyboard appears: Inclusive mode / Exclusive mode / Clear all filters.
  3. User clicks Inclusive mode.
  4. Bot confirms and prompts for keywords.
  5. User sends python, machine learning, AI (CSV or one per message).
  6. User sends /done or clicks the Done button.

Architecture Notes

Why PRAW is run in a thread

PRAW uses the requests library which is synchronous and blocks the thread it runs on. In an async application this would stall the entire event loop. By wrapping PRAW calls with asyncio.to_thread(), they execute in Python's thread pool executor, keeping the event loop free to handle Telegram updates simultaneously.

Duplicate guard

seen_posts is checked before dispatching and updated after. If the process crashes between dispatch and mark, the post will be re-sent on the next poll. This is an intentional trade-off (at-least-once delivery > silent loss).

Rate limiting

PRAW is configured with ratelimit_seconds=600, meaning it will wait up to 10 minutes rather than crash when Reddit enforces its rate limit. The scheduler adds natural spacing because polls happen at fixed intervals.


Running as a systemd service (production)

Create /etc/systemd/system/slavewatch.service:

[Unit]
Description=SlaveWatch Reddit-to-Telegram Bot
After=network.target

[Service]
Type=simple
User=ubuntu
WorkingDirectory=/home/ubuntu/dev_projects/slavewatch/bot
ExecStart=/home/ubuntu/dev_projects/slavewatch/.venv/bin/python main.py
Restart=on-failure
RestartSec=10
EnvironmentFile=/home/ubuntu/dev_projects/slavewatch/.env

[Install]
WantedBy=multi-user.target

Then enable and start:

sudo systemctl daemon-reload
sudo systemctl enable --now slavewatch
sudo journalctl -u slavewatch -f   # follow logs

Troubleshooting

Symptom Fix
Missing required environment variable Ensure .env is in the project root and all required keys are set
r/XYZ not found or banned The subreddit may be private, quarantined, or misspelled
Bot doesn't respond Check TELEGRAM_BOT_TOKEN and that the bot is not blocked by Telegram
No notifications arriving Run /mystatus — you may have an inclusive filter with no matching keywords
Duplicate notifications Should not happen; check that DATABASE_URL is consistent across restarts

License

MIT — do whatever you want, but don't blame us if Reddit changes their API again. 🙂

About

A telegram bot to monitor freelancing subreddits for specific gigs

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages