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

@ -224,6 +224,20 @@ export class WhatsappController {
});
}
async sendProactiveText(botId, target, text, options = {}) {
const config = this.#configStore.get(botId);
if (!config) throw new Error('Unknown WhatsApp bot');
return this.#withBotTransition(botId, async () => {
const runtime = this.#runtimes.get(botId);
if (!runtime?.status?.ready || typeof runtime.sendProactiveText !== 'function') {
const error = new Error(t('WhatsApp机器人尚未连接'));
error.code = 'bot-not-connected';
throw error;
}
return runtime.sendProactiveText(target, text, options);
});
}
async setAccessPolicy(botId, value) {
if (this.#closed) throw new Error('WhatsApp controller is closed');
const accessPolicy = normalizeWhatsappAccessPolicy(value);

View file

@ -719,6 +719,25 @@ export class WhatsappRuntime {
return { sent: true };
}
async sendProactiveText(target, text, { signal } = {}) {
const jid = typeof target?.route?.jid === 'string' ? target.route.jid.trim() : '';
const validUser = target?.kind === 'user'
&& /^[^@\s]+@(s\.whatsapp\.net|lid)$/.test(jid);
const validGroup = target?.kind === 'group' && /^[^@\s]+@g\.us$/.test(jid);
if (!validUser && !validGroup) {
const error = new TypeError('Invalid WhatsApp proactive delivery target');
error.code = 'invalid-target';
throw error;
}
if (!this.#status.ready || !this.#client) {
const error = new Error(t('WhatsApp机器人尚未连接'));
error.code = 'bot-not-connected';
throw error;
}
signal?.throwIfAborted();
return this.#client.sendText({ jid }, text);
}
async stop() {
const session = this.#session;
const client = this.#client;