feat: add stable proactive delivery

This commit is contained in:
xmanrui 2026-08-30 11:24:53 +08:00
parent 410cb822d7
commit 31792d7bc8
88 changed files with 6427 additions and 488 deletions

View file

@ -563,6 +563,41 @@ export class FeishuRuntime {
});
}
async sendProactiveText(target, text, { signal } = {}) {
if (!this.#status.ready || !this.#client) {
const error = new Error('飞书机器人尚未连接');
error.code = 'bot-not-connected';
throw error;
}
const receiveIdType = target?.kind === 'user' ? 'open_id'
: target?.kind === 'group' ? 'chat_id' : null;
const receiveId = target?.kind === 'user'
? nonEmptyString(target?.route?.openId)
: target?.kind === 'group'
? nonEmptyString(target?.route?.chatId)
: null;
if (!receiveIdType || !receiveId) {
const error = new TypeError('Invalid Feishu proactive delivery target');
error.code = 'invalid-target';
throw error;
}
signal?.throwIfAborted();
const response = await this.#client.im.v1.message.create({
params: { receive_id_type: receiveIdType },
data: {
receive_id: receiveId,
msg_type: 'text',
content: JSON.stringify({ text }),
},
});
if (response?.code && response.code !== 0) {
const error = new Error(`Feishu proactive delivery failed: ${response.msg || response.code}`);
error.code = 'target-rejected';
throw error;
}
return { sent: true };
}
stop(options = {}) {
if (this.#stopping) return this.#stopping;

View file

@ -537,6 +537,21 @@ export class MultiBotDshFeishuController {
});
}
async sendProactiveText(botId, target, text, options = {}) {
this.#assertOpen();
return this.#withBotTransition(botId, async () => {
this.#requireBot(botId);
const runtime = this.#runtimes.get(botId);
if (!isConnected(connectionStatus(runtime))
|| typeof runtime.sendProactiveText !== 'function') {
const error = new Error('飞书机器人尚未连接');
error.code = 'bot-not-connected';
throw error;
}
return runtime.sendProactiveText(target, text, options);
});
}
async disconnectBot(botId) {
this.#assertOpen();
// An operational pause only: credentials/config remain durable, so the