Studiocaster: A Labour of Love, Built Around the Listener

  • studiocaster
  • radio
  • broadcasting
  • side-projects

It’s twenty past seven on a Saturday evening. The presenter has a request show to run, a guest arriving at half past, and a link to write before the next song ends. Meanwhile the messages are coming in: a text to the studio number asking for a song for someone’s mum, a WhatsApp from a listener who has just finished a night shift, a Facebook comment with a dedication in it, and one message that definitely should not be read out on air. The producer has three tabs open and a phone face-up on the desk, and is trying to hold all of it in their head at once.

Nothing in that scene is dramatic. That’s rather the point. It’s just a small team doing several jobs at once, and the audience’s contributions — the whole reason the show exists — becoming one more thing to keep track of.

Studiocaster started as my attempt to make that moment less fraught. It began as a labour of love, it’s still very much an active project, and it’s now used by charities. That last part is what changed how I think about it.

The problem, in plain terms

Listener messages arrive through whatever channel the listener happens to prefer. Some people text. Some use WhatsApp. Some reply to a post on social media. From the station’s side, each of those is a separate inbox with its own notifications, its own layout, and its own way of showing you what’s new.

That fragmentation costs more than it looks like it should. Requests and dedications get missed simply because nobody was looking at the right window when they arrived. A genuinely good contribution scrolls past during a track. And every message needs a moment of judgement before it goes anywhere near a microphone — is this appropriate, is it from someone who’s been abusive before, is it what it appears to be? Making that call well is hard when the raw material is scattered across four applications and one personal phone.

Bringing it all into one place doesn’t make the work disappear. It makes the work visible, which turns out to be most of the battle.

flowchart LR
    A["SMS"] --> E["One live stream"]
    B["WhatsApp"] --> E
    C["Social channels"] --> E
    D["Other messaging apps"] --> E
    E --> F["Screen and organise"]
    F --> G["Choose what goes on air"]

The diagram makes a simple claim: channels should be inputs, not separate workflows. Where a message came from is a technical detail. What matters to the team is the single editorial decision between message received and microphone live.

Which channels it takes messages from

Being specific about this matters, because “supports social media” can mean almost anything. Studiocaster’s ingestion is built around per-provider adapters, so each source has its own small piece of code that knows how to authenticate that provider’s webhook and pull the useful fields out of its payload.

The channels with adapters in the platform today are:

Channel Providers
SMS Twilio, Nexmo/Vonage, Esendex
SMS, on site A GSM module on a Raspberry Pi, for stations keeping an existing SIM
WhatsApp Meta Cloud API, Twilio WhatsApp
Facebook Page messages
Instagram Direct messages
Telegram Bot messages
Signal Incoming messages
Twitter/X Mentions, via polling

Two honest caveats. The Twitter/X path is poll-based and depends on which API tier a station has access to — the adapter exists, but I’d treat it as unfinished rather than something to rely on this Saturday. And a handful of other providers are designed for but not built: YouTube live chat and comments is the one I most want, alongside Discord, Slack, TikTok and LinkedIn. They’re all gated on API access and approval rather than on the adapter itself, which is the easy part.

The reason the list can grow that way is that adapters do very little. A provider adapter authenticates the request, extracts the sender, the text, a timestamp and an ID, and hands over a normalised message. It is explicitly not allowed to implement banning, filtering, keyword matching or competitions. Every channel goes through exactly the same processing afterwards, which means a new source can’t quietly behave differently from the others.

The part with hardware in it

Not every message arrives over an API. Some stations have a studio number that’s been on posters, car stickers, the back of a mug and the bottom of every jingle for a decade, and it lives in a SIM card. They are, reasonably, not willing to give it up in order to move to a hosted provider. The number is part of the relationship with the audience; asking listeners to learn a new one costs more than the tidiness is worth.

So for those stations the ingestion point is a physical one: a GSM module attached to a Raspberry Pi, sitting in the building with the original SIM in it. Texts arrive exactly as they always have. The Pi reads them off the module, stores them locally, and pushes them up to the cloud, where they join the same pipeline as everything else — same normalisation, same moderation, same dashboard. From the producer’s side of the desk there is nothing to distinguish a message that came through a hosted SMS provider from one that came through a device on a shelf in the back room.

Storing on the Pi first is the same reasoning as keeping the raw webhook payload: the local copy is what survives a broken internet connection, and the backlog goes up when the link returns.

One of those units has been running at a charity for more than eight years and is still going. Unattended — nobody there gives it a thought, which is the correct amount of thought to give it. I can reach it remotely for the occasional bit of maintenance, and occasionally do. That’s the whole of it: eight years of Saturday evenings on a board that costs less than a decent microphone.

What Studiocaster actually does

At its centre is a live dashboard. Messages appear as they arrive, in real time, from every connected channel at once. From there the useful part is what you can do with them.

