




























@@ -1,4 +1,5 @@
11import { createHash } from "node:crypto";
2+import type { LanguageCode } from "@grammyjs/types";
23import type { Bot } from "grammy";
34import { logVerbose } from "openclaw/plugin-sdk/runtime-env";
45import type { RuntimeEnv } from "openclaw/plugin-sdk/runtime-env";
@@ -15,9 +16,10 @@ const TELEGRAM_COMMAND_RETRY_RATIO = 0.8;
1516const TELEGRAM_MIN_COMMAND_DESCRIPTION_LENGTH = 1;
1617const TELEGRAM_MENU_RESULT_CACHE_MAX = 128;
171818-type TelegramMenuCommand = {
19+export type TelegramMenuCommand = {
1920command: string;
2021description: string;
22+descriptionLocalizations?: Record<string, string>;
2123};
22242325type TelegramCommandMenuScope =
@@ -27,6 +29,7 @@ type TelegramCommandMenuScope =
2729type TelegramPluginCommandSpec = {
2830name: unknown;
2931description: unknown;
32+descriptionLocalizations?: Record<string, string>;
3033};
31343235const TELEGRAM_COMMAND_MENU_SCOPES: readonly TelegramCommandMenuScope[] = [
@@ -196,7 +199,11 @@ export function buildPluginTelegramMenuCommands(params: {
196199}
197200pluginCommandNames.add(normalized);
198201existingCommands.add(normalized);
199-commands.push({ command: normalized, description });
202+const menuCommand: TelegramMenuCommand = { command: normalized, description };
203+if (spec.descriptionLocalizations) {
204+menuCommand.descriptionLocalizations = spec.descriptionLocalizations;
205+}
206+commands.push(menuCommand);
200207}
201208202209return { commands, issues };
@@ -324,11 +331,33 @@ function writeCachedCommandHash(
324331syncedCommandHashes.set(key, hash);
325332}
326333334+function buildLocalizedCommandVariants(
335+commands: TelegramMenuCommand[],
336+): Array<{ languageCode: string; commands: TelegramMenuCommand[] }> {
337+const locales = new Set<string>();
338+for (const cmd of commands) {
339+if (cmd.descriptionLocalizations) {
340+for (const lang of Object.keys(cmd.descriptionLocalizations)) {
341+locales.add(lang);
342+}
343+}
344+}
345+return [...locales].toSorted().map((languageCode) => ({
346+ languageCode,
347+commands: commands.map((cmd) => ({
348+command: cmd.command,
349+description: cmd.descriptionLocalizations?.[languageCode] ?? cmd.description,
350+})),
351+}));
352+}
353+327354function formatTelegramCommandScopeOperation(
328355operation: "deleteMyCommands" | "setMyCommands",
329356scope: TelegramCommandMenuScope,
357+languageCode?: string,
330358): string {
331-return scope.label === "default" ? operation : `${operation}(${scope.label})`;
359+const base = scope.label === "default" ? operation : `${operation}(${scope.label})`;
360+return languageCode ? `${base}(${languageCode})` : base;
332361}
333362334363async function deleteTelegramMenuCommandsForScopes(params: {
@@ -359,18 +388,24 @@ async function setTelegramMenuCommandsForScopes(params: {
359388bot: Bot;
360389runtime: RuntimeEnv;
361390commands: TelegramMenuCommand[];
391+languageCode?: string;
362392shouldLog?: (err: unknown) => boolean;
363393}): Promise<void> {
364-const { bot, runtime, commands, shouldLog } = params;
394+const { bot, runtime, commands, languageCode, shouldLog } = params;
365395for (const scope of TELEGRAM_COMMAND_MENU_SCOPES) {
366396await withTelegramApiErrorLogging({
367-operation: formatTelegramCommandScopeOperation("setMyCommands", scope),
397+operation: formatTelegramCommandScopeOperation("setMyCommands", scope, languageCode),
368398 runtime,
369399 shouldLog,
370-fn: () =>
371-scope.options
372- ? bot.api.setMyCommands(commands, scope.options)
373- : bot.api.setMyCommands(commands),
400+fn: () => {
401+const opts = {
402+ ...scope.options,
403+ ...(languageCode ? { language_code: languageCode as LanguageCode } : undefined),
404+};
405+return Object.keys(opts).length > 0
406+ ? bot.api.setMyCommands(commands, opts)
407+ : bot.api.setMyCommands(commands);
408+},
374409});
375410}
376411}
@@ -428,8 +463,7 @@ export function syncTelegramMenuCommands(params: {
428463}),
429464);
430465}
431-writeCachedCommandHash(accountId, botIdentity, currentHash);
432-return;
466+break;
433467} catch (err) {
434468if (!isBotCommandsTooMuchError(err)) {
435469throw err;
@@ -449,6 +483,16 @@ export function syncTelegramMenuCommands(params: {
449483retryCommands = retryCommands.slice(0, reducedCount);
450484}
451485}
486+487+for (const variant of buildLocalizedCommandVariants(commandsToRegister)) {
488+await setTelegramMenuCommandsForScopes({
489+ bot,
490+ runtime,
491+commands: variant.commands,
492+languageCode: variant.languageCode,
493+});
494+}
495+writeCachedCommandHash(accountId, botIdentity, currentHash);
452496};
453497454498void sync().catch((err) => {
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。