Skip to content

feat(telegram): echo voice transcripts#196

Open
heswithme wants to merge 1 commit intobanteg:masterfrom
heswithme:stt-log
Open

feat(telegram): echo voice transcripts#196
heswithme wants to merge 1 commit intobanteg:masterfrom
heswithme:stt-log

Conversation

@heswithme
Copy link

PR: Telegram voice transcription echo

Adds an optional Telegram transport setting, transports.telegram.voice_transcription_echo (default: false), to reply to voice notes with the raw transcript before continuing the normal run flow.

Usage

[transports.telegram]
voice_transcription = true
voice_transcription_echo = true

Behavior

  • On successful transcription (and echo enabled), send a separate reply:
    • label: voice transcript:
    • transcript rendered as a blockquote
    • silent notify
    • respects topic thread_id
  • Echo is only sent for non-empty transcripts
  • Transcription failures unchanged (error + skip)

Changes

  • Config: add voice_transcription_echo to Telegram transport + bridge config; wire through backend
  • Docs:
    • docs/how-to/voice-notes.md
    • docs/reference/config.md
    • docs/reference/transports/telegram.md
  • Tests: add echo behavior coverage; extend backend wiring test

Verification

uv run -m pytest -q
# 541 passed

Copilot AI review requested due to automatic review settings February 6, 2026 13:49
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds an optional feature to echo voice transcripts back to users in Telegram. When voice_transcription_echo is enabled, the bot sends a separate reply containing the raw transcript in blockquote format before processing the voice message normally.

Changes:

  • Added voice_transcription_echo boolean configuration option (default: false) across the config chain
  • Implemented _send_voice_transcript_echo() function to format and send transcript replies with silent notifications
  • Updated documentation to explain the new feature and its usage

Reviewed changes

Copilot reviewed 9 out of 9 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
src/takopi/settings.py Added voice_transcription_echo field to TelegramTransportSettings
src/takopi/telegram/bridge.py Added voice_transcription_echo field to TelegramBridgeConfig
src/takopi/telegram/backend.py Wired voice_transcription_echo setting through to bridge config
src/takopi/telegram/loop.py Implemented echo logic with blockquote formatting and silent notification
tests/test_telegram_backend.py Added assertion to verify echo setting is passed through backend
tests/test_telegram_bridge.py Added comprehensive test for echo message format and behavior
docs/reference/config.md Documented the new configuration option
docs/reference/transports/telegram.md Added usage examples and explanation
docs/how-to/voice-notes.md Added documentation for the echo feature

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +2103 to +2118
yield TelegramIncomingMessage(
transport="telegram",
chat_id=123,
message_id=1,
text="",
reply_to_message_id=None,
reply_to_text=None,
sender_id=123,
voice=TelegramVoice(
file_id="voice-1",
mime_type=None,
file_size=None,
duration=None,
raw={"file_id": "voice-1"},
),
)
Copy link

Copilot AI Feb 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The test should verify the behavior when the incoming message has a thread_id set. According to the implementation at line 175 in loop.py, the thread_id from the incoming message should be passed through to SendOptions. This is important for maintaining proper thread context in Telegram forum topics. Consider adding a test case where the TelegramIncomingMessage includes a thread_id (e.g., thread_id=77) and asserting that first["options"].thread_id == 77.

Copilot uses AI. Check for mistakes.
Comment on lines +2085 to +2098
async def _fake_transcribe(
*,
bot: BotClient,
msg: TelegramIncomingMessage,
enabled: bool,
model: str,
max_bytes: int | None = None,
reply,
base_url: str | None = None,
api_key: str | None = None,
) -> str:
_ = bot, msg, enabled, model, max_bytes, reply, base_url, api_key
return "hello from stt"

Copy link

Copilot AI Feb 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider adding a test case for when the transcribed text is empty or contains only whitespace. The implementation at lines 150-152 in loop.py has logic to skip sending the echo when the transcript is empty after stripping, but this behavior is not explicitly tested. This edge case could occur if the transcription service returns empty strings or whitespace-only strings.

Copilot uses AI. Check for mistakes.
ddobrinskiy added a commit to ddobrinskiy/takopi that referenced this pull request Feb 27, 2026
Add configurable voice transcript echo behavior:
- New setting  in settings.py
- Echo sends transcript as reply with 🎤 emoji header (enabled by default)
- Users can disable with

Implementation:
- Added to TelegramTransportSettings, TelegramBridgeConfig
- Wired through backend.py to bridge/loop
- Conditional check in loop.py before sending transcript reply

Documentation:
- Updated config.md reference table
- Updated voice-notes.md with config examples and behavior notes
- Updated telegram.md transport reference with echo details

Tests:
- Updated existing voice transcript tests to use echo=True
- Added new test for echo=False to verify no message sent
- Updated backend test with new config assertion

Differs from upstream PR banteg#196:
- Default: true (enabled) vs false (upstream)
- Format: 🎤 emoji + italics (better UX) vs code + blockquote
- Implementation: bridge.py helper vs loop.py inline
ddobrinskiy added a commit to ddobrinskiy/takopi that referenced this pull request Feb 27, 2026
Add configurable voice transcript echo behavior:
- New setting `voice_transcription_echo: bool = true` in settings.py
- Echo sends transcript as reply with 🎤 emoji header (enabled by default)
- Users can disable with `voice_transcription_echo = false`

Implementation:
- Added to TelegramTransportSettings, TelegramBridgeConfig
- Wired through backend.py to bridge/loop
- Conditional check in loop.py before sending transcript reply

Documentation:
- Updated config.md reference table
- Updated voice-notes.md with config examples and behavior notes
- Updated telegram.md transport reference with echo details

Tests:
- Updated existing voice transcript tests to use echo=True
- Added new test for echo=False to verify no message sent
- Updated backend test with new config assertion

Inspiration: banteg#196 by @heswithme
Thanks for the idea to make echo behavior configurable!

Differs from upstream PR banteg#196:
- Default: true (enabled) vs false (upstream)
- Format: 🎤 emoji + italics (better UX) vs code + blockquote
- Implementation: bridge.py helper vs loop.py inline
ddobrinskiy added a commit to ddobrinskiy/takopi that referenced this pull request Feb 27, 2026
Add configurable voice transcript echo behavior:
- New setting `voice_transcription_echo: bool = true` in settings.py
- Echo sends transcript as reply with 🎤 emoji header (enabled by default)
- Users can disable with `voice_transcription_echo = false`

Implementation:
- Added to TelegramTransportSettings, TelegramBridgeConfig
- Wired through backend.py to bridge/loop
- Conditional check in loop.py before sending transcript reply

Documentation:
- Updated config.md reference table
- Updated voice-notes.md with config examples and behavior notes
- Updated telegram.md transport reference with echo details

Tests:
- Updated existing voice transcript tests to use echo=True
- Added new test for echo=False to verify no message sent
- Updated backend test with new config assertion

Inspiration: banteg#196 by @heswithme
Thanks for the idea to make echo behavior configurable!

Differs from upstream PR banteg#196:
- Default: true (enabled) vs false (upstream)
- Format: 🎤 emoji + italics (better UX) vs code + blockquote
- Implementation: bridge.py helper vs loop.py inline
@ddobrinskiy
Copy link

this is a duplicate of #169

@banteg banteg added the enhancement New feature or request label Mar 2, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants