mirror of
https://github.com/hansjone/dsh-im-ops.git
synced 2026-10-10 14:20:45 +08:00
Merge pull request #32 from bitxeno/feat/telegram-command-menu
This commit is contained in:
commit
0cd3d706c3
3 changed files with 155 additions and 3 deletions
|
|
@ -16,6 +16,18 @@ export function validTelegramToken(value) {
|
|||
return typeof value === 'string' && /^\d{5,20}:[A-Za-z0-9_-]{20,}$/.test(value.trim());
|
||||
}
|
||||
|
||||
const TELEGRAM_COMMAND_NAME = /^[a-z0-9_]{1,32}$/;
|
||||
|
||||
function validBotCommand(value) {
|
||||
return Boolean(value)
|
||||
&& typeof value === 'object' && !Array.isArray(value)
|
||||
&& typeof value.command === 'string' && TELEGRAM_COMMAND_NAME.test(value.command)
|
||||
&& typeof value.description === 'string' && value.description.length >= 1
|
||||
&& value.description.length <= 256;
|
||||
}
|
||||
|
||||
export const COMMANDS_MENU_BUTTON = Object.freeze({ type: 'commands' });
|
||||
|
||||
export class TelegramApi {
|
||||
#token;
|
||||
#fetch;
|
||||
|
|
@ -113,6 +125,25 @@ export class TelegramApi {
|
|||
}, { signal });
|
||||
}
|
||||
|
||||
async setMyCommands({ commands, scope, languageCode, signal } = {}) {
|
||||
if (!Array.isArray(commands) || commands.length === 0
|
||||
|| commands.some((command) => !validBotCommand(command))) {
|
||||
throw new TypeError('Telegram bot commands are invalid');
|
||||
}
|
||||
return this.#call('setMyCommands', {
|
||||
commands,
|
||||
...(scope ? { scope } : {}),
|
||||
...(cleanString(languageCode) ? { language_code: cleanString(languageCode) } : {}),
|
||||
}, { signal });
|
||||
}
|
||||
|
||||
async setChatMenuButton({ menuButton = COMMANDS_MENU_BUTTON, signal } = {}) {
|
||||
if (!menuButton || typeof menuButton !== 'object' || Array.isArray(menuButton)) {
|
||||
throw new TypeError('Telegram menu button is invalid');
|
||||
}
|
||||
return this.#call('setChatMenuButton', { menu_button: menuButton }, { signal });
|
||||
}
|
||||
|
||||
async #call(method, payload, { signal, timeoutMs = 15_000 } = {}) {
|
||||
const url = new URL(this.#baseUrl);
|
||||
url.pathname = `${url.pathname.replace(/\/$/, '')}/bot${this.#token}/${method}`;
|
||||
|
|
|
|||
|
|
@ -1,11 +1,26 @@
|
|||
import { createEditableMessageStream, splitMessageText } from '../shared/editable-message-stream.mjs';
|
||||
import { TelegramApi } from './telegram-api.mjs';
|
||||
import { COMMANDS_MENU_BUTTON, TelegramApi } from './telegram-api.mjs';
|
||||
import { createTelegramBridgeStatus, TelegramHarnessBridge } from './telegram-bridge.mjs';
|
||||
import {
|
||||
TELEGRAM_ACCESS_MODES,
|
||||
normalizeTelegramAccessPolicy,
|
||||
} from './config-store.mjs';
|
||||
|
||||
export const TELEGRAM_COMMAND_MENU = Object.freeze([
|
||||
{ command: 'new', description: '开启一个全新会话' },
|
||||
{ command: 'compact', description: '压缩当前会话的较早上下文' },
|
||||
{ command: 'workspace', description: '切换工作区' },
|
||||
{ command: 'workspacelist', description: '列出工作区绝对路径' },
|
||||
{ command: 'sessionlist', description: '列出会话 ID 和标题' },
|
||||
{ command: 'session', description: '将当前聊天绑定到指定会话' },
|
||||
{ command: 'models', description: '按序号列出所有可用模型' },
|
||||
{ command: 'model', description: '查看或切换当前会话模型' },
|
||||
{ command: 'stop', description: '停止当前任务' },
|
||||
{ command: 'steer', description: '纠偏当前任务' },
|
||||
{ command: 'status', description: '检查连接状态' },
|
||||
{ command: 'help', description: '显示帮助' },
|
||||
]);
|
||||
|
||||
function escaped(value) {
|
||||
return value.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
||||
}
|
||||
|
|
@ -290,6 +305,15 @@ export class TelegramRuntime {
|
|||
error.code = 'webhook-configured';
|
||||
throw error;
|
||||
}
|
||||
try {
|
||||
await api.setMyCommands({ commands: TELEGRAM_COMMAND_MENU, signal: controller.signal });
|
||||
await api.setChatMenuButton({ menuButton: COMMANDS_MENU_BUTTON, signal: controller.signal });
|
||||
} catch (error) {
|
||||
this.#logger.warn?.(
|
||||
`[dsh-im:telegram] bot ${this.#config.botId} command menu setup failed:`,
|
||||
error,
|
||||
);
|
||||
}
|
||||
const client = new TelegramBotClient({ api, signal: controller.signal });
|
||||
this.#bridge = new TelegramHarnessBridge({
|
||||
bot: client,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue