mirror of
https://github.com/openclaw/openclaw.git
synced 2026-04-19 09:08:38 +00:00
fix(telegram): handle sendVoice caption-too-long by resending without caption
When TTS text exceeds Telegram's 1024-char caption limit, sendVoice throws "message caption is too long" and the entire reply (voice + text) is lost. Now catch this specific error, resend the voice note without caption, then deliver the full text as a separate message. Closes #30980 Made-with: Cursor
This commit is contained in:
committed by
Peter Steinberger
parent
a262a3ea08
commit
60f8e832e0
@@ -35,6 +35,7 @@ import type { StickerMetadata, TelegramContext } from "./types.js";
|
|||||||
const PARSE_ERR_RE = /can't parse entities|parse entities|find end of the entity/i;
|
const PARSE_ERR_RE = /can't parse entities|parse entities|find end of the entity/i;
|
||||||
const EMPTY_TEXT_ERR_RE = /message text is empty/i;
|
const EMPTY_TEXT_ERR_RE = /message text is empty/i;
|
||||||
const VOICE_FORBIDDEN_RE = /VOICE_MESSAGES_FORBIDDEN/;
|
const VOICE_FORBIDDEN_RE = /VOICE_MESSAGES_FORBIDDEN/;
|
||||||
|
const CAPTION_TOO_LONG_RE = /caption is too long/i;
|
||||||
const FILE_TOO_BIG_RE = /file is too big/i;
|
const FILE_TOO_BIG_RE = /file is too big/i;
|
||||||
const TELEGRAM_MEDIA_SSRF_POLICY = {
|
const TELEGRAM_MEDIA_SSRF_POLICY = {
|
||||||
// Telegram file downloads should trust api.telegram.org even when DNS/proxy
|
// Telegram file downloads should trust api.telegram.org even when DNS/proxy
|
||||||
@@ -230,8 +231,6 @@ export async function deliverReplies(params: {
|
|||||||
markDelivered();
|
markDelivered();
|
||||||
} catch (voiceErr) {
|
} catch (voiceErr) {
|
||||||
// Fall back to text if voice messages are forbidden in this chat.
|
// Fall back to text if voice messages are forbidden in this chat.
|
||||||
// This happens when the recipient has Telegram Premium privacy settings
|
|
||||||
// that block voice messages (Settings > Privacy > Voice Messages).
|
|
||||||
if (isVoiceMessagesForbidden(voiceErr)) {
|
if (isVoiceMessagesForbidden(voiceErr)) {
|
||||||
const fallbackText = reply.text;
|
const fallbackText = reply.text;
|
||||||
if (!fallbackText || !fallbackText.trim()) {
|
if (!fallbackText || !fallbackText.trim()) {
|
||||||
@@ -256,7 +255,38 @@ export async function deliverReplies(params: {
|
|||||||
hasReplied = true;
|
hasReplied = true;
|
||||||
}
|
}
|
||||||
markDelivered();
|
markDelivered();
|
||||||
// Skip this media item; continue with next.
|
continue;
|
||||||
|
}
|
||||||
|
if (isCaptionTooLong(voiceErr)) {
|
||||||
|
logVerbose(
|
||||||
|
"telegram sendVoice caption too long; resending voice without caption + text separately",
|
||||||
|
);
|
||||||
|
const noCaptionParams = { ...mediaParams };
|
||||||
|
delete noCaptionParams.caption;
|
||||||
|
delete noCaptionParams.parse_mode;
|
||||||
|
await withTelegramApiErrorLogging({
|
||||||
|
operation: "sendVoice",
|
||||||
|
runtime,
|
||||||
|
fn: () => bot.api.sendVoice(chatId, file, { ...noCaptionParams }),
|
||||||
|
});
|
||||||
|
markDelivered();
|
||||||
|
const fallbackText = reply.text;
|
||||||
|
if (fallbackText?.trim()) {
|
||||||
|
await sendTelegramVoiceFallbackText({
|
||||||
|
bot,
|
||||||
|
chatId,
|
||||||
|
runtime,
|
||||||
|
text: fallbackText,
|
||||||
|
chunkText,
|
||||||
|
replyToId: undefined,
|
||||||
|
thread,
|
||||||
|
linkPreview,
|
||||||
|
replyMarkup,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (replyToMessageIdForPayload && !hasReplied) {
|
||||||
|
hasReplied = true;
|
||||||
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
throw voiceErr;
|
throw voiceErr;
|
||||||
@@ -463,6 +493,13 @@ function isVoiceMessagesForbidden(err: unknown): boolean {
|
|||||||
return VOICE_FORBIDDEN_RE.test(formatErrorMessage(err));
|
return VOICE_FORBIDDEN_RE.test(formatErrorMessage(err));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function isCaptionTooLong(err: unknown): boolean {
|
||||||
|
if (err instanceof GrammyError) {
|
||||||
|
return CAPTION_TOO_LONG_RE.test(err.description);
|
||||||
|
}
|
||||||
|
return CAPTION_TOO_LONG_RE.test(formatErrorMessage(err));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns true if the error is Telegram's "file is too big" error.
|
* Returns true if the error is Telegram's "file is too big" error.
|
||||||
* This happens when trying to download files >20MB via the Bot API.
|
* This happens when trying to download files >20MB via the Bot API.
|
||||||
|
|||||||
Reference in New Issue
Block a user