Private chats (positive numeric chat IDs) never support forum topics.
Sending message_thread_id to a private chat causes Telegram to reject
the request with '400: Bad Request: message thread not found', silently
dropping the message.
Guard all three send functions (sendMessageTelegram, sendStickerTelegram,
sendPollTelegram) to omit thread-related parameters when the target is a
private chat.
Root cause: the auto-reply pipeline can set messageThreadId from a
previous forum-group context, then reuse it when sending a DM.
Tests: add private-chat suppression assertions; update existing thread-
retry tests to use group chat IDs so the retry path is still exercised.
resolveTelegramThreadSpec now checks isForum in the non-group path.
DMs with forum/topics enabled return scope 'forum' so each topic
gets its own session, while plain DM threads keep scope 'dm'.
- Update test expectation: 'defaults to enable on Node 22'
- Update comment in fetch.ts to explain IPv4 fallback rationale
- Addresses greptile review feedback
Fixes issue where Telegram fails to send messages when IPv6 is configured
but not functional on the network.
Problem:
- Many networks (especially in Latin America) have IPv6 configured but
not properly routed by ISP/router
- Node.js tries IPv6 first, gets 'Network is unreachable' error
- With autoSelectFamily=false, Node doesn't fallback to IPv4
- Result: All Telegram API calls fail
Solution:
- Change default from false to true for Node.js 22+
- This enables automatic IPv4 fallback when IPv6 fails
- Config option channels.telegram.network.autoSelectFamily still available
for users who need to override
Symptoms fixed:
- Health check: Telegram | WARN | failed (unknown) - fetch failed
- Logs: Network request for 'sendMessage' failed
- Bot receives messages but cannot send replies
Tested on:
- macOS 26.2 (Sequoia)
- Node.js v22.15.0
- OpenClaw 2026.2.12
- Network with IPv6 configured but not routed
Catch GrammyError when getFile fails for files >20MB (Telegram Bot API limit).
Log warning, skip attachment, but continue processing message text.
- Add FILE_TOO_BIG_RE regex to detect 'file is too big' errors
- Add isFileTooBigError() and isRetryableGetFileError() helpers
- Skip retrying permanent 400 errors (they'll fail every time)
- Log specific warning for file size limit errors
- Return null so message text is still processed
Fixes#18518
The preflight transcription condition only triggered for group chats
(isGroup && requireMention), so voice notes sent in direct messages
were never transcribed — they arrived as raw <media:audio> placeholders.
This patch widens the condition to fire whenever there is audio and no
accompanying text, regardless of chat type.
It also adds a fallback path: if the standard media pipeline returns no
transcript (e.g. format mismatch, missing config), OpenClaw now calls
the configured whisper CLI command directly with the audio file, using
the same {{MediaPath}}/{{OutputBase}} template variables from config.
Co-Authored-By: TH <tzhsn.huang@gmail.com>