fix: preserve Telegram compatibility and stabilize Office

This commit is contained in:
xmanrui 2026-08-21 01:37:21 +08:00
parent 7f114e1c36
commit 24e690498b
23 changed files with 1679 additions and 314 deletions

View file

@ -5,23 +5,7 @@ import { TelegramRuntime } from '../../../../src/channels/telegram/telegram-runt
import { TelegramStateStore } from '../../../../src/channels/telegram/state-store.mjs';
import { createTokenProductionController } from '../shared/production.mjs';
const TELEGRAM_USER_ID = /^[1-9]\d{0,15}$/;
export function normalizeTelegramAllowedUsers(value) {
if (value === undefined) return Object.freeze([]);
if (!Array.isArray(value)) {
throw new TypeError('telegram.allowedUsers must be an array of numeric Telegram User IDs');
}
const normalized = value.map((entry) => {
const userId = typeof entry === 'number' && Number.isSafeInteger(entry)
? String(entry) : typeof entry === 'string' ? entry.trim() : '';
if (!TELEGRAM_USER_ID.test(userId)) {
throw new TypeError('telegram.allowedUsers contains an invalid Telegram User ID');
}
return userId;
});
return Object.freeze([...new Set(normalized)]);
}
export { normalizeTelegramAllowedUsers } from '../../../../src/channels/telegram/config-store.mjs';
export function createProductionController(ctx, config = {}, internals = {}) {
return createTokenProductionController(ctx, config, internals, {
@ -31,8 +15,5 @@ export function createProductionController(ctx, config = {}, internals = {}) {
HarnessClient: TelegramHarnessClient,
Controller: TelegramController,
Runtime: TelegramRuntime,
runtimeOptions: (runtimeConfig) => ({
allowedPrivateUserIds: normalizeTelegramAllowedUsers(runtimeConfig.allowedUsers),
}),
});
}

View file

@ -1,21 +1,71 @@
import {
TOKEN_BOT_ENDPOINTS,
createTokenBotRpcHandler,
installTokenBotRpc,
} from '../shared/rpc.mjs';
import { resolveRpcAuthority } from '../../rpc-authority.mjs';
import { normalizeTelegramAccessPolicy } from '../../../../src/channels/telegram/config-store.mjs';
export const TELEGRAM_RPC_CHANNEL = '/telegram';
export const TELEGRAM_ENDPOINTS = TOKEN_BOT_ENDPOINTS;
export const TELEGRAM_ENDPOINTS = Object.freeze({
...TOKEN_BOT_ENDPOINTS,
setAccessPolicy: 'bot.access-policy.set',
});
export const TELEGRAM_RPC_ENDPOINTS = Object.freeze(Object.values(TELEGRAM_ENDPOINTS));
export function createTelegramRpcHandler(controller) {
return createTokenBotRpcHandler(controller, { channel: 'Telegram' });
if (typeof controller?.setAccessPolicy !== 'function') {
throw new TypeError('A complete Telegram controller is required (setAccessPolicy)');
}
const sharedHandler = createTokenBotRpcHandler(controller, { channel: 'Telegram' });
return async (endpoint, payload, signal) => {
if (endpoint !== TELEGRAM_ENDPOINTS.setAccessPolicy) {
return sharedHandler(endpoint, payload, signal);
}
if (signal?.aborted) {
return { ok: false, error: { code: 'cancelled', message: 'The request was cancelled.' } };
}
const keys = payload && typeof payload === 'object' && !Array.isArray(payload)
? Object.keys(payload) : [];
if (keys.length !== 3 || !keys.every((key) => (
['botId', 'accessMode', 'allowedUsers'].includes(key)
)) || typeof payload.botId !== 'string' || !/^[A-Za-z0-9_-]{1,128}$/.test(payload.botId)) {
return {
ok: false,
error: { code: 'bad-request', message: 'bot.access-policy.set requires a valid policy.' },
};
}
let accessPolicy;
try {
accessPolicy = normalizeTelegramAccessPolicy(payload);
} catch {
return {
ok: false,
error: { code: 'bad-request', message: '请输入有效的 Telegram 访问模式和数字 User ID。' },
};
}
try {
const value = await controller.setAccessPolicy(payload.botId, accessPolicy);
return signal?.aborted
? { ok: false, error: { code: 'cancelled', message: 'The request was cancelled.' } }
: { ok: true, value };
} catch {
return signal?.aborted
? { ok: false, error: { code: 'cancelled', message: 'The request was cancelled.' } }
: {
ok: false,
error: { code: 'telegram-operation-failed', message: 'Telegram 操作失败,请稍后重试。' },
};
}
};
}
export function installTelegramRpc(ctx, controller, authority) {
return installTokenBotRpc(ctx, controller, {
channel: 'Telegram',
rpcChannel: TELEGRAM_RPC_CHANNEL,
authority,
});
if (!ctx?.connection?.rpc || typeof ctx.connection.rpc.handle !== 'function') {
throw new TypeError('DSH Host Connection RPC is required');
}
return ctx.connection.rpc.handle(
TELEGRAM_RPC_CHANNEL,
createTelegramRpcHandler(controller),
{ authority: resolveRpcAuthority(authority) },
);
}