Merge pull request #848 from azade-c/fix/telegram-general-topic-messages

fix(telegram): skip message_thread_id for General topic messages
This commit is contained in:
Peter Steinberger
2026-01-16 00:08:07 +00:00
committed by GitHub
3 changed files with 25 additions and 6 deletions

View File

@@ -18,6 +18,7 @@ import {
buildTelegramGroupFrom, buildTelegramGroupFrom,
buildTelegramGroupPeerId, buildTelegramGroupPeerId,
buildTelegramThreadParams, buildTelegramThreadParams,
buildTypingThreadParams,
describeReplyTarget, describeReplyTarget,
extractTelegramLocation, extractTelegramLocation,
hasBotMention, hasBotMention,
@@ -92,7 +93,7 @@ export const buildTelegramMessageContext = async ({
const sendTyping = async () => { const sendTyping = async () => {
try { try {
await bot.api.sendChatAction(chatId, "typing", buildTelegramThreadParams(resolvedThreadId)); await bot.api.sendChatAction(chatId, "typing", buildTypingThreadParams(resolvedThreadId));
} catch (err) { } catch (err) {
logVerbose(`telegram typing cue failed for chat ${chatId}: ${String(err)}`); logVerbose(`telegram typing cue failed for chat ${chatId}: ${String(err)}`);
} }

View File

@@ -19,8 +19,27 @@ export function resolveTelegramForumThreadId(params: {
return params.messageThreadId ?? undefined; return params.messageThreadId ?? undefined;
} }
/**
* Build thread params for Telegram API calls (messages, media).
* Excludes General topic (id=1) as Telegram rejects explicit message_thread_id=1
* for sendMessage calls in forum supergroups ("message thread not found" error).
*/
export function buildTelegramThreadParams(messageThreadId?: number) { export function buildTelegramThreadParams(messageThreadId?: number) {
return messageThreadId != null ? { message_thread_id: messageThreadId } : undefined; if (messageThreadId == null || messageThreadId === TELEGRAM_GENERAL_TOPIC_ID) {
return undefined;
}
return { message_thread_id: messageThreadId };
}
/**
* Build thread params for typing indicators (sendChatAction).
* Unlike sendMessage, sendChatAction accepts message_thread_id=1 for General topic.
*/
export function buildTypingThreadParams(messageThreadId?: number) {
if (messageThreadId == null) {
return undefined;
}
return { message_thread_id: messageThreadId };
} }
export function resolveTelegramStreamMode( export function resolveTelegramStreamMode(

View File

@@ -20,6 +20,7 @@ import { markdownToTelegramHtml } from "./format.js";
import { recordSentMessage } from "./sent-message-cache.js"; import { recordSentMessage } from "./sent-message-cache.js";
import { parseTelegramTarget, stripTelegramInternalPrefixes } from "./targets.js"; import { parseTelegramTarget, stripTelegramInternalPrefixes } from "./targets.js";
import { resolveTelegramVoiceSend } from "./voice.js"; import { resolveTelegramVoiceSend } from "./voice.js";
import { buildTelegramThreadParams } from "./bot/helpers.js";
type TelegramSendOpts = { type TelegramSendOpts = {
token?: string; token?: string;
@@ -166,12 +167,10 @@ export async function sendMessageTelegram(
// Build optional params for forum topics and reply threading. // Build optional params for forum topics and reply threading.
// Only include these if actually provided to keep API calls clean. // Only include these if actually provided to keep API calls clean.
const threadParams: Record<string, number> = {};
const messageThreadId = const messageThreadId =
opts.messageThreadId != null ? opts.messageThreadId : target.messageThreadId; opts.messageThreadId != null ? opts.messageThreadId : target.messageThreadId;
if (messageThreadId != null) { const threadIdParams = buildTelegramThreadParams(messageThreadId);
threadParams.message_thread_id = Math.trunc(messageThreadId); const threadParams: Record<string, number> = threadIdParams ? { ...threadIdParams } : {};
}
if (opts.replyToMessageId != null) { if (opts.replyToMessageId != null) {
threadParams.reply_to_message_id = Math.trunc(opts.replyToMessageId); threadParams.reply_to_message_id = Math.trunc(opts.replyToMessageId);
} }