We are big fans of the Fediverse.
Mastodon, the free and open source social network is surging in popularity, since the recent ~unpleasantness~ at Twitter.
It is currently full of early adopters and nerds – which could well be our bio. We are especially drawn to it due to the open standards it is based on, a simple to use API and strong support for RSS – something our side project spike.news – relies upon.
We’d created an account and were starting to copy and paste interesting articles from spike.news to the feed, when the usual developer senses start to buzz
Copying and pasting is for suckers. We should get a bot to do it.
1. Our requirements
What would we need it to do?
- Get the URL and text from any link on any webpage
- Save that link to a queue
- Auto-post to Mastodon on a schedule
- Move the link from queue to Published archive
- Provide an RSS feed of the most recent published links
- Optional – create an admin GUI
2. Save that link to a queue
Where does do we send that link? Serverless functions are all the rage – simple single-purpose Javascript files are perfect for this. we like Netlify functions although you can similarly host them on Google Cloud or Azure or Digital Ocean.
Our extension simply posts the a bit of JSON containing the url and the title to our function, and our function saves that in a Firebase Realtime Database – a super simple No-SQL database, our Queue is a simple collection called Links
.
3. Auto-post to Mastodon on a schedule
Once we have the queue ready, we can create another serverless function to pluck the most recent link from the Links
queue, post it to Mastodon then save it to a second collection, we’ll call Archive
.
Posting to Mastodon is surprisingly easy! You’ll just need to login to your account, go to Settings > Development > Your applications > New Application
.
Allow write:statuses
to publish posts. Copy the API key and secret.
Install the mastodon-api
package from NPM
Posting to your timeline is then as simple as
import Mastodon from 'mastodon-api'
const M = new Mastodon({
access_token: process.env.MASTODON_TOKEN,
api_url: 'https://mastodon.cloud/api/v1/',
})
await M.post('statuses', { title: 'my title', uri: 'http://test.com' })
After that, it’s a case of using either an external CRON service, or in our case, a Netlify scheduled-function to call this API every 4 hours.
Our bot lives 🦾
4. Move the link from queue to Published archive
Again using our Firebase database, once the bot has posted the link, update a new Collection called archive and add the link to it.
You can now remove it from the Posts collection by setting it to null.
5. Provide an RSS feed of the most recent published links
We can make a final netlify function which grabs our archives, sorts them by date, and converts them in to RSS items.
We used this excellent guide as a reference on how to make a Netlify RSS feed
<?xml version="1.0"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
<channel>
<title>spike.news</title>
<link>https://spike.news</link>
<description>spike.news - aggregating the news from around the web every minute. @mastodon.cloud/@spikenews</description>
//...items
</channel>
</rss>
Once we’ve created our RSS items, we can merge them into a template string, and return them with a contentType: "text/xml"
,
6. Optional – create an admin GUI
Not all links exist to be clickable, so it would be great to post via a UI. It would also be nice to see our links and archives without having to rummage through a database.
Our last job was to make a very simple Vue 3 / Vite.js Single Page App (SPA) dashboard in the same app as our Netlify functions, so we can use the same functions as an API to power the dashboard.
Using the fantastic Open Props @import "https://unpkg.com/open-props"
design tokens, we can quickly whip up a tidy looking SPA.
Done.
Hopefully this will inspire you to mash up a Frankenstein’s monster of your own.
If you’d like us to mash one up for you, ping us a message.