@xmanrui/dsh-im 4.0.1 → 4.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/PROACTIVE_DELIVERY.en.md +321 -0
- package/PROACTIVE_DELIVERY.md +321 -0
- package/README.en.md +11 -5
- package/README.md +11 -5
- package/lib/client.js +1190 -108
- package/lib/index.js +229 -229
- package/package.json +4 -1
- package/plugin-src/client/channel-card-meta.js +44 -0
- package/plugin-src/client/channels/dingtalk/index.js +16 -8
- package/plugin-src/client/channels/feishu/index.js +17 -9
- package/plugin-src/client/channels/qq/index.js +16 -8
- package/plugin-src/client/channels/shared/token-channel.js +16 -8
- package/plugin-src/client/channels/wecom/index.js +16 -8
- package/plugin-src/client/channels/weixin/index.js +16 -8
- package/plugin-src/client/channels/whatsapp/index.js +16 -8
- package/plugin-src/client/delivery-settings.js +749 -0
- package/plugin-src/client/i18n.js +82 -0
- package/plugin-src/client/index.js +46 -20
- package/plugin-src/client/styles.js +72 -0
- package/plugin-src/host/channels/dingtalk/index.mjs +3 -0
- package/plugin-src/host/channels/dingtalk/production.mjs +4 -0
- package/plugin-src/host/channels/discord/index.mjs +6 -1
- package/plugin-src/host/channels/feishu/index.mjs +3 -0
- package/plugin-src/host/channels/feishu/production.mjs +4 -0
- package/plugin-src/host/channels/qq/index.mjs +6 -1
- package/plugin-src/host/channels/qq/production.mjs +2 -0
- package/plugin-src/host/channels/shared/production.mjs +7 -0
- package/plugin-src/host/channels/slack/index.mjs +6 -1
- package/plugin-src/host/channels/slack/production.mjs +4 -0
- package/plugin-src/host/channels/telegram/index.mjs +6 -1
- package/plugin-src/host/channels/wecom/index.mjs +6 -1
- package/plugin-src/host/channels/wecom/production.mjs +4 -0
- package/plugin-src/host/channels/weixin/index.mjs +3 -0
- package/plugin-src/host/channels/weixin/production.mjs +4 -0
- package/plugin-src/host/channels/whatsapp/index.mjs +6 -1
- package/plugin-src/host/channels/whatsapp/production.mjs +4 -0
- package/plugin-src/host/delivery-adapter.mjs +179 -0
- package/plugin-src/host/delivery-http.mjs +132 -0
- package/plugin-src/host/delivery-rpc.mjs +158 -0
- package/plugin-src/host/delivery-service.mjs +224 -0
- package/plugin-src/host/delivery-suggestions.mjs +135 -0
- package/plugin-src/host/index.mjs +32 -5
- package/scripts/verify-package.mjs +3 -0
- package/src/channels/dingtalk/dingtalk-api.mjs +33 -0
- package/src/channels/dingtalk/dingtalk-bridge.mjs +2 -2
- package/src/channels/dingtalk/dingtalk-controller.mjs +14 -0
- package/src/channels/dingtalk/dingtalk-runtime.mjs +39 -0
- package/src/channels/discord/discord-runtime.mjs +16 -0
- package/src/channels/feishu/bridge.mjs +4 -4
- package/src/channels/feishu/feishu-cards.mjs +4 -4
- package/src/channels/feishu/feishu-runtime.mjs +35 -0
- package/src/channels/feishu/multi-bot-controller.mjs +15 -0
- package/src/channels/qq/qq-bridge.mjs +2 -2
- package/src/channels/qq/qq-controller.mjs +14 -0
- package/src/channels/qq/qq-runtime.mjs +23 -0
- package/src/channels/shared/bot-workspace-store.mjs +192 -6
- package/src/channels/shared/i18n-en/feishu.mjs +6 -2
- package/src/channels/shared/i18n-en/shared-a.mjs +4 -0
- package/src/channels/shared/preset-command.mjs +2 -2
- package/src/channels/shared/text-harness-bridge.mjs +7 -2
- package/src/channels/shared/token-bot-controller.mjs +16 -0
- package/src/channels/shared/workspace-command.mjs +1 -1
- package/src/channels/slack/slack-controller.mjs +14 -0
- package/src/channels/slack/slack-runtime.mjs +24 -0
- package/src/channels/telegram/telegram-runtime.mjs +26 -0
- package/src/channels/wecom/state-store.mjs +4 -0
- package/src/channels/wecom/wecom-bridge.mjs +2 -2
- package/src/channels/wecom/wecom-controller.mjs +14 -0
- package/src/channels/wecom/wecom-runtime.mjs +21 -0
- package/src/channels/weixin/weixin-bridge.mjs +2 -2
- package/src/channels/weixin/weixin-controller.mjs +14 -0
- package/src/channels/weixin/weixin-runtime.mjs +24 -0
- package/src/channels/whatsapp/whatsapp-controller.mjs +14 -0
- package/src/channels/whatsapp/whatsapp-runtime.mjs +19 -0
|
@@ -66,14 +66,14 @@ function helpText() {
|
|
|
66
66
|
t('/history [数量] 查看最近历史消息(默认 3 条,最多 5 条)'),
|
|
67
67
|
t('/workspace 工作区绝对路径 切换工作区'),
|
|
68
68
|
t('/workspacelist 列出工作区绝对路径'),
|
|
69
|
-
t('/sessionlist [工作区序号或绝对路径] 列出会话 ID 和标题'),
|
|
69
|
+
t('/sessionlist 或 /sessions [工作区序号或绝对路径] 列出会话 ID 和标题'),
|
|
70
70
|
t('/session Session ID 或当前工作区序号 将当前聊天绑定到指定会话'),
|
|
71
71
|
t('/models 按序号列出所有可用模型'),
|
|
72
72
|
t('/reasoninglist 或 /reasonings 按序号列出当前模型可用推理等级'),
|
|
73
73
|
t('/reasoning [序号、等级ID或 --default] 查看或切换当前推理等级'),
|
|
74
74
|
t('/model [序号或完整模型ID] [推理等级ID] 查看或切换当前会话模型'),
|
|
75
75
|
t('示例:先发 /models,再发 /model 2 [推理等级ID]'),
|
|
76
|
-
t('/presetlist 按序号列出可用 Agent Preset'),
|
|
76
|
+
t('/presetlist 或 /presets 按序号列出可用 Agent Preset'),
|
|
77
77
|
t('/preset [序号或完整ID] 查看或设置当前机器人 Agent Preset'),
|
|
78
78
|
t('纯数字 ID:/preset id:<ID>'),
|
|
79
79
|
t('/preset --default 跟随 Host 默认'),
|
|
@@ -257,6 +257,20 @@ export class WecomController {
|
|
|
257
257
|
});
|
|
258
258
|
}
|
|
259
259
|
|
|
260
|
+
async sendProactiveText(botId, target, text, options = {}) {
|
|
261
|
+
const config = this.#configStore.get(botId);
|
|
262
|
+
if (!config) throw new Error('Unknown Enterprise WeChat bot');
|
|
263
|
+
return this.#withBotTransition(botId, async () => {
|
|
264
|
+
const runtime = this.#runtimes.get(botId);
|
|
265
|
+
if (!runtime?.status?.ready || typeof runtime.sendProactiveText !== 'function') {
|
|
266
|
+
const error = new Error(t('企业微信连接当前离线'));
|
|
267
|
+
error.code = 'bot-not-connected';
|
|
268
|
+
throw error;
|
|
269
|
+
}
|
|
270
|
+
return runtime.sendProactiveText(target, text, options);
|
|
271
|
+
});
|
|
272
|
+
}
|
|
273
|
+
|
|
260
274
|
async deleteBot(botId) {
|
|
261
275
|
const config = this.#configStore.get(botId);
|
|
262
276
|
if (!config) throw new Error('Unknown Enterprise WeChat bot');
|
|
@@ -220,6 +220,27 @@ export class WecomRuntime {
|
|
|
220
220
|
});
|
|
221
221
|
}
|
|
222
222
|
|
|
223
|
+
async sendProactiveText(target, text, { signal } = {}) {
|
|
224
|
+
const chatId = typeof target?.route?.chatId === 'string'
|
|
225
|
+
? target.route.chatId.trim() : '';
|
|
226
|
+
if ((target?.kind !== 'user' && target?.kind !== 'group') || !chatId) {
|
|
227
|
+
const error = new TypeError('Invalid Enterprise WeChat proactive delivery target');
|
|
228
|
+
error.code = 'invalid-target';
|
|
229
|
+
throw error;
|
|
230
|
+
}
|
|
231
|
+
if (!this.#status.ready || !this.#client) {
|
|
232
|
+
const error = new Error('Enterprise WeChat runtime is not connected');
|
|
233
|
+
error.code = 'bot-not-connected';
|
|
234
|
+
throw error;
|
|
235
|
+
}
|
|
236
|
+
signal?.throwIfAborted();
|
|
237
|
+
await this.#client.sendMessage(chatId, {
|
|
238
|
+
msgtype: 'markdown',
|
|
239
|
+
markdown: { content: text },
|
|
240
|
+
});
|
|
241
|
+
return { sent: true };
|
|
242
|
+
}
|
|
243
|
+
|
|
223
244
|
async #stopActive() {
|
|
224
245
|
const client = this.#client;
|
|
225
246
|
const bridge = this.#bridge;
|
|
@@ -73,14 +73,14 @@ const HELP_TEXT = () => [
|
|
|
73
73
|
t('/history [数量] 查看最近历史消息(默认 3 条,最多 5 条)'),
|
|
74
74
|
t('/workspace 工作区绝对路径 切换工作区'),
|
|
75
75
|
t('/workspacelist 列出工作区绝对路径'),
|
|
76
|
-
t('/sessionlist [工作区序号或绝对路径] 列出会话 ID 和标题'),
|
|
76
|
+
t('/sessionlist 或 /sessions [工作区序号或绝对路径] 列出会话 ID 和标题'),
|
|
77
77
|
t('/session Session ID 或当前工作区序号 将当前聊天绑定到指定会话'),
|
|
78
78
|
t('/models 按序号列出所有可用模型'),
|
|
79
79
|
t('/reasoninglist 或 /reasonings 按序号列出当前模型可用推理等级'),
|
|
80
80
|
t('/reasoning [序号、等级ID或 --default] 查看或切换当前推理等级'),
|
|
81
81
|
t('/model [序号或完整模型ID] [推理等级ID] 查看或切换当前会话模型'),
|
|
82
82
|
t('示例:先发 /models,再发 /model 2 [推理等级ID]'),
|
|
83
|
-
t('/presetlist 按序号列出可用 Agent Preset'),
|
|
83
|
+
t('/presetlist 或 /presets 按序号列出可用 Agent Preset'),
|
|
84
84
|
t('/preset [序号或完整ID] 查看或设置当前机器人 Agent Preset'),
|
|
85
85
|
t('纯数字 ID:/preset id:<ID>'),
|
|
86
86
|
t('/preset --default 跟随 Host 默认'),
|
|
@@ -299,6 +299,20 @@ export class WeixinController {
|
|
|
299
299
|
});
|
|
300
300
|
}
|
|
301
301
|
|
|
302
|
+
async sendProactiveText(botId, target, text, options = {}) {
|
|
303
|
+
const config = this.#configStore.get(botId);
|
|
304
|
+
if (!config) throw new Error('Unknown Weixin account');
|
|
305
|
+
return this.#withBotTransition(botId, async () => {
|
|
306
|
+
const runtime = this.#runtimes.get(botId);
|
|
307
|
+
if (!runtime?.status?.ready || typeof runtime.sendProactiveText !== 'function') {
|
|
308
|
+
const error = new Error(t('微信连接当前离线'));
|
|
309
|
+
error.code = 'bot-not-connected';
|
|
310
|
+
throw error;
|
|
311
|
+
}
|
|
312
|
+
return runtime.sendProactiveText(target, text, options);
|
|
313
|
+
});
|
|
314
|
+
}
|
|
315
|
+
|
|
302
316
|
async deleteBot(botId) {
|
|
303
317
|
const config = this.#configStore.get(botId);
|
|
304
318
|
if (!config) throw new Error('Unknown Weixin account');
|
|
@@ -329,4 +329,28 @@ export class WeixinRuntime {
|
|
|
329
329
|
});
|
|
330
330
|
return { sent: true };
|
|
331
331
|
}
|
|
332
|
+
|
|
333
|
+
async sendProactiveText(target, text, { signal } = {}) {
|
|
334
|
+
const toUserId = typeof target?.route?.toUserId === 'string'
|
|
335
|
+
? target.route.toUserId.trim() : '';
|
|
336
|
+
if (target?.kind !== 'user' || !toUserId) {
|
|
337
|
+
const error = new TypeError('Invalid Weixin proactive delivery target');
|
|
338
|
+
error.code = 'invalid-target';
|
|
339
|
+
throw error;
|
|
340
|
+
}
|
|
341
|
+
if (!this.#status.ready || !this.#abortController) {
|
|
342
|
+
const error = new Error('Weixin runtime is not connected');
|
|
343
|
+
error.code = 'bot-not-connected';
|
|
344
|
+
throw error;
|
|
345
|
+
}
|
|
346
|
+
signal?.throwIfAborted();
|
|
347
|
+
await this.#api.sendText({
|
|
348
|
+
baseUrl: this.#config.baseUrl,
|
|
349
|
+
token: this.#token,
|
|
350
|
+
toUserId,
|
|
351
|
+
text,
|
|
352
|
+
signal: signal ?? this.#abortController.signal,
|
|
353
|
+
});
|
|
354
|
+
return { sent: true };
|
|
355
|
+
}
|
|
332
356
|
}
|
|
@@ -224,6 +224,20 @@ export class WhatsappController {
|
|
|
224
224
|
});
|
|
225
225
|
}
|
|
226
226
|
|
|
227
|
+
async sendProactiveText(botId, target, text, options = {}) {
|
|
228
|
+
const config = this.#configStore.get(botId);
|
|
229
|
+
if (!config) throw new Error('Unknown WhatsApp bot');
|
|
230
|
+
return this.#withBotTransition(botId, async () => {
|
|
231
|
+
const runtime = this.#runtimes.get(botId);
|
|
232
|
+
if (!runtime?.status?.ready || typeof runtime.sendProactiveText !== 'function') {
|
|
233
|
+
const error = new Error(t('WhatsApp机器人尚未连接'));
|
|
234
|
+
error.code = 'bot-not-connected';
|
|
235
|
+
throw error;
|
|
236
|
+
}
|
|
237
|
+
return runtime.sendProactiveText(target, text, options);
|
|
238
|
+
});
|
|
239
|
+
}
|
|
240
|
+
|
|
227
241
|
async setAccessPolicy(botId, value) {
|
|
228
242
|
if (this.#closed) throw new Error('WhatsApp controller is closed');
|
|
229
243
|
const accessPolicy = normalizeWhatsappAccessPolicy(value);
|
|
@@ -719,6 +719,25 @@ export class WhatsappRuntime {
|
|
|
719
719
|
return { sent: true };
|
|
720
720
|
}
|
|
721
721
|
|
|
722
|
+
async sendProactiveText(target, text, { signal } = {}) {
|
|
723
|
+
const jid = typeof target?.route?.jid === 'string' ? target.route.jid.trim() : '';
|
|
724
|
+
const validUser = target?.kind === 'user'
|
|
725
|
+
&& /^[^@\s]+@(s\.whatsapp\.net|lid)$/.test(jid);
|
|
726
|
+
const validGroup = target?.kind === 'group' && /^[^@\s]+@g\.us$/.test(jid);
|
|
727
|
+
if (!validUser && !validGroup) {
|
|
728
|
+
const error = new TypeError('Invalid WhatsApp proactive delivery target');
|
|
729
|
+
error.code = 'invalid-target';
|
|
730
|
+
throw error;
|
|
731
|
+
}
|
|
732
|
+
if (!this.#status.ready || !this.#client) {
|
|
733
|
+
const error = new Error(t('WhatsApp机器人尚未连接'));
|
|
734
|
+
error.code = 'bot-not-connected';
|
|
735
|
+
throw error;
|
|
736
|
+
}
|
|
737
|
+
signal?.throwIfAborted();
|
|
738
|
+
return this.#client.sendText({ jid }, text);
|
|
739
|
+
}
|
|
740
|
+
|
|
722
741
|
async stop() {
|
|
723
742
|
const session = this.#session;
|
|
724
743
|
const client = this.#client;
|