@xmanrui/dsh-im 4.3.0 → 4.5.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/README.en.md +2 -2
- package/README.md +2 -2
- package/lib/client.js +976 -634
- package/lib/index.js +241 -238
- package/package.json +1 -1
- package/plugin-src/client/access-policy-settings.js +351 -0
- package/plugin-src/client/channel-card-meta.js +2 -1
- package/plugin-src/client/channels/dingtalk/api.js +5 -0
- package/plugin-src/client/channels/dingtalk/index.js +1 -0
- package/plugin-src/client/channels/feishu/api.js +5 -0
- package/plugin-src/client/channels/feishu/index.js +1 -0
- package/plugin-src/client/channels/qq/api.js +5 -0
- package/plugin-src/client/channels/qq/index.js +1 -0
- package/plugin-src/client/channels/shared/token-api.js +5 -0
- package/plugin-src/client/channels/shared/token-channel.js +1 -0
- package/plugin-src/client/channels/telegram/api.js +2 -17
- package/plugin-src/client/channels/telegram/index.js +0 -112
- package/plugin-src/client/channels/telegram/styles.js +0 -28
- package/plugin-src/client/channels/wecom/api.js +5 -0
- package/plugin-src/client/channels/wecom/index.js +1 -0
- package/plugin-src/client/channels/weixin/api.js +5 -0
- package/plugin-src/client/channels/weixin/index.js +1 -0
- package/plugin-src/client/channels/whatsapp/api.js +4 -10
- package/plugin-src/client/channels/whatsapp/index.js +1 -125
- package/plugin-src/client/channels/whatsapp/styles.js +0 -25
- package/plugin-src/client/context-enhancement.js +19 -5
- package/plugin-src/client/delivery-settings.js +61 -9
- package/plugin-src/client/i18n.js +61 -2
- package/plugin-src/client/index.js +1 -0
- package/plugin-src/client/styles.js +50 -4
- package/plugin-src/host/channels/dingtalk/production.mjs +12 -1
- package/plugin-src/host/channels/dingtalk/rpc.mjs +11 -0
- package/plugin-src/host/channels/feishu/production.mjs +39 -1
- package/plugin-src/host/channels/feishu/rpc.mjs +19 -2
- package/plugin-src/host/channels/qq/production.mjs +12 -1
- package/plugin-src/host/channels/qq/rpc.mjs +11 -0
- package/plugin-src/host/channels/shared/access-policy-production.mjs +137 -0
- package/plugin-src/host/channels/shared/access-policy-rpc.mjs +17 -0
- package/plugin-src/host/channels/shared/production.mjs +15 -1
- package/plugin-src/host/channels/shared/rpc.mjs +9 -0
- package/plugin-src/host/channels/slack/production.mjs +12 -1
- package/plugin-src/host/channels/slack/rpc.mjs +10 -0
- package/plugin-src/host/channels/telegram/rpc.mjs +2 -49
- package/plugin-src/host/channels/wecom/production.mjs +12 -1
- package/plugin-src/host/channels/wecom/rpc.mjs +11 -0
- package/plugin-src/host/channels/weixin/production.mjs +12 -1
- package/plugin-src/host/channels/weixin/rpc.mjs +11 -0
- package/plugin-src/host/channels/whatsapp/production.mjs +16 -2
- package/plugin-src/host/channels/whatsapp/rpc.mjs +10 -15
- package/plugin-src/host/modern-harness-api.mjs +3 -0
- package/src/channels/dingtalk/dingtalk-bridge.mjs +70 -12
- package/src/channels/dingtalk/dingtalk-runtime.mjs +4 -0
- package/src/channels/discord/discord-runtime.mjs +29 -1
- package/src/channels/feishu/bridge.mjs +207 -82
- package/src/channels/feishu/feishu-cards.mjs +2 -2
- package/src/channels/feishu/feishu-channel.mjs +36 -6
- package/src/channels/feishu/feishu-runtime.mjs +4 -0
- package/src/channels/qq/qq-bridge.mjs +67 -20
- package/src/channels/qq/qq-runtime.mjs +20 -2
- package/src/channels/shared/access-policy.mjs +210 -0
- package/src/channels/shared/bot-workspace-store.mjs +181 -33
- package/src/channels/shared/command-permission.mjs +32 -0
- package/src/channels/shared/compact-command.mjs +5 -2
- package/src/channels/shared/context-enhancement.mjs +9 -4
- package/src/channels/shared/harness-client.mjs +6 -0
- package/src/channels/shared/i18n-en/feishu.mjs +3 -3
- package/src/channels/shared/i18n-en/shared-a.mjs +2 -1
- package/src/channels/shared/i18n-en/shared-b.mjs +6 -3
- package/src/channels/shared/i18n-en/shared-c.mjs +2 -0
- package/src/channels/shared/inbound-access.mjs +43 -0
- package/src/channels/shared/session-title.mjs +74 -0
- package/src/channels/shared/text-harness-bridge.mjs +54 -6
- package/src/channels/shared/workspace-command.mjs +26 -5
- package/src/channels/shared/workspace-session.mjs +28 -2
- package/src/channels/slack/slack-runtime.mjs +4 -0
- package/src/channels/telegram/telegram-runtime.mjs +6 -13
- package/src/channels/wecom/wecom-bridge.mjs +57 -6
- package/src/channels/wecom/wecom-runtime.mjs +4 -0
- package/src/channels/weixin/weixin-bridge.mjs +67 -19
- package/src/channels/weixin/weixin-runtime.mjs +4 -0
- package/src/channels/whatsapp/whatsapp-runtime.mjs +42 -20
|
@@ -57,6 +57,10 @@ import {
|
|
|
57
57
|
messageFailureText,
|
|
58
58
|
setLastMessageFailure,
|
|
59
59
|
} from '../shared/message-failure.mjs';
|
|
60
|
+
import {
|
|
61
|
+
COMMAND_PERMISSION_DENIED_MESSAGE,
|
|
62
|
+
evaluateInboundAccess,
|
|
63
|
+
} from '../shared/inbound-access.mjs';
|
|
60
64
|
import { t } from '../shared/i18n.mjs';
|
|
61
65
|
|
|
62
66
|
const INTERACTION_RESOLVED_TEXT = () => t('这个问题已在其他客户端处理,无需再次回答。');
|
|
@@ -71,7 +75,7 @@ const HELP_TEXT = () => [
|
|
|
71
75
|
t('/new 开启一个全新会话'),
|
|
72
76
|
t('/compact 压缩当前会话的较早上下文'),
|
|
73
77
|
t('/history [数量] 查看最近历史消息(默认 3 条,最多 5 条)'),
|
|
74
|
-
t('/workspace
|
|
78
|
+
t('/workspace 工作区序号或绝对路径 切换工作区'),
|
|
75
79
|
t('/workspacelist 列出工作区绝对路径'),
|
|
76
80
|
t('/sessionlist 或 /sessions [工作区序号或绝对路径] 列出会话 ID 和标题'),
|
|
77
81
|
t('/session Session ID 或当前工作区序号 将当前聊天绑定到指定会话'),
|
|
@@ -260,6 +264,7 @@ export class WeixinHarnessBridge {
|
|
|
260
264
|
#harness;
|
|
261
265
|
#state;
|
|
262
266
|
#contextEnhancement;
|
|
267
|
+
#accessPolicy;
|
|
263
268
|
#status;
|
|
264
269
|
#logger;
|
|
265
270
|
#replyTimeoutMs;
|
|
@@ -292,6 +297,7 @@ export class WeixinHarnessBridge {
|
|
|
292
297
|
harness,
|
|
293
298
|
state,
|
|
294
299
|
contextEnhancement,
|
|
300
|
+
accessPolicy,
|
|
295
301
|
status = createWeixinBridgeStatus(),
|
|
296
302
|
logger = console,
|
|
297
303
|
replyTimeoutMs = 600_000,
|
|
@@ -312,6 +318,7 @@ export class WeixinHarnessBridge {
|
|
|
312
318
|
this.#harness = harness;
|
|
313
319
|
this.#state = state;
|
|
314
320
|
this.#contextEnhancement = contextEnhancement;
|
|
321
|
+
this.#accessPolicy = accessPolicy;
|
|
315
322
|
this.#status = status;
|
|
316
323
|
this.#logger = logger;
|
|
317
324
|
this.#replyTimeoutMs = replyTimeoutMs;
|
|
@@ -332,6 +339,22 @@ export class WeixinHarnessBridge {
|
|
|
332
339
|
const sender = nonEmptyString(message?.from_user_id);
|
|
333
340
|
if (!messageId || !sender || this.#state.hasSeen(messageId)
|
|
334
341
|
|| this.#acceptedMessageIds.has(messageId)) return Promise.resolve();
|
|
342
|
+
const commandText = nonEmptyString(extractWeixinText(message)) ?? '';
|
|
343
|
+
const access = this.#accessPolicy
|
|
344
|
+
? evaluateInboundAccess(this.#accessPolicy, {
|
|
345
|
+
conversationType: 'direct',
|
|
346
|
+
senderIds: sender,
|
|
347
|
+
text: commandText,
|
|
348
|
+
hasImages: hasWeixinImageItems(message),
|
|
349
|
+
hasFiles: hasWeixinFileItems(message),
|
|
350
|
+
})
|
|
351
|
+
: sender === this.#ownerUserId
|
|
352
|
+
? { allowed: true, reason: 'legacy-owner' }
|
|
353
|
+
: { allowed: false, reason: 'sender-not-allowed' };
|
|
354
|
+
if (!access.allowed) {
|
|
355
|
+
this.#acceptedMessageIds.set(messageId, null);
|
|
356
|
+
return this.#finishAccessDecision(messageId, sender, message, access);
|
|
357
|
+
}
|
|
335
358
|
this.#acceptedMessageIds.set(messageId, captureContextEnhancement(
|
|
336
359
|
this.#contextEnhancement,
|
|
337
360
|
'direct',
|
|
@@ -343,11 +366,9 @@ export class WeixinHarnessBridge {
|
|
|
343
366
|
const contextToken = nonEmptyString(message?.context_token) ?? undefined;
|
|
344
367
|
const runId = nonEmptyString(message?.run_id) ?? undefined;
|
|
345
368
|
const pending = this.#pendingInteractions.get(key);
|
|
346
|
-
const commandText = nonEmptyString(extractWeixinText(message)) ?? '';
|
|
347
369
|
const batchCommand = isBatchInputCommand(commandText);
|
|
348
370
|
const batchStatus = this.#batchInputs.status(key);
|
|
349
|
-
if (
|
|
350
|
-
&& (batchCommand || batchStatus.phase === 'collecting')) {
|
|
371
|
+
if (batchCommand || batchStatus.phase === 'collecting') {
|
|
351
372
|
const exactBatchStart = /^\/batch$/iu.test(commandText);
|
|
352
373
|
const result = exactBatchStart
|
|
353
374
|
&& batchStatus.phase === 'idle'
|
|
@@ -380,7 +401,7 @@ export class WeixinHarnessBridge {
|
|
|
380
401
|
: (isModelCommand(commandText)
|
|
381
402
|
? runModelCommand
|
|
382
403
|
: (isPresetCommand(commandText) ? runPresetCommand : null));
|
|
383
|
-
if (commandRunner
|
|
404
|
+
if (commandRunner) {
|
|
384
405
|
let task;
|
|
385
406
|
task = this.#processFastCommand(
|
|
386
407
|
message,
|
|
@@ -467,12 +488,10 @@ export class WeixinHarnessBridge {
|
|
|
467
488
|
alreadyRecorded = false,
|
|
468
489
|
batchSubmission = null,
|
|
469
490
|
} = {}) {
|
|
470
|
-
const preparedMessage =
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
)
|
|
475
|
-
: undefined;
|
|
491
|
+
const preparedMessage = prefetchInboundFiles(
|
|
492
|
+
weixinInboundMessage(message, this.#api),
|
|
493
|
+
{ signal: this.#signal },
|
|
494
|
+
);
|
|
476
495
|
const previous = this.#queues.get(key) ?? Promise.resolve();
|
|
477
496
|
const current = previous
|
|
478
497
|
.catch(() => undefined)
|
|
@@ -518,6 +537,36 @@ export class WeixinHarnessBridge {
|
|
|
518
537
|
return task;
|
|
519
538
|
}
|
|
520
539
|
|
|
540
|
+
#finishAccessDecision(messageId, sender, message, access) {
|
|
541
|
+
const contextToken = nonEmptyString(message?.context_token) ?? undefined;
|
|
542
|
+
const runId = nonEmptyString(message?.run_id) ?? undefined;
|
|
543
|
+
let task;
|
|
544
|
+
task = Promise.resolve().then(async () => {
|
|
545
|
+
if (this.#state.hasSeen(messageId)) return;
|
|
546
|
+
await this.#state.markSeen(messageId);
|
|
547
|
+
if (access.reason === 'command-not-allowed') {
|
|
548
|
+
this.#status.messagesReceived += 1;
|
|
549
|
+
this.#status.lastMessageAt = new Date().toISOString();
|
|
550
|
+
await this.#send(sender, t(COMMAND_PERMISSION_DENIED_MESSAGE), contextToken, runId);
|
|
551
|
+
this.#status.messagesReplied += 1;
|
|
552
|
+
this.#status.lastReplyAt = new Date().toISOString();
|
|
553
|
+
} else {
|
|
554
|
+
this.#status.messagesRejected += 1;
|
|
555
|
+
this.#status.lastRejectedAt = new Date().toISOString();
|
|
556
|
+
}
|
|
557
|
+
this.#status.lastError = null;
|
|
558
|
+
}).catch((error) => {
|
|
559
|
+
if (this.#signal?.aborted) return;
|
|
560
|
+
this.#status.lastError = error?.message ?? String(error);
|
|
561
|
+
this.#logger.error?.('[dsh-weixin] failed to apply inbound access policy:', error);
|
|
562
|
+
}).finally(() => {
|
|
563
|
+
this.#acceptedMessageIds.delete(messageId);
|
|
564
|
+
this.#commandTasks.delete(task);
|
|
565
|
+
});
|
|
566
|
+
this.#commandTasks.add(task);
|
|
567
|
+
return task;
|
|
568
|
+
}
|
|
569
|
+
|
|
521
570
|
async waitForIdle() {
|
|
522
571
|
await Promise.allSettled([
|
|
523
572
|
...this.#queues.values(),
|
|
@@ -590,12 +639,6 @@ export class WeixinHarnessBridge {
|
|
|
590
639
|
this.#status.messagesReceived += 1;
|
|
591
640
|
this.#status.lastMessageAt = new Date().toISOString();
|
|
592
641
|
}
|
|
593
|
-
if (sender !== this.#ownerUserId) {
|
|
594
|
-
this.#status.messagesRejected += 1;
|
|
595
|
-
this.#status.lastRejectedAt = new Date().toISOString();
|
|
596
|
-
return;
|
|
597
|
-
}
|
|
598
|
-
|
|
599
642
|
const contextToken = typeof message.context_token === 'string' ? message.context_token : undefined;
|
|
600
643
|
const runId = typeof message.run_id === 'string' ? message.run_id : undefined;
|
|
601
644
|
let batchSettled = batchSubmission === null;
|
|
@@ -662,11 +705,14 @@ export class WeixinHarnessBridge {
|
|
|
662
705
|
? await promptContentForMessage(promptMessage, { signal: this.#signal })
|
|
663
706
|
: undefined;
|
|
664
707
|
const snapshot = this.#acceptedMessageIds.get(messageId);
|
|
708
|
+
let contextEnhanced = false;
|
|
665
709
|
if (snapshot) {
|
|
666
|
-
|
|
710
|
+
const originalContent = content ?? text;
|
|
711
|
+
content = enhanceContextContent(originalContent, snapshot, () => ({
|
|
667
712
|
channel: 'weixin',
|
|
668
713
|
senderId: sender,
|
|
669
714
|
}));
|
|
715
|
+
contextEnhanced = content !== originalContent;
|
|
670
716
|
}
|
|
671
717
|
await this.#state.markSeen(messageId);
|
|
672
718
|
promptRecorded = true;
|
|
@@ -674,7 +720,9 @@ export class WeixinHarnessBridge {
|
|
|
674
720
|
harness: this.#harness,
|
|
675
721
|
state: this.#state,
|
|
676
722
|
key,
|
|
677
|
-
|
|
723
|
+
text,
|
|
724
|
+
content,
|
|
725
|
+
contextEnhanced,
|
|
678
726
|
createOptions: { signal: this.#signal },
|
|
679
727
|
existsOptions: { signal: this.#signal },
|
|
680
728
|
askOptions: {
|
|
@@ -109,6 +109,7 @@ export class WeixinRuntime {
|
|
|
109
109
|
#harness;
|
|
110
110
|
#state;
|
|
111
111
|
#contextEnhancement;
|
|
112
|
+
#accessPolicy;
|
|
112
113
|
#logger;
|
|
113
114
|
#replyTimeoutMs;
|
|
114
115
|
#maxMessageChars;
|
|
@@ -126,6 +127,7 @@ export class WeixinRuntime {
|
|
|
126
127
|
harness,
|
|
127
128
|
state,
|
|
128
129
|
contextEnhancement,
|
|
130
|
+
accessPolicy,
|
|
129
131
|
logger = console,
|
|
130
132
|
replyTimeoutMs = 600_000,
|
|
131
133
|
maxMessageChars = DEFAULT_WEIXIN_MAX_MESSAGE_CHARS,
|
|
@@ -140,6 +142,7 @@ export class WeixinRuntime {
|
|
|
140
142
|
this.#harness = harness;
|
|
141
143
|
this.#state = state;
|
|
142
144
|
this.#contextEnhancement = contextEnhancement;
|
|
145
|
+
this.#accessPolicy = accessPolicy;
|
|
143
146
|
this.#logger = logger;
|
|
144
147
|
this.#replyTimeoutMs = replyTimeoutMs;
|
|
145
148
|
this.#maxMessageChars = maxMessageChars;
|
|
@@ -182,6 +185,7 @@ export class WeixinRuntime {
|
|
|
182
185
|
harness: this.#harness,
|
|
183
186
|
state: this.#state,
|
|
184
187
|
contextEnhancement: this.#contextEnhancement,
|
|
188
|
+
accessPolicy: this.#accessPolicy,
|
|
185
189
|
status: this.#status,
|
|
186
190
|
logger: this.#logger,
|
|
187
191
|
replyTimeoutMs: this.#replyTimeoutMs,
|
|
@@ -3,6 +3,7 @@ import { createHash, randomBytes } from 'node:crypto';
|
|
|
3
3
|
import {
|
|
4
4
|
areJidsSameUser,
|
|
5
5
|
downloadMediaMessage,
|
|
6
|
+
jidDecode,
|
|
6
7
|
normalizeMessageContent,
|
|
7
8
|
} from '@whiskeysockets/baileys';
|
|
8
9
|
|
|
@@ -13,7 +14,6 @@ import { trackOutboundArtifactProviderPromise } from '../shared/semantic/artifac
|
|
|
13
14
|
import { createWhatsappBridgeStatus, WhatsappHarnessBridge } from './whatsapp-bridge.mjs';
|
|
14
15
|
import {
|
|
15
16
|
WHATSAPP_ACCESS_MODES,
|
|
16
|
-
normalizeWhatsappAccessPolicy,
|
|
17
17
|
} from './config-store.mjs';
|
|
18
18
|
import { createWhatsappWebSession } from './whatsapp-web-session.mjs';
|
|
19
19
|
|
|
@@ -37,6 +37,36 @@ const VIEW_ONCE_WRAPPER_KEYS = new Set([
|
|
|
37
37
|
'viewOnceMessageV2',
|
|
38
38
|
'viewOnceMessageV2Extension',
|
|
39
39
|
]);
|
|
40
|
+
const WHATSAPP_ACCESS_POLICY_USER_SERVERS = new Set([
|
|
41
|
+
's.whatsapp.net',
|
|
42
|
+
'c.us',
|
|
43
|
+
'lid',
|
|
44
|
+
'hosted',
|
|
45
|
+
'hosted.lid',
|
|
46
|
+
]);
|
|
47
|
+
|
|
48
|
+
function normalizeWhatsappAccessPolicyId(value) {
|
|
49
|
+
if (typeof value !== 'string') return null;
|
|
50
|
+
const candidate = value.trim();
|
|
51
|
+
if (/^\+?\d+$/.test(candidate)) {
|
|
52
|
+
return `${candidate.replace(/^\+/, '')}@s.whatsapp.net`;
|
|
53
|
+
}
|
|
54
|
+
const decoded = jidDecode(candidate);
|
|
55
|
+
if (!decoded || !/^\d+$/.test(decoded.user)
|
|
56
|
+
|| !WHATSAPP_ACCESS_POLICY_USER_SERVERS.has(decoded.server)) return null;
|
|
57
|
+
return candidate;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export function whatsappAccessPolicyIdsEqual(left, right) {
|
|
61
|
+
const normalizedLeft = normalizeWhatsappAccessPolicyId(left);
|
|
62
|
+
const normalizedRight = normalizeWhatsappAccessPolicyId(right);
|
|
63
|
+
if (!normalizedLeft || !normalizedRight) return false;
|
|
64
|
+
try {
|
|
65
|
+
return areJidsSameUser(normalizedLeft, normalizedRight) === true;
|
|
66
|
+
} catch {
|
|
67
|
+
return false;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
40
70
|
|
|
41
71
|
function hasViewOnceWrapper(content) {
|
|
42
72
|
let current = content;
|
|
@@ -538,12 +568,11 @@ export class WhatsappRuntime {
|
|
|
538
568
|
#harness;
|
|
539
569
|
#state;
|
|
540
570
|
#contextEnhancement;
|
|
571
|
+
#accessPolicy;
|
|
541
572
|
#logger;
|
|
542
573
|
#replyTimeoutMs;
|
|
543
574
|
#connectTimeoutMs;
|
|
544
575
|
#mediaUploadTimeoutMs;
|
|
545
|
-
#accessMode;
|
|
546
|
-
#allowedPrivateNumbers;
|
|
547
576
|
#createSession;
|
|
548
577
|
#status = createWhatsappRuntimeStatus();
|
|
549
578
|
#abortController = null;
|
|
@@ -558,6 +587,7 @@ export class WhatsappRuntime {
|
|
|
558
587
|
harness,
|
|
559
588
|
state,
|
|
560
589
|
contextEnhancement,
|
|
590
|
+
accessPolicy,
|
|
561
591
|
logger = console,
|
|
562
592
|
replyTimeoutMs = 600_000,
|
|
563
593
|
connectTimeoutMs = 30_000,
|
|
@@ -572,6 +602,7 @@ export class WhatsappRuntime {
|
|
|
572
602
|
this.#harness = harness;
|
|
573
603
|
this.#state = state;
|
|
574
604
|
this.#contextEnhancement = contextEnhancement;
|
|
605
|
+
this.#accessPolicy = accessPolicy;
|
|
575
606
|
this.#logger = logger;
|
|
576
607
|
this.#replyTimeoutMs = replyTimeoutMs;
|
|
577
608
|
this.#connectTimeoutMs = connectTimeoutMs;
|
|
@@ -583,21 +614,12 @@ export class WhatsappRuntime {
|
|
|
583
614
|
WHATSAPP_MEDIA_UPLOAD_TIMEOUT_MS,
|
|
584
615
|
);
|
|
585
616
|
this.#createSession = createSession;
|
|
586
|
-
this.setAccessPolicy(config);
|
|
587
617
|
}
|
|
588
618
|
|
|
589
619
|
get status() {
|
|
590
620
|
return structuredClone(this.#status);
|
|
591
621
|
}
|
|
592
622
|
|
|
593
|
-
setAccessPolicy(value) {
|
|
594
|
-
const policy = normalizeWhatsappAccessPolicy(value);
|
|
595
|
-
this.#accessMode = policy.accessMode;
|
|
596
|
-
this.#allowedPrivateNumbers = new Set(policy.allowedNumbers);
|
|
597
|
-
this.#config = { ...this.#config, ...policy };
|
|
598
|
-
return policy;
|
|
599
|
-
}
|
|
600
|
-
|
|
601
623
|
async start() {
|
|
602
624
|
if (this.#status.ready && this.#session) return this.status;
|
|
603
625
|
if (this.#starting) return this.#starting;
|
|
@@ -636,14 +658,6 @@ export class WhatsappRuntime {
|
|
|
636
658
|
});
|
|
637
659
|
if (!message || outboundIds.has(message.providerMessageId) || !this.#bridge) return;
|
|
638
660
|
this.#status.lastCheckedAt = Date.now();
|
|
639
|
-
if (!whatsappInboundAllowed(message, {
|
|
640
|
-
accessMode: this.#accessMode,
|
|
641
|
-
allowedNumbers: this.#allowedPrivateNumbers,
|
|
642
|
-
})) {
|
|
643
|
-
this.#status.messagesRejected += 1;
|
|
644
|
-
this.#status.lastRejectedAt = new Date().toISOString();
|
|
645
|
-
return;
|
|
646
|
-
}
|
|
647
661
|
await this.#bridge.accept(message);
|
|
648
662
|
},
|
|
649
663
|
onDisconnect: ({ error }) => {
|
|
@@ -678,6 +692,14 @@ export class WhatsappRuntime {
|
|
|
678
692
|
harness: this.#harness,
|
|
679
693
|
state: this.#state,
|
|
680
694
|
contextEnhancement: this.#contextEnhancement,
|
|
695
|
+
accessPolicy: this.#accessPolicy ? {
|
|
696
|
+
botId: this.#accessPolicy.botId,
|
|
697
|
+
getSettings: (...args) => this.#accessPolicy.getSettings(...args),
|
|
698
|
+
...(typeof this.#accessPolicy.isPrivileged === 'function' ? {
|
|
699
|
+
isPrivileged: (...args) => this.#accessPolicy.isPrivileged(...args),
|
|
700
|
+
} : {}),
|
|
701
|
+
equals: whatsappAccessPolicyIdsEqual,
|
|
702
|
+
} : undefined,
|
|
681
703
|
status: this.#status,
|
|
682
704
|
logger: this.#logger,
|
|
683
705
|
replyTimeoutMs: this.#replyTimeoutMs,
|