PlanetPulse · Tech Lead · Oct 2026 to now
Meeting minutes that arrive once, for the meeting that happened
An internal meeting notetaker. A bot joins the call, the recording is transcribed with each speaker’s name, and an LLM turns it into minutes that reach everyone invited shortly after the call ends.
The problem
Minutes get written late or not at all. A bot that writes them brings its own problems: two notetakers in one call when two calendars both book it, minutes titled after what the meeting was called last week, and on Teams, short interjections credited to whoever was already talking.
What I built
- Built it alone: a Python and FastAPI service, a Next.js dashboard, and a self-hosted Attendee instance that runs the bots on Teams, Google Meet and Zoom.
- Calendar sync for Google and Microsoft, work and personal accounts. The notetaker joins every meeting you haven’t declined, or only the ones you organise or invite it to, and you can send it to a link or schedule a Teams or Meet call from the dashboard.
- One notetaker per meeting, however many calendars it’s on. Invite copies of one Teams meeting can spell the link differently and the bot platform matches links exactly, so bots are matched by calendar event, by link within ten minutes, and by title and start time.
- Notetakers that haven’t joined yet follow their meeting: a new title, a changed guest list or a new time is picked up on the next calendar sync, and external recipients added by hand are kept.
- Speaker separation. Teams gives the bot one mixed audio stream, so after the call the recording is re-transcribed with diarisation, and each voice is named after the participant whose turns it covers the largest share of.
- A crosstalk filter. A laptop playing a different call next to someone’s mic ends up in the recording, so a re-transcribed turn is kept only when the live transcript heard enough of the same words around that moment. When the live transcript is too thin to judge, nothing is dropped.
- Minutes as schema-validated JSON, with one retry on bad output and a prompt that forbids inventing owners or dates. Delivery fails safe: only approved email domains unless approved for that meeting, never sent twice after a restart, and the organiser is told when the bot wasn’t let in or nothing was said.
- Over 300 backend tests with an 80% coverage floor, and Vitest for the web app. Both ship as Docker images on Dokploy.
What changed
It runs in production on the company’s own servers. Minutes reach everyone invited a minute or two after each call, in English even when the meeting was in Hindi, and a notes page lets them replay the audio against a transcript they can search.