跳到正文
DEV Community· Suvin Nimnaka·· 4 小時前AI 評分44

One More Mile:以 Twilio 為跑手帶來親友語音鼓勵

One More Mile - Bringing Joy to Runners with Twilio

AI 導讀

One More Mile 利用 Twilio Voice SDK 和 WebRTC,讓親友透過瀏覽器按跑手號碼錄製語音鼓勵,跑手則透過私人連結收聽。連結附有秘密 token 以限制存取;服務無須 app、電話號碼或國際通話費,Twilio Sync 負責管理跑手名單及對應訊息。

正文

If you've ever run a long race, you probably know that there are parts where things get a little difficult. Your legs hurt. You are tired. You start questioning your life choices and wondering why you voluntarily paid money to do this.

And then you hear someone cheering for you.

It could be your mum, your partner, a friend, or anyone else you care about. Just hearing a familiar voice can give you that little push to keep going.

The problem is that your favourite people are usually not running alongside you. I've felt this myself during runs in Colombo. There are parts of some city races where you are running between buildings, with hardly anyone around to cheer. You have thousands of runners around you, but somehow it can still feel pretty lonely.

That got me thinking. Most runners already have their phones with them, and a lot of them run with headphones. So why not use the phone to bring some of that support to them?

The idea was simple. Friends and family could record short voice messages for a runner. During the race, the runner could open a link and listen to those messages.

Then I started thinking about how to build it.

The first idea

My first thought was a phone hotline.

A supporter could call a number, enter the runner's bib number, record a message, and hang up. The runner could then call another number and listen to the messages.

Twilio seemed perfect for this. It already handles phone calls, recordings, menus and pretty much everything else you need for a voice application.

There was just one problem.

Then I hit a wall

Twilio phone numbers aren't available in Sri Lanka. That made the phone hotline idea pretty useless.

I could have used an international number, but then supporters would have to pay international call charges just to leave a 20 second message. The runner would also have to spend phone credit listening to those messages during the race. Like running is not already expensive :D

That didn't make much sense.

So I started looking at the problem again.

The mundane workaround

I realized I was too focused on the phone number.

The number wasn't really what I needed. I just needed a way to send audio from a supporter to a runner, with the runner's bib number connecting the two.

And a browser can handle audio.

Twilio's Voice SDK supports WebRTC, which means a web page can connect to Twilio and behave much like a phone call, without actually using a phone number.

That was enough.

Instead of asking someone to call a number, I could just give them a link.

The supporter opens the link, enters the bib number, records a message and sends it. The runner gets their own private link and can listen to everything.

No app. No phone number. No international call charges.

I called it One More Mile.

Leaving a message

A supporter opens the page and enters the runner's bib number.

The app checks it and shows the runner's name. This is a small thing, but it helps avoid a surprisingly easy mistake. You never know if it's 1234 or 2444 (One 2, three 4 in case you didn't get it :p).

Once the runner is confirmed, the supporter enters their own name and starts recording.

They can say whatever they want. Well, not just anything. Only the good things.

It might be a serious motivational message. It might be "Come on, you've got this!" Or it might be a (good?) friend reminding them that therapy is much cheaper than running.

Good Friends I Guess

When they're done, they hit stop and the message is saved.

There is a small trick happening here.

With a normal phone call, you can press the # key to tell Twilio that the recording is finished. Obviously, a browser doesn't have a phone keypad. So the stop button sends the same signal through the WebRTC connection. Twilio receives it, stops the recording and stores it.

The person recording doesn't need to know any of that.

Listening to the messages

The runner gets a private link, usually through a QR code or a message from the event organizer.

When they open it, they see one big play button.

That's basically the whole interface.

At kilometer 32, nobody wants to read instructions or figure out which menu to open. You just want to press something and hear someone you know.

The messages play one after another, with the sender's name announced before each one. Sometimes, just hearing the sender's name is enough to brighten your day, if you know what I mean. :wink

If there aren't any messages yet, the app tells the runner to keep going anyway. Hopefully someone remembers to send one soon.

The listening link also contains a secret token, so the messages aren't publicly accessible. If someone opens the page without a valid token, they just get an invalid-link screen.

Nobody else gets to listen to your race-day fan mail.

What Twilio is actually doing

Once I had the basic idea working, here is how I designed all the features around Twilio.

One More Mile Architecture

The Voice SDK connects the browser to Twilio using WebRTC.

A small token function gives the browser a short-lived token so it can make the connection. Think of it as a wristband at a concert.

The TwiML App tells Twilio where to send the call.

The Serverless Functions handle the calls and return TwiML instructions such as "start recording" or "play this recording."

Twilio Sync stores the runner roster and keeps track of the messages associated with each bib number.

The actual audio is stored as recordings, which Twilio can then play back.

The whole app also lives in Twilio. The web pages are served as Twilio Assets alongside the Functions, so the frontend and backend can be deployed together.

That means there isn't another server I need to worry about on race morning.

One less thing to break at 5 am!

The race organizer's side

Race Organizer's UI

Someone still needs to tell the application who is actually running.

For that, I built a small admin page where the organizer can upload a CSV containing the bib numbers and runner names.

The page validates the file before replacing the existing roster.

It also generates a private listening link for each runner, which the organizer can distribute before the race.

And yes, there is a CSV template. Because whenever you give someone a CSV upload, the first question is almost always, "What columns do I need?"

Want to try it yourself?

If you have a Twilio account, just run:

curl -fsSL https://raw.githubusercontent.com/Suvink/one-more-mile/main/init.sh | bash

The script walks you through the setup and deploys the app for you. You only have to input the Twilio Auth Token and account SID. Yes, it's a bit of a black box. But hey, at least it's a box that works!

Now if you don't wanna put your blind faith in a total stranger, head over to the GitHub repo for the source code and setup instructions.

One More Mile

Voice messages for marathon runners. Supporters enter a runner's bib number and record a message in the browser. On race day, each runner opens a private link and hears every message through their headphones.

It runs entirely on Twilio, with no phone number needed. The browser places the call over WebRTC using the Twilio Voice SDK, so it works in countries where Twilio numbers aren't available.

  • Functions (functions/): access tokens, bib lookup, roster upload, and the TwiML for recording and playback
  • Sync stores the roster and each runner's message list. Recordings stay in Twilio's recording storage.
  • Web app (web/): a Vite + React PWA, served as Twilio Assets on the same domain

Setup

You need git, Node 18+, and your Twilio Account SID and Auth Token from the Twilio Console.

curl -fsSL https://raw.githubusercontent.com/Suvink/one-more-mile/main/init.sh | bash

This clones the repo, asks for your…

Where I could take it next

The first version is intentionally simple, but there are a few things I'd like to add as I keep working on One More Mile.

The first is moderation. Give people a microphone and eventually, someone is going to use it to say something they probably shouldn't.

A cat with a mic

Twilio's Conversational Intelligence could help here. Voice messages could be transcribed and analyzed before they reach the runner, allowing the application to flag or reject messages containing profanity or other unwanted content. That would be especially useful if this is being used for a large public race where hundreds or thousands of people might be sending messages.

There is also room to make the experience more fun for supporters. Maybe they could choose a few quick prompts like "Give them a pep talk" or "Make them laugh" when they start recording. That could make it easier for someone who wants to send a message but has no idea what to say.

The finish line

The original phone hotline idea would have worked if Twilio phone numbers were available in Sri Lanka. The web version ended up being just as good anyways.

It is easier to share, works directly from the runner's phone, doesn't require an app, and works without relying on local phone numbers.

But the technical part is only half the reason I built it.

The real reason is what happens during a long race when you are tired and the crowd disappears.

You might hear your mum saying, "I'm so proud of you." You might hear your partner telling you that they're waiting at the finish line. Or you might hear your best friend saying something so stupid that you actually laugh when you are supposed to be conserving whatever energy you have left.

For a moment, they feel like they're right there with you. And maybe that's enough to keep running.

One more mile.

來源:DEV Community · dev.to