diff --git a/extensions/telegram/src/action-runtime.ts b/extensions/telegram/src/action-runtime.ts index 5aeac6c9511..6ca3982d5db 100644 --- a/extensions/telegram/src/action-runtime.ts +++ b/extensions/telegram/src/action-runtime.ts @@ -79,6 +79,10 @@ type RawTelegramButton = { text?: unknown; }; +function resolveTelegramForumTopicIconColor(value: number | undefined) { + return typeof value === "number" ? value : undefined; +} + function resolveTelegramPollVisibility(params: { pollAnonymous?: boolean; pollPublic?: boolean; @@ -581,7 +585,9 @@ export async function handleTelegramAction( } const chatId = readTelegramChatId(params); const name = readStringParam(params, "name", { required: true }); - const iconColor = readNumberParam(params, "iconColor", { integer: true }); + const iconColor = resolveTelegramForumTopicIconColor( + readNumberParam(params, "iconColor", { integer: true }) ?? undefined, + ); const iconCustomEmojiId = readStringParam(params, "iconCustomEmojiId"); if ( typeof iconColor === "number" && diff --git a/extensions/telegram/src/bot-message-context.ts b/extensions/telegram/src/bot-message-context.ts index 26537325805..3186dc18353 100644 --- a/extensions/telegram/src/bot-message-context.ts +++ b/extensions/telegram/src/bot-message-context.ts @@ -76,7 +76,6 @@ export type TelegramMessageContext = { statusReactionController: StatusReactionController | null; accountId: string; }; - export const buildTelegramMessageContext = async ({ primaryCtx, allMedia, @@ -429,7 +428,7 @@ export const buildTelegramMessageContext = async ({ : null; // When status reactions are enabled, setQueued() replaces the simple ack reaction - const ackReactionPromise = statusReactionController + const ackReactionPromise: Promise | null = statusReactionController ? shouldAckReaction() ? Promise.resolve(statusReactionController.setQueued()).then( () => true, @@ -469,7 +468,7 @@ export const buildTelegramMessageContext = async ({ route, rawBody: bodyResult.rawBody, bodyText: bodyResult.bodyText, - historyKey: bodyResult.historyKey, + historyKey: bodyResult.historyKey ?? "", historyLimit, groupHistories, groupConfig, @@ -493,7 +492,7 @@ export const buildTelegramMessageContext = async ({ threadSpec, replyThreadId, isForum, - historyKey: bodyResult.historyKey, + historyKey: bodyResult.historyKey ?? "", historyLimit, groupHistories, route, diff --git a/extensions/telegram/src/bot/types.ts b/extensions/telegram/src/bot/types.ts index 3089317161d..516da65b23c 100644 --- a/extensions/telegram/src/bot/types.ts +++ b/extensions/telegram/src/bot/types.ts @@ -5,6 +5,7 @@ export type TelegramStreamMode = "off" | "partial" | "block"; export type TelegramGetFile = () => Promise<{ file_path?: string }>; export type TelegramChatDetails = { + id?: number | string; available_reactions?: ChatFullInfo["available_reactions"] | null; is_forum?: boolean; }; diff --git a/extensions/telegram/src/draft-stream.ts b/extensions/telegram/src/draft-stream.ts index bc9147664db..d44122e14d0 100644 --- a/extensions/telegram/src/draft-stream.ts +++ b/extensions/telegram/src/draft-stream.ts @@ -23,6 +23,16 @@ type TelegramSendMessageDraft = ( type TelegramSendMessageParams = Parameters[2]; +function hasNumericMessageThreadId( + params: TelegramSendMessageParams | undefined, +): params is TelegramSendMessageParams & { message_thread_id: number } { + return ( + typeof params === "object" && + params !== null && + typeof (params as { message_thread_id?: unknown }).message_thread_id === "number" + ); +} + /** * Keep draft-id allocation shared across bundled chunks so concurrent preview * lanes do not accidentally reuse draft ids when code-split entries coexist. @@ -179,9 +189,7 @@ export function createTelegramDraftStream(params: { parse_mode: sendArgs.renderedParseMode, } : replyParams; - const usedThreadParams = - typeof (sendParams as { message_thread_id?: unknown } | undefined)?.message_thread_id === - "number"; + const usedThreadParams = hasNumericMessageThreadId(sendParams); try { return { sent: await params.api.sendMessage(chatId, sendArgs.renderedText, sendParams),