refactor(telegram): inject shared bot deps

This commit is contained in:
Ayaan Zaidi
2026-03-18 10:08:30 +05:30
parent 243dabc186
commit b85d97f22c
5 changed files with 49 additions and 43 deletions

View File

@@ -0,0 +1,28 @@
import { loadConfig, resolveStorePath } from "openclaw/plugin-sdk/config-runtime";
import { readChannelAllowFromStore } from "openclaw/plugin-sdk/conversation-runtime";
import { enqueueSystemEvent } from "openclaw/plugin-sdk/infra-runtime";
import {
dispatchReplyWithBufferedBlockDispatcher,
listSkillCommandsForAgents,
} from "openclaw/plugin-sdk/reply-runtime";
import { wasSentByBot } from "./sent-message-cache.js";
export type TelegramBotDeps = {
loadConfig: typeof loadConfig;
resolveStorePath: typeof resolveStorePath;
readChannelAllowFromStore: typeof readChannelAllowFromStore;
enqueueSystemEvent: typeof enqueueSystemEvent;
dispatchReplyWithBufferedBlockDispatcher: typeof dispatchReplyWithBufferedBlockDispatcher;
listSkillCommandsForAgents: typeof listSkillCommandsForAgents;
wasSentByBot: typeof wasSentByBot;
};
export const defaultTelegramBotDeps: TelegramBotDeps = {
loadConfig,
resolveStorePath,
readChannelAllowFromStore,
enqueueSystemEvent,
dispatchReplyWithBufferedBlockDispatcher,
listSkillCommandsForAgents,
wasSentByBot,
};

View File

