Conversation
Adds `tgcli messages transcribe --chat <id> --id <msgId>`, exposing the `messages.transcribeAudio` MTProto method that mtcute already ships but the CLI had no path to. Accepts several `--id` flags and honours `--json`. Two behaviours that are easy to get wrong, and that this implements: - When Telegram answers `pending`, the finished text arrives as an `updateTranscribedAudio` event, not in the reply. Re-calling the method to poll for it spends the rate-limit budget and yields the unrefined first-pass text, so the command subscribes and waits (`--wait`, 60s default) and only reports `pending` if the update never comes. - Transcription is rate-limited even on Premium; `FLOOD_WAIT_X` shorter than the caller's ceiling is slept through and retried, longer ones rethrown. mtcute's own `floodSleepThreshold` does not apply here because the flood waiter middleware is not enabled on this client. Requires Telegram Premium. The non-Premium path returns a weekly trial allowance in `trial_remains_num`, surfaced as `trialRemaining`, but that branch is untested — it was developed against a Premium account. Tests cover the flood-wait retry, the ceiling, the pending/update handoff and the incomplete fallback.
leemour
force-pushed
the
feat/transcribe-voice
branch
from
September 11, 2026 18:20
7ea0021 to
5625fcf
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Adds
tgcli messages transcribe --chat <id> --id <msgId>— Telegram's own speech-to-text for voice and video messages. The underlying MTProto method (messages.transcribeAudio) is already in the bundled mtcute schema; the CLI just had no way to reach it.Accepts repeated
--id, honours--json, and follows the shape ofmessages show.Two things that are easy to get wrong
Both were found by measuring against a live account, and both are the reason this is more than a one-line wrapper.
The finished text does not come back in the reply. When Telegram answers with
pending, the refined transcription arrives later as anupdateTranscribedAudioevent. My first attempt polledtranscribeAudioin a loop instead — that spent the rate-limit budget and returned the unrefined first-pass text (no punctuation, mangled proper nouns) while reporting itself complete. The command now subscribes to the update and waits,--waitseconds, 60 by default, and only reportspending: trueif the update never arrives.Transcription is rate-limited even on Premium. A batch of six messages reliably produced
FLOOD_WAIT_13. A flood wait shorter than the caller's ceiling is slept through and retried; longer ones are rethrown. mtcute's ownfloodSleepThresholddoes not help here — it only applies when the flood waiter middleware is enabled, which this client does not configure.Verification
npx vitest run— 307 passed, 1 skipped, 19 files.tests/transcribe.test.jscovers the flood-wait retry, the ceiling, the pending-to-update handoff, and the incomplete fallback.--jsonand multi---idpaths both work.Limitation worth stating plainly
Transcription requires Telegram Premium. Without it Telegram grants a small weekly allowance, returned in
trial_remains_numand surfaced astrialRemaining— but that branch is untested, since this was developed against a Premium account. Happy to adjust if you want different behaviour when the allowance runs out.Unrelated, so not included here:
session.jsonis created world-readable (644) whileconfig.jsonandaccount.jsonare600. Since that file is the account credential, it probably wants600too — say the word and I will open a separate PR.