Telegram: remove last @ts-nocheck from bot-handlers.ts (#9206)

* Telegram: remove @ts-nocheck from bot-handlers.ts, use Grammy types directly, deduplicate StickerMetadata

* Telegram: remove last @ts-nocheck from bot-handlers.ts (#9206)
This commit is contained in:
Christian Klotz
2026-02-05 00:58:49 +00:00
committed by GitHub
parent 392bbddf29
commit 21f8c3db18
3 changed files with 17 additions and 25 deletions

View File

@@ -6,6 +6,7 @@ Docs: https://docs.openclaw.ai
### Changes ### Changes
- Telegram: remove last `@ts-nocheck` from `bot-handlers.ts`, use Grammy types directly, deduplicate `StickerMetadata`. Zero `@ts-nocheck` remaining in `src/telegram/`. (#9206)
- Telegram: remove `@ts-nocheck` from `bot-message.ts`, type deps via `Omit<BuildTelegramMessageContextParams>`, widen `allMedia` to `TelegramMediaRef[]`. (#9180) - Telegram: remove `@ts-nocheck` from `bot-message.ts`, type deps via `Omit<BuildTelegramMessageContextParams>`, widen `allMedia` to `TelegramMediaRef[]`. (#9180)
- Telegram: remove `@ts-nocheck` from `bot.ts`, fix duplicate `bot.catch` error handler (Grammy overrides), remove dead reaction `message_thread_id` routing, harden sticker cache guard. (#9077) - Telegram: remove `@ts-nocheck` from `bot.ts`, fix duplicate `bot.catch` error handler (Grammy overrides), remove dead reaction `message_thread_id` routing, harden sticker cache guard. (#9077)
- Onboarding: add Cloudflare AI Gateway provider setup and docs. (#7914) Thanks @roerohan. - Onboarding: add Cloudflare AI Gateway provider setup and docs. (#7914) Thanks @roerohan.

View File

@@ -1,5 +1,6 @@
// @ts-nocheck
import type { Message } from "@grammyjs/types"; import type { Message } from "@grammyjs/types";
import type { TelegramMediaRef } from "./bot-message-context.js";
import type { TelegramContext } from "./bot/types.js";
import { resolveDefaultAgentId } from "../agents/agent-scope.js"; import { resolveDefaultAgentId } from "../agents/agent-scope.js";
import { hasControlCommand } from "../auto-reply/command-detection.js"; import { hasControlCommand } from "../auto-reply/command-detection.js";
import { import {
@@ -63,7 +64,7 @@ export const registerTelegramHandlers = ({
type TextFragmentEntry = { type TextFragmentEntry = {
key: string; key: string;
messages: Array<{ msg: Message; ctx: unknown; receivedAtMs: number }>; messages: Array<{ msg: Message; ctx: TelegramContext; receivedAtMs: number }>;
timer: ReturnType<typeof setTimeout>; timer: ReturnType<typeof setTimeout>;
}; };
const textFragmentBuffer = new Map<string, TextFragmentEntry>(); const textFragmentBuffer = new Map<string, TextFragmentEntry>();
@@ -71,9 +72,9 @@ export const registerTelegramHandlers = ({
const debounceMs = resolveInboundDebounceMs({ cfg, channel: "telegram" }); const debounceMs = resolveInboundDebounceMs({ cfg, channel: "telegram" });
type TelegramDebounceEntry = { type TelegramDebounceEntry = {
ctx: unknown; ctx: TelegramContext;
msg: Message; msg: Message;
allMedia: Array<{ path: string; contentType?: string }>; allMedia: TelegramMediaRef[];
storeAllowFrom: string[]; storeAllowFrom: string[];
debounceKey: string | null; debounceKey: string | null;
botUsername?: string; botUsername?: string;
@@ -108,7 +109,7 @@ export const registerTelegramHandlers = ({
return; return;
} }
const first = entries[0]; const first = entries[0];
const baseCtx = first.ctx as { me?: unknown; getFile?: unknown } & Record<string, unknown>; const baseCtx = first.ctx;
const getFile = const getFile =
typeof baseCtx.getFile === "function" ? baseCtx.getFile.bind(baseCtx) : async () => ({}); typeof baseCtx.getFile === "function" ? baseCtx.getFile.bind(baseCtx) : async () => ({});
const syntheticMessage: Message = { const syntheticMessage: Message = {
@@ -193,11 +194,7 @@ export const registerTelegramHandlers = ({
const captionMsg = entry.messages.find((m) => m.msg.caption || m.msg.text); const captionMsg = entry.messages.find((m) => m.msg.caption || m.msg.text);
const primaryEntry = captionMsg ?? entry.messages[0]; const primaryEntry = captionMsg ?? entry.messages[0];
const allMedia: Array<{ const allMedia: TelegramMediaRef[] = [];
path: string;
contentType?: string;
stickerMetadata?: { emoji?: string; setName?: string; fileId?: string };
}> = [];
for (const { ctx } of entry.messages) { for (const { ctx } of entry.messages) {
const media = await resolveMedia(ctx, mediaMaxBytes, opts.token, opts.proxyFetch); const media = await resolveMedia(ctx, mediaMaxBytes, opts.token, opts.proxyFetch);
if (media) { if (media) {
@@ -241,7 +238,7 @@ export const registerTelegramHandlers = ({
}; };
const storeAllowFrom = await readChannelAllowFromStore("telegram").catch(() => []); const storeAllowFrom = await readChannelAllowFromStore("telegram").catch(() => []);
const baseCtx = first.ctx as { me?: unknown; getFile?: unknown } & Record<string, unknown>; const baseCtx = first.ctx;
const getFile = const getFile =
typeof baseCtx.getFile === "function" ? baseCtx.getFile.bind(baseCtx) : async () => ({}); typeof baseCtx.getFile === "function" ? baseCtx.getFile.bind(baseCtx) : async () => ({});
@@ -308,8 +305,8 @@ export const registerTelegramHandlers = ({
return; return;
} }
const messageThreadId = (callbackMessage as { message_thread_id?: number }).message_thread_id; const messageThreadId = callbackMessage.message_thread_id;
const isForum = (callbackMessage.chat as { is_forum?: boolean }).is_forum === true; const isForum = callbackMessage.chat.is_forum === true;
const resolvedThreadId = resolveTelegramForumThreadId({ const resolvedThreadId = resolveTelegramForumThreadId({
isForum, isForum,
messageThreadId, messageThreadId,
@@ -613,7 +610,7 @@ export const registerTelegramHandlers = ({
const oldChatId = String(msg.chat.id); const oldChatId = String(msg.chat.id);
const newChatId = String(msg.migrate_to_chat_id); const newChatId = String(msg.migrate_to_chat_id);
const chatTitle = (msg.chat as { title?: string }).title ?? "Unknown"; const chatTitle = msg.chat.title ?? "Unknown";
runtime.log?.(warn(`[telegram] Group migrated: "${chatTitle}" ${oldChatId}${newChatId}`)); runtime.log?.(warn(`[telegram] Group migrated: "${chatTitle}" ${oldChatId}${newChatId}`));
@@ -664,8 +661,8 @@ export const registerTelegramHandlers = ({
const chatId = msg.chat.id; const chatId = msg.chat.id;
const isGroup = msg.chat.type === "group" || msg.chat.type === "supergroup"; const isGroup = msg.chat.type === "group" || msg.chat.type === "supergroup";
const messageThreadId = (msg as { message_thread_id?: number }).message_thread_id; const messageThreadId = msg.message_thread_id;
const isForum = (msg.chat as { is_forum?: boolean }).is_forum === true; const isForum = msg.chat.is_forum === true;
const resolvedThreadId = resolveTelegramForumThreadId({ const resolvedThreadId = resolveTelegramForumThreadId({
isForum, isForum,
messageThreadId, messageThreadId,
@@ -817,7 +814,7 @@ export const registerTelegramHandlers = ({
} }
// Media group handling - buffer multi-image messages // Media group handling - buffer multi-image messages
const mediaGroupId = (msg as { media_group_id?: string }).media_group_id; const mediaGroupId = msg.media_group_id;
if (mediaGroupId) { if (mediaGroupId) {
const existing = mediaGroupBuffer.get(mediaGroupId); const existing = mediaGroupBuffer.get(mediaGroupId);
if (existing) { if (existing) {

View File

@@ -1,7 +1,7 @@
import type { Bot } from "grammy"; import type { Bot } from "grammy";
import type { OpenClawConfig } from "../config/config.js"; import type { OpenClawConfig } from "../config/config.js";
import type { DmPolicy, TelegramGroupConfig, TelegramTopicConfig } from "../config/types.js"; import type { DmPolicy, TelegramGroupConfig, TelegramTopicConfig } from "../config/types.js";
import type { TelegramContext } from "./bot/types.js"; import type { StickerMetadata, TelegramContext } from "./bot/types.js";
import { resolveAckReaction } from "../agents/identity.js"; import { resolveAckReaction } from "../agents/identity.js";
import { import {
findModelInCatalog, findModelInCatalog,
@@ -57,13 +57,7 @@ import {
export type TelegramMediaRef = { export type TelegramMediaRef = {
path: string; path: string;
contentType?: string; contentType?: string;
stickerMetadata?: { stickerMetadata?: StickerMetadata;
emoji?: string;
setName?: string;
fileId?: string;
fileUniqueId?: string;
cachedDescription?: string;
};
}; };
type TelegramMessageContextOptions = { type TelegramMessageContextOptions = {