diff --git a/tests/gateway/test_telegram_voice_duration.py b/tests/gateway/test_telegram_voice_duration.py index 307407298f25..226d6f63e294 100644 --- a/tests/gateway/test_telegram_voice_duration.py +++ b/tests/gateway/test_telegram_voice_duration.py @@ -46,6 +46,7 @@ from plugins.platforms.telegram.adapter import ( # noqa: E402 _coerce_duration_seconds, _probe_voice_duration_seconds, ) +from tools.send_message_tool import _send_telegram # noqa: E402 def _write_wav(path, *, rate, frames): @@ -186,3 +187,37 @@ async def test_voice_send_omits_unknown_duration(monkeypatch, tmp_path): await adapter.send_voice("123", str(audio)) assert adapter._bot.send_voice.await_args.kwargs["duration"] is None + + +@pytest.mark.asyncio +@pytest.mark.parametrize( + ("filename", "is_voice", "sender_name"), + [("reply.ogg", True, "send_voice"), ("song.mp3", False, "send_audio")], +) +async def test_standalone_send_includes_duration_on_thread_retry( + monkeypatch, tmp_path, filename, is_voice, sender_name +): + audio = tmp_path / filename + audio.write_bytes(b"audio") + bot = MagicMock() + bot.send_message = AsyncMock() + bot.send_photo = AsyncMock() + bot.send_video = AsyncMock() + bot.send_voice = AsyncMock() + bot.send_audio = AsyncMock() + bot.send_document = AsyncMock() + sender = getattr(bot, sender_name) + sender.side_effect = [ + Exception("Bad Request: message thread not found"), + MagicMock(message_id=3), + ] + monkeypatch.setattr(sys.modules["telegram"], "Bot", lambda **_kwargs: bot) + monkeypatch.setattr(telegram_mod, "_probe_voice_duration_seconds", lambda _path: 314) + + result = await _send_telegram( + "token", "-1001234567890", "", media_files=[(str(audio), is_voice)], thread_id="17585" + ) + + assert result.get("success") is True, result + assert sender.await_count == 2 + assert all(call.kwargs["duration"] == 314 for call in sender.await_args_list) diff --git a/tools/send_message_tool.py b/tools/send_message_tool.py index c143ea8064f1..24e8386ce215 100644 --- a/tools/send_message_tool.py +++ b/tools/send_message_tool.py @@ -1314,6 +1314,14 @@ async def _send_telegram(token, chat_id, message, media_files=None, thread_id=No if _tg_caption is not None and not (ext in _VOICE_EXTS and is_voice): media_kwargs["caption"] = _tg_caption media_kwargs["parse_mode"] = send_parse_mode + if (ext in _VOICE_EXTS and is_voice) or ext in _TELEGRAM_SEND_AUDIO_EXTS: + try: + from plugins.platforms.telegram.adapter import _probe_voice_duration_seconds + duration = await asyncio.to_thread(_probe_voice_duration_seconds, media_path) + if duration is not None: + media_kwargs["duration"] = duration + except Exception: + pass try: if ext in _IMAGE_EXTS and not force_document: last_msg = await bot.send_photo(