Inspiration
Every night someone in our group chat is already walking to Franklin Street, while someone else orders delivery and pays for a car to drive that same half mile. We figured the walk was happening anyway, so the food might as well come along for the ride. That turned into Ferry, plus a little guilt about how many cars idle outside the dorms for a single burrito.
What it does
Ferry is a Telegram bot that lives in your friends' group chat, and when someone says they're heading to a restaurant it opens a short order window for everyone else. You can order by just messaging it or through our web and Android app, and the runner pays at the counter with a Ferry Card that only gets loaded with the exact total once the window closes, so they never front anyone's money. Then you watch your friend's bubble walk toward you on a map, and when the food shows up you see how much CO2 you skipped compared to a car delivery.
How we built it
The backend is Rust (Axum and SQLx) on Supabase, and a small Bun sidecar connects it to Telegram through Photon's Spectrum SDK. Gemini 3.6 Flash handles the conversation side with tool calls, so the bot can spot trips and turn messages like "burrito no beans" into real orders without ever seeing anyone's name. The web app is React with a Frutiger Aero look, all glossy bubbles and sky, wrapped for Android with Capacitor. Money runs through Capital One's Nessie sandbox with an escrow account and a card that gets funded right before purchase, and the carbon math uses the EPA's estimate of about 400 g of CO2 per car mile:
$$\text{CO}2\ \text{saved} = d{\text{drive}} \times 400\ \text{g/mile}$$
so the demo's drive from Cosmic Cantina to Fetzer Gym, about 0.97 miles, saves about 389 g.
Challenges we ran into
A few hours in, we found out Photon's Pro plan routes each user through a shared pool of numbers, so there was no single Ferry number and no iMessage group chat support. We moved the bot to Telegram through the same Spectrum SDK, which turned sign-in into "tap Start, then Confirm" in Telegram instead of a texted code. Building the backend and frontend on two laptops at once also meant locking down a strict API contract early, or the two halves would never have fit together.
Accomplishments that we're proud of
We're proud that the runner never touches anyone's money and every cent balances in our ledger, because that's what made the idea feel safe enough to actually use. Getting the bot to stay quiet in the group chat until it's actually useful took more tuning than we expected, and it's way less annoying because of it. Watching a bubble burst into "+389 g CO2 saved" never got old.
What we learned
We learned way more about how DoorDash pays restaurants than we planned to, especially how the Red Card lets a Dasher buy the food without fronting cash. Reading the fine print on a platform's plan before building on it would have saved us a rewrite. Agreeing on the API contract first is what made building in parallel, and wiring it all together at the end, actually work.
What's next for Ferry
We want to bring Ferry back to iMessage on a dedicated line, since that's where most of our friends' group chats live. Real payments would move to Stripe Connect with virtual cards instead of the Nessie sandbox. After that we'd ship the Android and iOS apps to the stores and start partnering with Franklin Street restaurants. Furthermore, the end goal is for Ferry to work at every college campus; and not one at a time, we want to implement a universal method of integration!
Built with
rust, axum, tokio, sqlx, postgresql, supabase, typescript, react, vite, react-router, tanstack-query, motion, maplibre-gl, openapi, msw, capacitor, android, pwa, bun, telegram, photon-spectrum, google-gemini, capital-one-nessie, osrm, openstreetmap, web-push, cloudflare-tunnel, vercel, github-actions, playwright, claude-code
Built With
- axum
- claude
- cloudflare
- codex
- gemini
- github
- nessie
- photon
- playwright
- react
- rust
- sql
- supabase
- telegram
- tokio
- typescript
- vercel
- vite

Log in or sign up for Devpost to join the conversation.