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

@ -163,6 +163,34 @@ export class TokenBotController {
return this.status();
}
async updateBotConfig(botId, update) {
if (this.#closed) throw new Error(`${this.#descriptor.label} controller is closed`);
if (typeof update !== 'function') throw new TypeError('Bot config update must be a function');
await this.#withBotTransition(botId, async () => {
if (this.#closed) throw new Error(`${this.#descriptor.label} controller is closed`);
const config = this.#configStore.get(botId);
if (!config) throw new Error(`Unknown ${this.#descriptor.label} bot`);
const token = await this.#resolveToken(config.tokenRef);
if (!token) throw new Error(`${this.#descriptor.label} bot token is missing`);
if (this.#closed) throw new Error(`${this.#descriptor.label} controller is closed`);
const nextConfig = update(config);
const savedConfig = await this.#configStore.save(nextConfig);
try {
await this.#startRuntime(savedConfig, token);
this.#errors.delete(botId);
} catch (error) {
this.#errors.set(botId, safeError(
'connection-failed',
`${this.#descriptor.label}连接仍未就绪,请稍后重试。`,
));
throw error;
} finally {
this.#touch();
}
});
return this.status();
}
async sendConnectionTest(botId) {
const config = this.#configStore.get(botId);
if (!config) throw new Error(`Unknown ${this.#descriptor.label} bot`);

View file

@ -33,16 +33,26 @@ export class TokenBotConfigStore {
#channel;
#botPrefix;
#tokenRefPrefix;
#normalizeBotExtension;
#botIdPattern;
#tokenRefPattern;
#value = EMPTY_DOCUMENT;
#writeQueue = Promise.resolve();
constructor(path, { channel, botPrefix, tokenRefPrefix }) {
constructor(path, {
channel,
botPrefix,
tokenRefPrefix,
normalizeBotExtension = () => ({}),
}) {
if (typeof normalizeBotExtension !== 'function') {
throw new TypeError('normalizeBotExtension must be a function');
}
this.#path = path;
this.#channel = channel;
this.#botPrefix = botPrefix;
this.#tokenRefPrefix = tokenRefPrefix;
this.#normalizeBotExtension = normalizeBotExtension;
this.#botIdPattern = new RegExp(`^${escapePattern(botPrefix)}_[a-f0-9]{24}$`);
this.#tokenRefPattern = new RegExp(`^${escapePattern(tokenRefPrefix)}_[A-F0-9]{24}$`);
}
@ -127,6 +137,8 @@ export class TokenBotConfigStore {
tokenRefPrefix: this.#tokenRefPrefix,
});
if (derived.botId !== botId || derived.tokenRef !== tokenRef) return null;
const extension = this.#normalizeBotExtension(value);
if (!extension || typeof extension !== 'object' || Array.isArray(extension)) return null;
return Object.freeze({
botId,
platformId,
@ -135,6 +147,7 @@ export class TokenBotConfigStore {
username: cleanString(value.username),
createdAt: cleanString(value.createdAt) ?? new Date().toISOString(),
connectedAt: cleanString(value.connectedAt),
...extension,
});
}