@@ -24,10 +24,10 @@ import type {
import { getAgentScopedMediaLocalRoots } from "openclaw/plugin-sdk/media-runtime";
import { resolveChunkMode } from "openclaw/plugin-sdk/reply-runtime";
import { clearHistoryEntriesIfEnabled } from "openclaw/plugin-sdk/reply-runtime";
import { dispatchReplyWithBufferedBlockDispatcher } from "openclaw/plugin-sdk/reply-runtime";
import type { ReplyPayload } from "openclaw/plugin-sdk/reply-runtime";
import { danger, logVerbose } from "openclaw/plugin-sdk/runtime-env";
import type { RuntimeEnv } from "openclaw/plugin-sdk/runtime-env";
import { defaultTelegramBotDeps, type TelegramBotDeps } from "./bot-deps.js";
import type { TelegramMessageContext } from "./bot-message-context.js";
import type { TelegramBotOptions } from "./bot.js";
import { deliverReplies } from "./bot/delivery.js";
@@ -52,18 +52,6 @@ import { editMessageTelegram } from "./send.js";
import { cacheSticker, describeStickerImage } from "./sticker-cache.js";
const EMPTY_RESPONSE_FALLBACK = "No response generated. Please try again.";
const DEFAULT_BOT_MESSAGE_DISPATCH_RUNTIME = {
dispatchReplyWithBufferedBlockDispatcher,
};
let botMessageDispatchRuntimeForTest:
| Partial<typeof DEFAULT_BOT_MESSAGE_DISPATCH_RUNTIME>
| undefined;
export function setBotMessageDispatchRuntimeForTest(
runtime?: Partial<typeof DEFAULT_BOT_MESSAGE_DISPATCH_RUNTIME>,
): void {
botMessageDispatchRuntimeForTest = runtime;
}
/** Minimum chars before sending first streaming message (improves push notification UX) */
const DRAFT_MIN_INITIAL_CHARS = 30;
@@ -122,6 +110,7 @@ type DispatchTelegramMessageParams = {
streamMode: TelegramStreamMode;
textLimit: number;
telegramCfg: TelegramAccountConfig;
telegramDeps?: TelegramBotDeps;
opts: Pick<TelegramBotOptions, "token">;
};
@@ -159,12 +148,9 @@ export const dispatchTelegramMessage = async ({
streamMode,
textLimit,
telegramCfg,
telegramDeps = defaultTelegramBotDeps,
opts,
}: DispatchTelegramMessageParams) => {
const botMessageDispatchRuntime = {
...DEFAULT_BOT_MESSAGE_DISPATCH_RUNTIME,
...botMessageDispatchRuntimeForTest,
};
const {
ctxPayload,
msg,
@@ -551,7 +537,7 @@ export const dispatchTelegramMessage = async ({
let dispatchError: unknown;
try {
({ queuedFinal } = await botMessageDispatchRuntime.dispatchReplyWithBufferedBlockDispatcher({
({ queuedFinal } = await telegramDeps.dispatchReplyWithBufferedBlockDispatcher({
ctx: ctxPayload,
cfg,
dispatcherOptions: {

View File

@@ -2,6 +2,7 @@ import type { ReplyToMode } from "openclaw/plugin-sdk/config-runtime";
import type { TelegramAccountConfig } from "openclaw/plugin-sdk/config-runtime";
import { danger } from "openclaw/plugin-sdk/runtime-env";
import type { RuntimeEnv } from "openclaw/plugin-sdk/runtime-env";
import type { TelegramBotDeps } from "./bot-deps.js";
import {
buildTelegramMessageContext,
type BuildTelegramMessageContextParams,
@@ -21,6 +22,7 @@ type TelegramMessageProcessorDeps = Omit<
replyToMode: ReplyToMode;
streamMode: TelegramStreamMode;
textLimit: number;
telegramDeps: TelegramBotDeps;
opts: Pick<TelegramBotOptions, "token">;
};
@@ -45,6 +47,7 @@ export const createTelegramMessageProcessor = (deps: TelegramMessageProcessorDep
replyToMode,
streamMode,
textLimit,
telegramDeps,
opts,
} = deps;
@@ -89,6 +92,7 @@ export const createTelegramMessageProcessor = (deps: TelegramMessageProcessorDep
streamMode,
textLimit,
telegramCfg,
telegramDeps,
opts,
});
} catch (err) {

View File

@@ -37,8 +37,6 @@ import {
resolveCommandArgMenu,
} from "openclaw/plugin-sdk/reply-runtime";
import { finalizeInboundContext } from "openclaw/plugin-sdk/reply-runtime";
import { dispatchReplyWithBufferedBlockDispatcher } from "openclaw/plugin-sdk/reply-runtime";
import { listSkillCommandsForAgents } from "openclaw/plugin-sdk/reply-runtime";
import { resolveAgentRoute } from "openclaw/plugin-sdk/routing";
import { resolveThreadSessionKeys } from "openclaw/plugin-sdk/routing";
import { danger, logVerbose } from "openclaw/plugin-sdk/runtime-env";
@@ -46,6 +44,7 @@ import { getChildLogger } from "openclaw/plugin-sdk/runtime-env";
import type { RuntimeEnv } from "openclaw/plugin-sdk/runtime-env";
import { withTelegramApiErrorLogging } from "./api-logging.js";
import { isSenderAllowed, normalizeDmAllowFromWithStore } from "./bot-access.js";
import { defaultTelegramBotDeps, type TelegramBotDeps } from "./bot-deps.js";
import type { TelegramMediaRef } from "./bot-message-context.js";
import {
buildCappedTelegramMenuCommands,
@@ -77,19 +76,6 @@ import { resolveTelegramGroupPromptSettings } from "./group-config-helpers.js";
import { buildInlineKeyboard } from "./send.js";
const EMPTY_RESPONSE_FALLBACK = "No response generated. Please try again.";
const DEFAULT_BOT_NATIVE_COMMANDS_RUNTIME = {
dispatchReplyWithBufferedBlockDispatcher,
listSkillCommandsForAgents,
};
let botNativeCommandsRuntimeForTest:
| Partial<typeof DEFAULT_BOT_NATIVE_COMMANDS_RUNTIME>
| undefined;
export function setBotNativeCommandsRuntimeForTest(
runtime?: Partial<typeof DEFAULT_BOT_NATIVE_COMMANDS_RUNTIME>,
): void {
botNativeCommandsRuntimeForTest = runtime;
}
type TelegramNativeCommandContext = Context & { match?: string };
@@ -114,6 +100,7 @@ export type RegisterTelegramHandlerParams = {
telegramTransport?: TelegramTransport;
runtime: RuntimeEnv;
telegramCfg: TelegramAccountConfig;
telegramDeps?: TelegramBotDeps;
allowFrom?: Array<string | number>;
groupAllowFrom?: Array<string | number>;
resolveGroupPolicy: (chatId: string | number) => ChannelGroupPolicy;
@@ -155,6 +142,7 @@ export type RegisterTelegramNativeCommandsParams = {
messageThreadId?: number,
) => { groupConfig?: TelegramGroupConfig; topicConfig?: TelegramTopicConfig };
shouldSkipUpdate: (ctx: TelegramUpdateKeyContext) => boolean;
telegramDeps?: TelegramBotDeps;
opts: { token: string };
};
@@ -377,12 +365,9 @@ export const registerTelegramNativeCommands = ({
resolveGroupPolicy,
resolveTelegramGroupConfig,
shouldSkipUpdate,
telegramDeps = defaultTelegramBotDeps,
opts,
}: RegisterTelegramNativeCommandsParams) => {
const botNativeCommandsRuntime = {
...DEFAULT_BOT_NATIVE_COMMANDS_RUNTIME,
...botNativeCommandsRuntimeForTest,
};
const silentErrorReplies = telegramCfg.silentErrorReplies === true;
const boundRoute =
nativeEnabled && nativeSkillsEnabled
@@ -395,7 +380,7 @@ export const registerTelegramNativeCommands = ({
}
const skillCommands =
nativeEnabled && nativeSkillsEnabled && boundRoute
? botNativeCommandsRuntime.listSkillCommandsForAgents({
? telegramDeps.listSkillCommandsForAgents({
cfg,
agentIds: [boundRoute.agentId],
})
@@ -776,7 +761,7 @@ export const registerTelegramNativeCommands = ({
accountId: route.accountId,
});
await botNativeCommandsRuntime.dispatchReplyWithBufferedBlockDispatcher({
await telegramDeps.dispatchReplyWithBufferedBlockDispatcher({
ctx: ctxPayload,
cfg,
dispatcherOptions: {

View File

@@ -10,7 +10,6 @@ import {
resolveNativeSkillsEnabled,
} from "openclaw/plugin-sdk/config-runtime";
import type { OpenClawConfig, ReplyToMode } from "openclaw/plugin-sdk/config-runtime";
import { loadConfig } from "openclaw/plugin-sdk/config-runtime";
import {
resolveChannelGroupPolicy,
resolveChannelGroupRequireMention,
@@ -24,6 +23,7 @@ import { getChildLogger } from "openclaw/plugin-sdk/runtime-env";
import { createSubsystemLogger } from "openclaw/plugin-sdk/runtime-env";
import { createNonExitingRuntime, type RuntimeEnv } from "openclaw/plugin-sdk/runtime-env";
import { resolveTelegramAccount } from "./accounts.js";
import { defaultTelegramBotDeps, type TelegramBotDeps } from "./bot-deps.js";
import { registerTelegramHandlers } from "./bot-handlers.js";
import { createTelegramMessageProcessor } from "./bot-message.js";
import { registerTelegramNativeCommands } from "./bot-native-commands.js";
@@ -64,6 +64,7 @@ export type TelegramBotOptions = {
};
/** Pre-resolved Telegram transport to reuse across bot instances. If not provided, creates a new one. */
telegramTransport?: TelegramTransport;
telegramDeps?: TelegramBotDeps;
};
export { getTelegramSequentialKey };
@@ -72,14 +73,12 @@ type TelegramBotRuntime = {
Bot: typeof Bot;
sequentialize: typeof sequentialize;
apiThrottler: typeof apiThrottler;
loadConfig: typeof loadConfig;
};
const DEFAULT_TELEGRAM_BOT_RUNTIME: TelegramBotRuntime = {
Bot,
sequentialize,
apiThrottler,
loadConfig,
};
let telegramBotRuntimeForTest: TelegramBotRuntime | undefined;
@@ -124,7 +123,8 @@ function extractTelegramApiMethod(input: TelegramFetchInput): string | null {
export function createTelegramBot(opts: TelegramBotOptions) {
const botRuntime = telegramBotRuntimeForTest ?? DEFAULT_TELEGRAM_BOT_RUNTIME;
const runtime: RuntimeEnv = opts.runtime ?? createNonExitingRuntime();
const cfg = opts.config ?? botRuntime.loadConfig();
const telegramDeps = opts.telegramDeps ?? defaultTelegramBotDeps;
const cfg = opts.config ?? telegramDeps.loadConfig();
const account = resolveTelegramAccount({
cfg,
accountId: opts.accountId,
@@ -490,6 +490,7 @@ export function createTelegramBot(opts: TelegramBotOptions) {
streamMode,
textLimit,
opts,
telegramDeps,
});
registerTelegramNativeCommands({
@@ -510,6 +511,7 @@ export function createTelegramBot(opts: TelegramBotOptions) {
resolveTelegramGroupConfig,
shouldSkipUpdate,
opts,
telegramDeps,
});
registerTelegramHandlers({
@@ -528,6 +530,7 @@ export function createTelegramBot(opts: TelegramBotOptions) {
shouldSkipUpdate,
processMessage,
logger,
telegramDeps,
});
const originalStop = bot.stop.bind(bot);