mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-09 13:07:39 +00:00
fix(telegram): suppress message_thread_id for private chat sends (#17242)
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.
This commit is contained in:
committed by
Peter Steinberger
parent
2ed43fd7b4
commit
b4a90bb743
@@ -196,6 +196,17 @@ function isTelegramMessageNotModifiedError(err: unknown): boolean {
|
||||
return MESSAGE_NOT_MODIFIED_RE.test(formatErrorMessage(err));
|
||||
}
|
||||
|
||||
/**
|
||||
* Telegram private chats have positive numeric IDs.
|
||||
* Groups and supergroups have negative IDs (typically -100… for supergroups).
|
||||
* Private chats never support forum topics, so `message_thread_id` must
|
||||
* not be included in API calls targeting them (#17242).
|
||||
*/
|
||||
function isTelegramPrivateChat(chatId: string): boolean {
|
||||
const n = Number(chatId);
|
||||
return Number.isFinite(n) && n > 0;
|
||||
}
|
||||
|
||||
function hasMessageThreadIdParam(params?: Record<string, unknown>): boolean {
|
||||
if (!params) {
|
||||
return false;
|
||||
@@ -428,9 +439,10 @@ export async function sendMessageTelegram(
|
||||
const mediaUrl = opts.mediaUrl?.trim();
|
||||
const replyMarkup = buildInlineKeyboard(opts.buttons);
|
||||
|
||||
const isPrivate = isTelegramPrivateChat(chatId);
|
||||
const threadParams = buildTelegramThreadReplyParams({
|
||||
targetMessageThreadId: target.messageThreadId,
|
||||
messageThreadId: opts.messageThreadId,
|
||||
targetMessageThreadId: isPrivate ? undefined : target.messageThreadId,
|
||||
messageThreadId: isPrivate ? undefined : opts.messageThreadId,
|
||||
replyToMessageId: opts.replyToMessageId,
|
||||
quoteText: opts.quoteText,
|
||||
});
|
||||
@@ -919,9 +931,10 @@ export async function sendStickerTelegram(
|
||||
const target = parseTelegramTarget(to);
|
||||
const chatId = normalizeChatId(target.chatId);
|
||||
|
||||
const isPrivate = isTelegramPrivateChat(chatId);
|
||||
const threadParams = buildTelegramThreadReplyParams({
|
||||
targetMessageThreadId: target.messageThreadId,
|
||||
messageThreadId: opts.messageThreadId,
|
||||
targetMessageThreadId: isPrivate ? undefined : target.messageThreadId,
|
||||
messageThreadId: isPrivate ? undefined : opts.messageThreadId,
|
||||
replyToMessageId: opts.replyToMessageId,
|
||||
});
|
||||
const hasThreadParams = Object.keys(threadParams).length > 0;
|
||||
@@ -997,9 +1010,10 @@ export async function sendPollTelegram(
|
||||
// Normalize the poll input (validates question, options, maxSelections)
|
||||
const normalizedPoll = normalizePollInput(poll, { maxOptions: 10 });
|
||||
|
||||
const isPrivate = isTelegramPrivateChat(chatId);
|
||||
const threadParams = buildTelegramThreadReplyParams({
|
||||
targetMessageThreadId: target.messageThreadId,
|
||||
messageThreadId: opts.messageThreadId,
|
||||
targetMessageThreadId: isPrivate ? undefined : target.messageThreadId,
|
||||
messageThreadId: isPrivate ? undefined : opts.messageThreadId,
|
||||
replyToMessageId: opts.replyToMessageId,
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user