Inspiration
A friend of mine was going through depression, and I didn’t know what to say to him. I’d type a message, delete it, and type it again because I was scared of saying the wrong thing. Most of the time I ended up sending something like “you’ll be fine,” which didn’t help at all. That’s when I realized nobody teaches you how to have that conversation. You’re supposed to figure it out in the moment, with someone you care about, when it matters most. And when teens are struggling, they usually go to a friend first, not an adult. I wanted a way to practice before it’s real.
What it does
Unsent lets you practice texting a friend who’s going through something hard. You pick a friend, like Maya, who just went through a breakup and has been pulling away, and you text her like you would in real life.
She reacts to what you actually say. If you check in and listen, her trust goes up and she opens up more. If you brush her off with “lol you’ll be fine,” she leaves you on read, and you have to earn her trust back.
When you’re done, Unsent shows you what you did well, the exact message where you lost her, and a “What if?” view where you can go back to that moment and see how a different text would have played out.
You can also:
Add your own friend: describe them, what happened and a few texts they’d send, and Unsent builds a friend that texts like them. Practice for a real friend: upload screenshots of your chat (you cover names and numbers first), and it tells you which warning signs it noticed and how serious it looks, then lets you practice checking in. X-ray mode: see exactly what the app thinks of each message and why trust went up or down.
How we built it
How we built it Backend: Python with FastAPI. Frontend: React and TypeScript, styled to feel like a real messaging app. The main model: trained with scikit-learn. It reads your message and figures out what you did, like checking in, validating, asking directly, or brushing someone off. On messages it had never seen before, it scored 0.84 (F1). A simple keyword list only got 0.49. The trust engine: my own code decides how much the friend trusts you, what she’s ready to share, and when she leaves you on read. Friend replies: worded by OpenAI, but if that ever goes down, the friends switch to pre-written lines, so the app still works.
Challenges we ran into
Challenges we ran into Understanding what you meant: my first version just looked for keywords, and it was bad. It thought “lol” meant you were being mean even in a kind message. Training my own model fixed that, but getting good training data and measuring it honestly took a long time. Tuning trust: if trust moved too much, the friend felt fake. If it moved too little, nothing you did mattered. I had to tune it a lot before Maya felt like a real person. Keeping the AI in line: the AI words the replies, but I didn’t want it making things up or saying things the friend wasn’t ready to say yet, so my code controls what it’s allowed to reveal at each point. Screenshots: making sure names and numbers get covered before anything is uploaded took a lot of testing.
Accomplishments that we're proud of
Accomplishments that we’re proud of The “left on read” moment. It’s the first time an app made me feel what it’s like when a message lands wrong. Training a model that’s way better than a keyword list, and measuring it on messages it had never seen instead of just guessing. The “What if?” feature: seeing a different text change how the whole conversation goes is the part people remember. Building a full app with a real backend, a real model and a real frontend by myself as a high schooler.
What we learned
What we learned
Building something people can actually use is way harder than getting code to run. A lot of my first ideas technically worked but felt wrong when I used them, like Maya forgiving you too fast or the feedback being too harsh. I had to test it like a user and keep changing it.
I also learned how to train and evaluate a real model, and that honest numbers matter more than impressive-sounding ones. Mostly, I learned that a hard conversation gets easier the more times you practice it.
What's next for Unsent
What’s next for Unsent Voice calls: a lot of real check-ins happen on the phone, so in 2.0 you could call your practice friend and talk to them in real time, and they’d react to your tone, not just your words. A face to practice with: a video call where your friend actually reacts, like looking away, going quiet, or finally opening up. More friends and languages: more stories, and more people who can practice in their own language. Practicing together: a way for a class or club to practice and compare how they did.
Built With
- chart.js
- css
- docker
- fastapi
- fastembed
- javascript
- numpy
- pandas
- playwright
- pydantic
- pytest
- python
- react
- router
- scikit-learn
- tailwind
- typescript
- uvicorn
- vite
- vitest
Log in or sign up for Devpost to join the conversation.