spillspot-news

254 Spill Spot News Bot

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.

What the bot does

Project structure

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

Requirements

Installation on Ubuntu VPS

1. Install system packages

sudo apt update
sudo apt install -y python3 python3-venv python3-pip fonts-dejavu-core

2. Upload the project

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.

3. Create a virtual environment and install Python dependencies

cd /opt/254spillspot-bot
python3 -m venv .venv
source .venv/bin/activate
pip install --upgrade pip
pip install -r requirements.txt

4. Configure environment variables

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.

SQL database setup (TiDB / MySQL)

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.

Facebook API setup

  1. Create a Meta app in the Meta developer dashboard.
  2. Add the Facebook Login and Graph API products that match your app flow.
  3. Create or connect the Facebook Page that will publish the posts.
  4. Generate a Page access token for that Page.
  5. Add the Page ID and Page access token to .env:
FACEBOOK_PAGE_ID=your_page_id
FACEBOOK_ACCESS_TOKEN=your_page_access_token
  1. Confirm your app has the permissions needed to publish Page posts in the current Meta dashboard. At minimum, Page posting access must be granted for the Page token you use.

Instagram API setup

Instagram posting through Meta requires:

Add the values to .env:

INSTAGRAM_USER_ID=your_instagram_user_id
INSTAGRAM_ACCESS_TOKEN=your_instagram_access_token

Important: Instagram needs a public image URL

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.

Example Nginx location block

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

Running the bot

Continuous scheduler mode

The app includes an internal scheduler and runs every 30 minutes by default:

cd /opt/254spillspot-bot
source .venv/bin/activate
python app.py

Single-cycle mode

Run one cycle manually:

python app.py --run-once

Dry-run mode

Render images and test the pipeline without publishing:

python app.py --run-once --dry-run

Cron setup

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.

How duplicate detection works

Notes about feed reliability

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.

Production checklist

  1. Replace placeholder values in .env.
  2. Set DRY_RUN=false.
  3. Confirm SQL connectivity.
  4. Confirm the generated image folder is publicly reachable if Instagram is enabled.
  5. Confirm your Meta app, token scopes, and Graph API version are valid in your current Meta dashboard.
  6. Run python app.py --run-once and inspect logs/bot.log.

Example workflow

  1. RSS feeds are fetched.
  2. New article metadata is extracted.
  3. The best available article image is downloaded.
  4. Pillow generates a branded image with the 254 Spill Spot logo.
  5. Captions are generated for Facebook and Instagram.
  6. SQL stores the processing result.
  7. Facebook and Instagram receive the post if credentials are configured.

Troubleshooting

Security

Disclaimer

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.