Nobody was logging sales notes into the CRM. Not because the CRM was bad. Because logging a note meant stopping what you were doing, opening another app, finding the right record, and typing into fields that did not match how the call actually went. So the notes lived in someone's head for a day, then in nobody's head.
I run operations at an early-stage fintech company, and a sales pipeline nobody updates is worse than no pipeline at all: the pipeline report still looked complete, and everyone kept making decisions off it. So instead of asking the team to change how they work, I built a CRM that lives inside the app they already have open all day: Telegram.
What it actually does
You type what happened, in your own words, into a chat:
called the account about pricing, they want a sheet by Friday
The bot reads that, structures it, and shows you what it understood before writing anything. You confirm, it saves. No dropdowns, no required fields, no CRM tab.
Behind that one message: Telegram sends a webhook to a small serverless function, an AI model turns the free text into a structured interaction, and it lands in Notion, which is the actual database and the dashboard everyone else looks at. The whole thing runs on four Notion databases: accounts (the relationship, which outlives any single deal), opportunities (one per sales cycle, so an upsell six months later is a new row on the same account, not a fresh contact), interactions (the timeline), and a team config table that says who is allowed in and when they want to be reminded.
It has zero application dependencies. Every call is a plain fetch. That was deliberate, not a flex: fewer moving parts means fewer places for a sales tool to quietly break on a Tuesday.
The part that actually earns its keep is the six reminder rules running on a 30-minute tick: a meeting logged with no next step after 24 hours, docs requested a week ago with nothing back, a deal gone quiet for two weeks, a client sitting on no open deal for 60 days (the upsell prompt), and a next step whose due date just arrived. Nobody has to remember to check the pipeline. The pipeline checks itself and taps the right person in Telegram.
What broke
The AI parsing step is the part I trusted least, and it earned that. Early on, the model was slow one afternoon and a note came in during that window. I found out later it had been silently dropped: no error, no record, just a conversation that never made it in. For a sales tool, a lost note is worse than an ugly one.
The fix was to stop treating the model as required infrastructure. Now, if the model call fails or times out, a plain rule-based parser takes over and saves the note anyway, flagged for a human to clean up later. It is a worse structured record. It is still a record. That one change mattered more than any prompt tuning I did.
The other thing I got wrong was assuming a scheduled cron job would just fire at the times each person wanted their reminders. The platform's free-tier scheduler runs on a fixed global interval, not per-person times, so a 9am reminder for one rep and a 7am reminder for another were never both going to happen on the same clock. I ended up pointing an external ticker at the endpoint every 30 minutes instead and letting the code decide, per person, whether now was the right moment. Small fix, but it only showed up once real people with real time zones started using it.
I also spent a day trying to route the AI calls through infrastructure I already had running for other automations, before realizing it authenticates in a way that has no path to a plain API key. Rather than force it, I wrote down exactly why it does not fit so I would stop re-proposing it to myself every few weeks. Sometimes the fastest fix is closing the door properly.
What it costs, and what it must never touch
The model call costs a fraction of a cent per note. At this bot's volume that is pennies a month, and the model is swappable with one environment variable if a better or cheaper option shows up.
The one rule I did not compromise on: this database never holds identity documents, dates of birth, or anything regulator-sensitive. That data lives somewhere else entirely, joined by an opaque reference key, and the code itself refuses to write anything that looks like it belongs there. A sales tool should make it easier to talk to people, not easier to accidentally mishandle the data that actually needs protecting.
The takeaway
I did not build a better CRM interface. I moved the CRM to the place the work was already happening, and let the reminders do the part nobody was reliably doing by hand. If a system in your business depends on someone remembering to open a second tab, fix the tab. It is usually a cheaper repair than the training everyone reaches for first.
