Case Studies

SpikeBot

Firebase/Mastodon browser extension

Browser extension > Database > Mastodon

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?

  1. Get the URL and text from any link on any webpage
  2. Save that link to a queue
  3. Auto-post to Mastodon on a schedule
  4. Move the link from queue to Published archive
  5. Provide an RSS feed of the most recent published links
  6. Optional – create an admin GUI
Some code that calls an API from a browser extension

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 🦾

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.

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",

spike.news.bot

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.