254 Spill Spot News Bot is a Python automation project for Ubuntu VPS deployments. It pulls real stories from trusted RSS feeds, creates branded news images with Pillow, stores processed items in SQL to avoid duplicates, and can publish to Facebook and Instagram.
BREAKING NEWS banner--run-once mode.254spillspot-bot/
├── app.py
├── config/
│ └── config.py
├── rss/
│ └── news_fetcher.py
├── image/
│ └── image_editor.py
├── social/
│ ├── facebook.py
│ └── instagram.py
├── database/
│ └── sql_store.py
├── assets/
│ ├── logo.png
│ └── fonts/
├── downloads/
├── generated/
├── logs/
├── .env
├── .env.example
├── requirements.txt
└── README.md
sudo apt update
sudo apt install -y python3 python3-venv python3-pip fonts-dejavu-core
cd /opt
sudo mkdir -p 254spillspot-bot
sudo chown -R $USER:$USER 254spillspot-bot
cd 254spillspot-bot
Copy the project files into /opt/254spillspot-bot.
cd /opt/254spillspot-bot
python3 -m venv .venv
source .venv/bin/activate
pip install --upgrade pip
pip install -r requirements.txt
cd /opt/254spillspot-bot
cp .env.example .env
nano .env
Update .env with your SQL connection string, Facebook Page credentials, Instagram credentials, public image URL, and optional custom fonts.
Set a SQLAlchemy connection string in .env:
SQL_DATABASE_URL=mysql+pymysql://USER:PASSWORD@gateway04.us-east-1.prod.aws.tidbcloud.com:4000/DB_NAME
SQL_SSL=true
SQL_SSL_CA_PATH=
If your TiDB provider requires a CA file, set SQL_SSL_CA_PATH to the local path of the CA cert.
The bot automatically creates the processed_news table with a unique constraint on article_id.
.env:FACEBOOK_PAGE_ID=your_page_id
FACEBOOK_ACCESS_TOKEN=your_page_access_token
Instagram posting through Meta requires:
Add the values to .env:
INSTAGRAM_USER_ID=your_instagram_user_id
INSTAGRAM_ACCESS_TOKEN=your_instagram_access_token
Meta does not publish Instagram images directly from a local file path. The generated image must be reachable from the public internet.
Set a public base URL in .env:
PUBLIC_IMAGE_BASE_URL=https://your-domain.com/generated
The bot saves branded images into the local generated/ folder. You must expose that folder publicly with Nginx, Caddy, Apache, or another static file server.
server {
server_name your-domain.com;
location /generated/ {
alias /opt/254spillspot-bot/generated/;
autoindex off;
}
}
After changing Nginx, reload it:
sudo nginx -t
sudo systemctl reload nginx
The app includes an internal scheduler and runs every 30 minutes by default:
cd /opt/254spillspot-bot
source .venv/bin/activate
python app.py
Run one cycle manually:
python app.py --run-once
Render images and test the pipeline without publishing:
python app.py --run-once --dry-run
If you prefer cron instead of the internal scheduler, use --run-once every 30 minutes:
crontab -e
Add:
*/30 * * * * cd /opt/254spillspot-bot && /opt/254spillspot-bot/.venv/bin/python app.py --run-once >> /opt/254spillspot-bot/logs/cron.log 2>&1
Use either cron or the internal scheduler, not both at the same time.
article_id hash.completed or rendered_only, it is skipped on later cycles.Publisher RSS URLs can change over time. The bot ships with defaults for:
If any publisher changes a feed URL, update RSS_FEEDS_JSON in .env or edit config/config.py.
.env.DRY_RUN=false.python app.py --run-once and inspect logs/bot.log.PUBLIC_IMAGE_BASE_URL points to a real public URL and the image is reachable in a browser..ttf font files to assets/fonts/ and set HEADLINE_FONT_PATH and BODY_FONT_PATH..env secrets to git.This project is designed to repost real stories from trusted RSS sources. You are responsible for complying with each publisher’s usage rules, local laws, and Meta platform policies before deploying it.