You can filter and label, so a request show can pull up requests and leave the rest for later. You can favourite the ones worth keeping, and hold back or block senders who’ve caused problems before, so that judgement doesn’t have to be made afresh every week. Messages can be claimed or assigned, which sounds like a small thing until you’ve had two people in a small team both reply to the same listener — or neither of them.

It handles competitions, where entries arrive by keyword and need collecting, tracking and drawing without someone maintaining a spreadsheet during a live show. And it lets you search back through what’s come in before, which matters more than I expected: stations get asked to find a message from last Tuesday surprisingly often.

What it isn’t, deliberately, is a replacement for your scheduling or playout system. Studiocaster is about the audience side of the desk. The music software can carry on doing what it does well.

What happens to a message

Between a listener pressing send and their text appearing on the studio screen, a fair amount happens — and most of it is the work a producer would otherwise be doing by hand.

flowchart TD
    A["Message arrives at the webhook"] --> B["Acknowledge immediately, store the raw event"]
    B --> C["Queue for processing"]
    C --> D["Normalise into a common shape"]
    D --> E["Identify the sender, or create them"]
    E --> F["Apply moderation: bans, blacklists, expletive filter"]
    F --> G["Flag priority senders and first-time contributors"]
    G --> H["Match keywords and competition entries"]
    H --> I["Save message, sender and conversation together"]
    I --> J["Push to the live dashboard"]

A few of those steps are worth pulling out.

The webhook accepts and acknowledges the message straight away, before doing any real work, and keeps a copy of the raw payload. That matters because providers give up and retry if you’re slow, and because when something does go wrong you want the original to replay rather than a lost message. Duplicates are caught by the provider’s own message ID, so a retried delivery doesn’t turn into a second entry on screen.

The actual processing then happens on a queue, off the request path. That’s where the useful automation lives: the sender is matched to their history, bans and blacklists are applied, the expletive filter runs — keeping both the original and the censored version — regular contributors are marked as priority, first-timers are flagged as first-timers, keywords are matched, and competition entries are recognised and linked to the right competition. All of it is written in a single transaction, so a message and its entry either both exist or neither does.

One detail I think is right and would defend: a message from a banned sender is still stored. It’s just marked as not for display. Deleting it would throw away the moderation history, and a station occasionally needs to show what was received, not only what was aired.

Finally the message is pushed to the dashboard over a live connection, so it appears without anyone refreshing anything. The dashboard also reconciles against the database behind the scenes, on the assumption that a live connection is an acceleration rather than a guarantee — the sort of belt-and-braces you want in something running during a broadcast.

Who it’s for

The people I picture using it are presenters, producers and station operators — the ones actually in the room while the programme is going out.

Community and charity broadcasters fit particularly well, and that’s borne out by the fact that charities are the confirmed users today. In those stations the roles blur: the person presenting may also be the person screening messages, and the person screening messages may also be on the rota to lock up afterwards. A shared workspace helps precisely because responsibilities move around. If everything lives in one place with a visible state, a volunteer picking up a shift can see where things stand rather than having to be briefed.

Beyond that there are other kinds of stations it could suit — student radio, hospital radio, small commercial outfits, anyone running phone-ins or request shows. I’d rather describe those as plausible than claim them. And I’d rather not suggest that every charity needs broadcast software; most don’t. The ones that broadcast do.

Listeners benefit indirectly, and I think that’s the honest framing. Nobody sending a dedication cares what software the station runs. They care whether their message gets noticed.

Why it still matters to me

There’s a particular shift that happens when a personal project acquires actual users. Before that, the project belongs to you: you build what interests you, you break things when you feel like it, and the only person inconvenienced is you at two in the morning.

Afterwards, someone is depending on it during a live broadcast. That’s a genuine responsibility, and it changes the work in ways I didn’t fully anticipate. Reliability stops being an abstract virtue. Small friction that I’d learned to work around becomes something I have to actually fix, because a volunteer meeting it for the first time on a Saturday evening won’t know the workaround.

That responsibility is also what makes it worth continuing. Feedback from people using it in anger has been more useful than any amount of my own speculation about what a station might want. It has repeatedly redirected what I build next.

Some of the work isn’t visible from the outside at all. A good deal of effort has gone into moving from an older application towards a more maintainable modern platform — not because rewriting is fun, but because a tool people rely on needs to be something I can still change safely in five years’ time. That’s an investment in the project’s future rather than a feature anyone will notice.

I want to be careful about what I claim. There’s been meaningful progress, and there’s plenty still in flight. Some capabilities exist in the codebase or on the roadmap without being available to everyone using it today — live polls, for instance, are something I’m working towards rather than something you can switch on. The project is evolving, and I’d rather say so than imply it’s finished.

Still going

Studiocaster remains what it started as: something I build because I want it to exist, now with the added weight of people who’d notice if it stopped working. I don’t have grand plans to announce. I have a list of things to improve, a handful of stations whose feedback shapes that list, and a fairly clear sense of what the tool is for.

If the result is that a presenter spots a dedication they’d otherwise have missed, and a listener hears their name on the radio — that’s a good enough reason to keep going.