Skip to content

dlnorman/standalone-rss-mastodon-bridge

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

10 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

RSS to Mastodon Bridge

A lightweight, self-hosted bridge that automatically posts new RSS/Atom feed items to Mastodon. Perfect for static site generators like Hugo, Jekyll, or any website with an RSS feed.

Features

  • Multi-Feed Support - Monitor multiple RSS/Atom feeds simultaneously
  • Flexible Configuration - Customize prepend/append text with emoji support
  • Image Support - Automatically extracts and uploads first image from posts
  • Template System - Control post format with excerpt length, hashtags, etc.
  • Single or Multiple Accounts - Post all feeds to one account, or use different accounts
  • SQLite Database - Lightweight tracking of posted items
  • Admin Dashboard - Web interface to view posted items and statistics
  • Webhook-Based - Trigger from your deployment script
  • Shared Hosting Compatible - Just PHP and SQLite required

Architecture

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”              β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚   Laptop    β”‚              β”‚   Server    β”‚
β”‚             β”‚              β”‚             β”‚
β”‚  Hugo Site  β”‚              β”‚ Static HTML β”‚
β”‚             β”‚   rsync      β”‚    Files    β”‚
β”‚   Build     β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Άβ”‚             β”‚
β”‚             β”‚              β”‚             β”‚
│  Deploy     │   webhook    │ RSS→Mastodon│
β”‚   Script    β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Άβ”‚   Bridge    β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜              β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”˜
                                    β”‚
                                    β”‚ Mastodon API
                                    β”‚
                            β”Œβ”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”
                            β”‚   Mastodon     β”‚
                            β”‚   Instance     β”‚
                            β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

How it works:

  1. You build and deploy your static site
  2. Your deploy script calls the webhook
  3. Bridge checks RSS feeds for new items
  4. New items are formatted and posted to Mastodon
  5. People see your posts in their Mastodon timelines
  6. Replies and interactions happen on Mastodon

Quick Start

1. Get Mastodon Access Token

  1. Log into your Mastodon account
  2. Go to Settings β†’ Development β†’ New Application
  3. Give it a name like "RSS Bridge"
  4. Required scopes: write:statuses, write:media
  5. Copy the access token

2. Server Setup

Upload the server/ directory to your web server:

