Skip to main content
Ungathered Thoughts

⭐ to relay

I have mixed feelings about relaying between social networks: it's okay, but needs consideration.

For:

Against:

(Probably missing some bits there. Anyway.)

Currently I'm active in Fediverse (preferred, via the excellent, small, https://toot.cafe Mastodon instance) and Bluesky. I wanted the capacity to continue posting laundry appreciation, tech snark and life reflections to the Fediverse, and make it easy to circulate those posts from Fediverse to Bluesky when I wanted to[1]. Since I'd be making that choice when posting, I control using the available interface - typically my mobile Mastodon client, Tusky, or the web interface for my home toot.cafe instance.

We can't extend the UI of apps we don't control ... usually. With ingenuity, we can re-use an existing UI element for our requirements: use the ⭐ "Fave" UI to flag a post from the posting UI for our own purposes, then read the post's faved status to determine whether the post should be relayed.

I had previously implemented this same functionality for a Fediverse / Twitter relay service, moa.party (fedstoa/moa#53). That project was no longer active but the solution could be reworked with a new service. Skymoth looked viable, and while it didn't share any DNA from Moa, I was able to implement a similar solution.

Taking a look at Skymoth, I could see notes in the README already relating to user control. The first step would be to see if this system was a fit for my usage. I ran up a copy locally using Docker Compose and tested it out; aside from the addition I planned to add, it seemed to work fine.

Next I opened an issue (https://github.com/thilobillerbeck/skymoth#55) to let the maintainer/community know I was interested in making this happen, posted some first thoughts on approach, and outlined my understanding of the existing implementation. My goal here was to avoid conflict with any existing WIP and to seek initial input.

Then I used the project docs to bring up a local development environment. This was interesting as the project uses a toolkit I hadn't tried before, Cachix DevEnv. It's pretty swish! It was super fast to bring up the local development environment, and this setup had a tidy TUI interface, process-compose, to manage and observe running processes.

Skymoth is written in TypeScript, using Fastify to provide the web app interface and Prisma + Postgres for storage. Of these, only Postgres was familiar territory. The DevEnv setup made it really easy to get up and running, and the toolchain was accessible and straightforward to get hacking on.

I mocked up some local changes to show the UX I would propose, and shared them on the issue queue. Then I set about implementing. The existing query structure made it pretty easy to work with. While I only wanted fave-to-relay for my own needs, I recalled that moa.party (and/or other relaying tools?) had supported relaying based on the presence or absence of a hashtag, so I included that functionality as well.

I liked that Skymoth's call to Mastodon API fetched 50 recent posts and iterated over them; that eliminated an ungainly part of how this worked in moa.party, where your post might not be relayed if you didn't fave it quickly enough, as the most recent post ID would be used as a high-water mark whether or not that post was relayed at the time of the poll.

The most challenging part was trying to follow some existing implementation - there was storage for user settings in the DB schema, but that didn't seem to be wired up in the application. I gave it a shot, but eventually left it and stored the details against the user; I think what I ran into was some incompletely implemented settings storage, not yet in a state to be used, making for a bit of a red herring! Once I decided to ignore that entirely, things progressed fine :)

The changes did what I wanted and the end result is great for me - I am happily posting to Fediverse (my preferred network), hitting ⭐ if I want to circulate it over to Bluesky, and able to engage with replies on both networks. Relayed posts handle the details of each network fine so far, including media, alt text, and splitting post bodies if the Mastodon post is too long for a single Bluesky post. I don't have to fave right away, self-replies work as desired, it's grand. And now that the PR is merged, the users of https://skymoth.app have the same functionality. Delighted!

I picked up some TypeScript knowledge along the way, and appreciated the simplicity of this tidy little app and the toolchain Thilo has selected for it. Nix, DevEnv, Fastify and Prisma all look interesting tools to use again in future if opportunity arises.

If you want to use this yourself, you can either use the hosted version at https://skymoth.app which now does this, or use the example.compose.yml in https://github.com/thilobillerbeck/skymoth/ to run your own copy locally.


  1. Bluesky can join the Fediverse any time they like, of course, and save me the effort, but hey. ↩︎