Bot running anonymous Chrome in Docker recorded 1,170 meetings and delivers summaries in 4.6 minutes
A Habr author built an internal meeting bot as an alternative to Copilot. In four months, it recorded about 1,170 meetings and 920 hours of speech from 93 organizers. The median time from the end of a recording to a summary with action items is 4.6 minutes. Recognition and speaker diarization run on the company's own servers, so audio never leaves its perimeter. There are two pipelines: a bot installed in a team for Teams channel meetings, and anonymous Chrome running in a container for everything else.
AI-processed from Habr AI; edited by Hamidun News
Meeting decisions tend to survive only until the next meeting. Nobody keeps minutes, and a week later participants remember about 10% of what was said. The second problem is newer: the company uses AI agents, but they know only what has been recorded and indexed. Anything decided verbally does not exist for them. The author of the Habr article set out to close both gaps with a custom meeting assistant and shared production figures.
Why not Copilot or native transcription
Copilot works only for people with a subscription, which makes it unsuitable for automating the process across every team without manual intervention. It also does not cover external tenants, Telemost, MTS Link, or TrueConf. In addition, the company wanted audio from client meetings to be processed on its own servers.
The author was also dissatisfied with Teams' native Russian transcription. For the same meetings, it produced 26–37 words per minute, while normal business speech runs at about 100 and the author's pipeline delivered 99–108. Teams also renders technical terms phonetically, writing “add button” as “ed batton.” The sample is small, and the author candidly describes the comparison as a reference point rather than a benchmark.
Two pipelines instead of one
A universal solution proved impractical because Teams meetings come in two forms.
Channel meetings—dailies, planning sessions, and retrospectives—are recorded automatically under company policy and stored in SharePoint. They do not have a conventional group chat: messages live in a thread beneath the channel's root post, and anonymous guests cannot enter it. A bot is therefore installed in the team. It reads the channel and catches the CallRecording service event with a Success status. It downloads the MP4, converts it to 16 kHz WAV, sends it for recognition, and publishes the summary in the meeting thread. This requires the ChannelMessage.Read.Group RSC permission, granted by the team owner without an administrator granting access across the entire tenant.
All other meetings are handled by “Meeting Assistant.” It is added to the invitation like a regular participant, and anonymous Chrome running in Docker joins when the meeting begins. Recording occurs only with explicit consent: if the assistant was invited and admitted, it records; otherwise, it does not. The pipelines are physically separated, with their own registrations, applications, and permissions, so a leaked key from one cannot compromise the other.
Pitfalls worth remembering
Recording race condition. State was initially stored in JSON files, and during the first week the listener and a fallback cron job submitted the same recording twice. The fix was Postgres with INSERT … ON CONFLICT DO NOTHING and SELECT … FOR UPDATE; the claim operation returns one of four modes: new, retake, attach, or skip.
Transcript dead ends. The ChannelMeetingTranscript.Read.Group RSC permission returned 403, SharePoint rejected an app-only token without a certificate, and Graph's onlineMeetings/transcripts endpoint requires an application access policy for the organizer. The pipeline is therefore built around MP4 files and in-house recognition, with Teams VTT used as an auxiliary source.
Speaker names. The number of speakers—the num_speakers hint—and their names come from the VTT file. Segments are then matched to diarization clusters by time lag. Across three manually checked meetings, 94–99% of segments received the correct name. Any failed match is labeled “Anonymous”: a wrongly attributed line is worse than an anonymous one.
Graph API also cannot see the calendar in on-prem Exchange, so the developers had to use EWS. The browser-based poster's session would silently expire because of a session cookie, while the active-speaker detector captured only a quarter of the speech until the implementation switched from events to state polling.
What this means in practice
If you are building something similar, the conclusion is straightforward. Do not try to cover every platform with one solution: Teams channel meetings are cheaper to handle with a bot installed in the team, while everything else is better served by joining the conversation. Store state in a database with locking, not in files. Tailor summary prompts to the meeting type—daily, retrospective, or planning—and load them for every submission so they can be edited without a restart. Most importantly, transcripts indexed by the platform give agents a memory of decisions made verbally. That is the foundation for proactive agents.
There are limitations. Pipeline 1 does not support private channels; in external meetings, someone must admit the bot from the lobby; and Teams itself has bugs that can cause the bot to stop receiving channel updates (msteams-docs issue #11106). The figures also come from a single company and have not been independently verified, but four months in production with 93 organizers is compelling evidence.
- Nov 8, 2026Pentagon Introduces 3 Checks for Every Piece of AI-Generated Code
- Nov 8, 2026GitHub expands Copilot analytics to nine usage scenarios
- Nov 8, 2026GitHub opens Copilot Code Review management via API at three levels
- Nov 8, 2026Docx Anonymizer recognizes 50 data categories and supports nine formats
Key Questions Answered
Why not Copilot or native transcription?
Copilot works only for people with a subscription, which makes it unsuitable for automating the process across every team without manual intervention. It also does not cover external tenants, Telemost, MTS Link, or TrueConf. In addition, the company wanted audio from client meetings to be processed on its own servers. The author was also dissatisfied with Teams' native Russian transcription.
What are the key details on Two pipelines instead of one?
A universal solution proved impractical because Teams meetings come in two forms. Channel meetings—dailies, planning sessions, and retrospectives—are recorded automatically under company policy and stored in SharePoint. They do not have a conventional group chat: messages live in a thread beneath the channel's root post, and anonymous guests cannot enter it. A bot is therefore installed in the team. It reads the channel and catches the CallRecording service event with a Success status.
What are the key details on Pitfalls worth remembering?
Recording race condition. State was initially stored in JSON files, and during the first week the listener and a fallback cron job submitted the same recording twice. The fix was Postgres with INSERT … ON CONFLICT DO NOTHING and SELECT … FOR UPDATE; the claim operation returns one of four modes: new, retake, attach, or skip. Transcript dead ends.
Build & Ship Production AI Agents Without Boilerplate Code
Start your free 72-hour trial at Hamidun Academy (academy.hamidun.com) — interactive lessons on Claude Code & Cursor, live Tech Radar, and production agent templates.
The AI world, distilled — once a week
Seven stories that actually mattered, hand-picked. No noise, no reposts, no press releases.
Done! Check your inbox for a confirmation.