A Telegram bot that turns any voice note or audio/video file into a speaker-diarized, timestamped transcript — with no 20 MB size limit. Send a recording, get the text back. An hour-long meeting works exactly the same as a ten-second voice note.
Almost every "transcribe my Telegram voice note" bot works right up until you send it a real recording — then it silently fails. That's because the Telegram Bot API refuses getFile above 20 MB (File is too big), and a 30-minute recording is well past that. The usual answers are ugly: tell the user to split the file, or route it through some paid upload service.
This bot sidesteps the limit entirely by downloading over MTProto (via Pyrogram) instead of the Bot API. MTProto lifts the ceiling to ~2 GB per file, so the bot handles long recordings natively — the same code path for a 200 KB voice note and a 1.5 GB screen recording.
- No size limit, for real. The 20 MB Bot-API wall is the whole reason this exists. MTProto downloads mean hour-long meetings, podcasts, and uncompressed WAVs just work.
- Speaker diarization out of the box. Deepgram
nova-2withdiarize=truelabels each turn (Speaker 1,Speaker 2, …) with a timestamp, so multi-person recordings read like a script, not a wall of text. - Automatic language detection. No need to tell it the language — Deepgram detects it and the transcript header reports what it found.
- Anything with audio. Voice notes, audio files, video, video notes, and documents whose MIME type is
audio/*orvideo/*are all accepted; ffmpeg normalizes every container to 16 kHz mono before transcription. - Long transcripts don't get truncated. Telegram caps a message at 4096 characters. Short transcripts come back inline; anything longer is delivered as a
.txtfile, complete. - Zero-SDK transcription. The Deepgram call is a plain
urllibPOST — no vendor SDK, no extra dependency to keep patched. The only real dependency is the Telegram client.
Telegram voice / audio / video ─► Pyrogram (MTProto) ─► temp file (≤ 2 GB)
│
ffmpeg → 16 kHz mono WAV
│
Deepgram nova-2 (diarize=true)
│
diarized + timestamped Markdown transcript
│
inline reply (short) / .txt document (long)
Two small modules:
transcribe.py— takes a file path, normalizes it with ffmpeg, POSTs it to Deepgram, and formats the JSON into[mm:ss] Speaker N: …lines with a duration/speakers/language header. Standard library only.bot.py— a Pyrogram bot session. On any incoming media it downloads over MTProto, runstranscribe()off the event loop (so the bot stays responsive), and replies. An optional allowlist restricts who can use it.
1. Get your credentials
| Variable | Where |
|---|---|
TELEGRAM_API_ID, TELEGRAM_API_HASH |
my.telegram.org/apps — needed for the MTProto download path |
TELEGRAM_BOT_TOKEN |
@BotFather |
DEEPGRAM_API_KEY |
console.deepgram.com (free tier includes credits) |
2. Install
git clone https://github.com/thomasproject-stack/telegram-transcriber
cd telegram-transcriber
python -m venv venv && source venv/bin/activate
pip install -r requirements.txt
sudo apt install ffmpeg # or: brew install ffmpeg3. Configure
cp .env.example .env
# then fill in the four keys (and, optionally, an allowlist)4. Run
python bot.pyMessage your bot, send it a voice note or an audio file, and the transcript comes straight back.
By default anyone who finds the bot can use it (and spend your Deepgram credits). Set an allowlist of Telegram user IDs to lock it down:
TELEGRAM_ALLOWED_USERS=123456789,987654321Message @userinfobot to find your own ID.
A ready-to-adapt systemd unit lives in systemd/telegram-transcriber.service:
sudo cp systemd/telegram-transcriber.service /etc/systemd/system/
# edit paths / User to match your install
sudo systemctl daemon-reload
sudo systemctl enable --now telegram-transcriber- ffmpeg is required — it's the one system dependency (everything else is
pip-installable). - The MTProto ceiling is ~2 GB (4 GB for Telegram Premium accounts). That's the file upload limit on Telegram's side, not a limit of this bot.
- Deepgram is a paid API with a free credit tier. Transcription quality, diarization, and language coverage are Deepgram's; the bot just wires it up. Swapping in another provider means changing only
transcribe.py. - Large files are read into memory as a normalized WAV before upload. A multi-hour recording can use a few hundred MB of RAM briefly — fine on a small VPS, worth knowing if you run many at once.
- The first run creates a
*.sessionfile (Pyrogram's auth cache). It's git-ignored — never commit it.
MIT — see LICENSE.