scp -r server/* user@example.com:~/public_html/rss-mastodon/

Create configuration:

cd ~/public_html/rss-mastodon
cp config.example.php config.php
nano config.php

Configure your feeds:

'feeds' => [
    'blog' => [
        'enabled' => true,
        'feed_url' => 'https://yourdomain.com/index.xml',
        'feed_type' => 'rss',
        'mastodon' => [
            'instance' => 'https://mastodon.social',
            'access_token' => 'YOUR_ACCESS_TOKEN_HERE',
        ],
        'template' => [
            'prepend' => 'πŸ“ New post: ',
            'append' => "\n\n#blog",
            'include_excerpt' => true,
            'excerpt_length' => 200,
        ],
        'images' => [
            'enabled' => true,
            'extract_first' => true,
            'alt_text_source' => 'alt',
        ],
    ],
    'photos' => [
        'enabled' => true,
        'feed_url' => 'https://yourdomain.com/photos/index.xml',
        'feed_type' => 'rss',
        'mastodon' => [
            'instance' => 'https://mastodon.social',
            'access_token' => 'YOUR_ACCESS_TOKEN_HERE',
        ],
        'template' => [
            'prepend' => 'πŸ“· ',
            'append' => '#photography',
            'include_excerpt' => true,
            'excerpt_length' => 100,
        ],
        'images' => [
            'enabled' => true,
            'extract_first' => true,
            'alt_text_source' => 'alt',
            'required' => true,  // Skip posts without images
        ],
    ],
],

Set a random webhook secret:

# Generate a secure random secret
openssl rand -hex 32

Create data directory:

mkdir data
chmod 755 data

3. Client Setup

On your laptop, configure the webhook trigger:

cd client/
cp config.example.sh config.sh
nano config.sh

Set your webhook URL and secret:

WEBHOOK_URL="https://example.com/rss-mastodon/webhook.php"
WEBHOOK_SECRET="your_random_secret_from_config_php"

Make the script executable:

chmod +x notify-mastodon.sh

4. Add to Deploy Script

Add to your Hugo (or other SSG) deploy script:

#!/bin/bash

# Build site
hugo

# Deploy to server
rsync -avz --delete public/ user@server:/path/to/public_html/

# Trigger Mastodon posting
./path/to/client/notify-mastodon.sh

5. Test It

Test the webhook:

./client/notify-mastodon.sh

Check the admin dashboard:

https://example.com/rss-mastodon/admin.php

Default password: changeme123 (change this in admin.php line 23!)

Configuration Options

Feed Configuration

Each feed supports:

  • enabled: Enable/disable the feed
  • feed_url: URL to RSS or Atom feed
  • feed_type: 'rss' or 'atom'

Mastodon Configuration

Template Options

  • prepend: Text to add before the title (supports emoji! ✨ πŸ“ πŸ“· 🎨)
  • append: Text to add after the post (great for hashtags)
  • include_excerpt: Include excerpt from post content
  • excerpt_length: Maximum length of excerpt (characters)
  • include_link: Include link to original post

Image Options

  • enabled: Enable/disable image handling
  • extract_first: Extract first image from content
  • alt_text_source: 'title', 'alt', or 'none'
  • required: Skip posts without images if true

Post Timing Options

  • minimum_interval: Minimum minutes between posts from this feed (optional)
    • If set to a value greater than 0, posts will be queued and processed gradually
    • Prevents flooding your Mastodon feed when multiple items are published at once
    • Requires setting up the queue processor (see below)
    • Set to 0 or omit for immediate posting (default behavior)

Requirements

Server:

  • PHP 7.4+ with SQLite3, OpenSSL, and cURL extensions
  • HTTPS (Mastodon API requires secure connections)
  • Write permissions for data directory

Client (Laptop):

  • Bash
  • curl

Admin Dashboard

Visit https://example.com/rss-mastodon/admin.php to:

  • View posted items across all feeds
  • See statistics (total posts, recent activity)
  • Monitor per-feed post counts
  • Access Mastodon URLs for each post

Security: Change the default password in admin.php:23

Queue Processor Setup (Optional)

If you're using the minimum_interval feature to space out posts, you need to set up the queue processor to run periodically.

Setting Up Cron Job

The queue processor should run every minute (or at your preferred interval). On your server:

# Edit your crontab
crontab -e

Add this line to run the queue processor every minute:

* * * * * /usr/bin/php /path/to/your/server/queue-processor.php >> /path/to/your/server/data/queue.log 2>&1

Replace /path/to/your/server/ with the actual path to your installation.

How Queue Processing Works

  1. When the webhook runs, new posts are added to the queue instead of being posted immediately
  2. The queue processor (run via cron) checks the queue every minute
  3. For each feed, it checks if enough time has passed since the last post
  4. If the minimum interval has elapsed, it posts the next item in the queue
  5. The process repeats, spacing out posts according to your minimum_interval setting

Example Configuration

'blog' => [
    'enabled' => true,
    'feed_url' => 'https://yourdomain.com/index.xml',
    // ... other settings ...
    'minimum_interval' => 30,  // Post at most once every 30 minutes
],
'photos' => [
    'enabled' => true,
    'feed_url' => 'https://yourdomain.com/photos/index.xml',
    // ... other settings ...
    'minimum_interval' => 60,  // Post photos once per hour
],

Monitoring the Queue

Check queue status in the log file:

tail -f /path/to/your/server/data/bridge.log

Or check the queue directly in the database:

sqlite3 /path/to/your/server/data/posts.db "SELECT * FROM post_queue;"

Troubleshooting

Posts aren't appearing on Mastodon:

  • Check the access token has correct permissions
  • Verify the webhook is being triggered (check server/data/bridge.log)
  • Ensure images are publicly accessible
  • Check admin dashboard for errors
  • If using minimum_interval, check that the queue processor cron job is running

Posts are queued but not being posted:

  • Verify the cron job is set up correctly: crontab -l
  • Check queue processor logs: tail -f /path/to/data/queue.log
  • Ensure PHP path in cron is correct (try which php)
  • Check that the minimum interval has elapsed since the last post

Webhook returns 403:

  • Verify webhook secret matches between client config.sh and server config.php

Images aren't uploading:

  • Ensure images are publicly accessible (not behind authentication)
  • Check image URLs are using HTTPS
  • Verify image formats are supported (JPEG, PNG, GIF, WebP)

Character limit exceeded:

  • Reduce excerpt_length in template configuration
  • Shorten prepend/append text
  • The system will auto-truncate but may cut off content

File Structure

standalone-fediverse/
β”œβ”€β”€ server/                  # Upload to your web server
β”‚   β”œβ”€β”€ config.example.php   # Configuration template
β”‚   β”œβ”€β”€ webhook.php          # Main webhook handler
β”‚   β”œβ”€β”€ queue-processor.php  # Queue processor (for minimum_interval)
β”‚   β”œβ”€β”€ admin.php            # Web dashboard
β”‚   β”œβ”€β”€ database.php         # SQLite database management
β”‚   β”œβ”€β”€ feed-parser.php      # RSS/Atom parser
β”‚   β”œβ”€β”€ mastodon-client.php  # Mastodon API client
β”‚   β”œβ”€β”€ post-formatter.php   # Template system
β”‚   β”œβ”€β”€ logger.php           # Logging utility
β”‚   └── data/                # Created automatically
β”‚       β”œβ”€β”€ posts.db         # SQLite database (includes post_queue table)
β”‚       β”œβ”€β”€ bridge.log       # Webhook log file
β”‚       └── queue.log        # Queue processor log file
β”‚
β”œβ”€β”€ client/                  # Keep on your laptop
β”‚   β”œβ”€β”€ notify-mastodon.sh   # Webhook trigger script
β”‚   └── config.example.sh    # Configuration template
β”‚
└── archive-activitypub/     # Old ActivityPub implementation (reference)

Security

  • HTTPS Required - Mastodon API requires secure connections
  • Webhook Secret - Prevents unauthorized triggering
  • Rate Limiting - Prevents abuse (60 requests/minute default)
  • Admin Password - Change default password immediately
  • Access Token - Keep your Mastodon token secure

License

MIT License - Free to use and modify

Credits

Built for static site enthusiasts who want to share their content on the Fediverse without complex infrastructure.

About

A standalone Fediverse integration app intended for static websites like mine, which is generated by Hugo.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors