@soimy/dingtalk 3.1.4 → 3.3.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/LICENSE +21 -0
- package/README.md +808 -40
- package/index.ts +62 -0
- package/package.json +4 -2
- package/src/access-control.ts +18 -0
- package/src/ack-reaction-classifier.ts +62 -0
- package/src/ack-reaction-service.ts +135 -0
- package/src/attachment-text-extractor.ts +147 -0
- package/src/card-callback-service.ts +119 -0
- package/src/card-draft-controller.ts +114 -0
- package/src/card-service.ts +794 -62
- package/src/channel.ts +675 -179
- package/src/config-schema.ts +49 -5
- package/src/config.ts +136 -4
- package/src/connection-manager.ts +356 -36
- package/src/dedup.ts +1 -0
- package/src/docs-service.ts +198 -0
- package/src/draft-stream-loop.ts +119 -0
- package/src/feedback-learning-service.ts +643 -0
- package/src/feedback-learning-store.ts +543 -0
- package/src/group-members-store.ts +48 -14
- package/src/inbound-handler.ts +1191 -206
- package/src/learning-command-service.ts +339 -0
- package/src/media-utils.ts +566 -8
- package/src/message-utils.ts +301 -39
- package/src/onboarding.ts +85 -3
- package/src/peer-id-registry.ts +102 -0
- package/src/persistence-store.ts +131 -0
- package/src/quote-journal.ts +242 -0
- package/src/quoted-file-service.ts +385 -0
- package/src/quoted-msg-cache.ts +226 -0
- package/src/send-service.ts +239 -59
- package/src/session-command-service.ts +147 -0
- package/src/session-lock.ts +34 -0
- package/src/session-peer-store.ts +77 -0
- package/src/session-routing.ts +33 -0
- package/src/types.ts +165 -22
- package/src/utils.ts +231 -12
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import type { DingTalkConfig } from "./types";
|
|
2
|
+
|
|
3
|
+
export interface ResolveDingTalkSessionPeerParams {
|
|
4
|
+
isDirect: boolean;
|
|
5
|
+
senderId: string;
|
|
6
|
+
conversationId: string;
|
|
7
|
+
peerIdOverride?: string;
|
|
8
|
+
config: DingTalkConfig;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export interface ResolvedDingTalkSessionPeer {
|
|
12
|
+
kind: "direct" | "group";
|
|
13
|
+
peerId: string;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
// Keep DingTalk aligned with Feishu's explicit peerId -> sessionKey model:
|
|
17
|
+
// resolve a stable peer identity first, then let OpenClaw build the final session key.
|
|
18
|
+
export function resolveDingTalkSessionPeer(
|
|
19
|
+
params: ResolveDingTalkSessionPeerParams,
|
|
20
|
+
): ResolvedDingTalkSessionPeer {
|
|
21
|
+
const normalizedPeerIdOverride = params.peerIdOverride?.trim();
|
|
22
|
+
if (params.isDirect) {
|
|
23
|
+
return {
|
|
24
|
+
kind: "direct",
|
|
25
|
+
peerId: normalizedPeerIdOverride || params.senderId,
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
return {
|
|
30
|
+
kind: "group",
|
|
31
|
+
peerId: normalizedPeerIdOverride || params.conversationId,
|
|
32
|
+
};
|
|
33
|
+
}
|
package/src/types.ts
CHANGED
|
@@ -17,6 +17,7 @@ import type {
|
|
|
17
17
|
ChannelGatewayContext as SDKChannelGatewayContext,
|
|
18
18
|
ChannelPlugin as SDKChannelPlugin,
|
|
19
19
|
} from "openclaw/plugin-sdk";
|
|
20
|
+
import { mergeAccountWithDefaults } from "./config";
|
|
20
21
|
|
|
21
22
|
export interface DingtalkPluginModule {
|
|
22
23
|
id: string;
|
|
@@ -40,7 +41,9 @@ export interface DingTalkConfig extends OpenClawConfig {
|
|
|
40
41
|
dmPolicy?: "open" | "pairing" | "allowlist";
|
|
41
42
|
groupPolicy?: "open" | "allowlist";
|
|
42
43
|
allowFrom?: string[];
|
|
43
|
-
|
|
44
|
+
mediaUrlAllowlist?: string[];
|
|
45
|
+
journalTTLDays?: number;
|
|
46
|
+
ackReaction?: string;
|
|
44
47
|
debug?: boolean;
|
|
45
48
|
messageType?: "markdown" | "card";
|
|
46
49
|
cardTemplateId?: string;
|
|
@@ -54,10 +57,36 @@ export interface DingTalkConfig extends OpenClawConfig {
|
|
|
54
57
|
reconnectJitter?: number;
|
|
55
58
|
/** Maximum number of runtime reconnect cycles before giving up (default: 10) */
|
|
56
59
|
maxReconnectCycles?: number;
|
|
60
|
+
/** Maximum time (ms) for a single reconnect cycle before giving up and starting a new cycle (default: 50000) */
|
|
61
|
+
reconnectDeadlineMs?: number;
|
|
62
|
+
/** Whether to use ConnectionManager; when false, use DWClient native keepAlive+autoReconnect */
|
|
63
|
+
useConnectionManager?: boolean;
|
|
64
|
+
/** Maximum inbound media file size in MB (overrides runtime default when set) */
|
|
65
|
+
mediaMaxMb?: number;
|
|
66
|
+
/** Whether to enable underlying stream keepAlive heartbeat; defaults to !useConnectionManager when omitted */
|
|
67
|
+
keepAlive?: boolean;
|
|
68
|
+
/** Bypass system/global HTTP(S) proxy for DingTalk outbound send/card/upload APIs */
|
|
69
|
+
bypassProxyForSend?: boolean;
|
|
57
70
|
proactivePermissionHint?: {
|
|
58
71
|
enabled?: boolean;
|
|
59
72
|
cooldownHours?: number;
|
|
60
73
|
};
|
|
74
|
+
/** Enable real-time card streaming (default false, true = 300ms throttled per-token updates) */
|
|
75
|
+
cardRealTimeStream?: boolean;
|
|
76
|
+
/** AICard degrade duration in milliseconds after trigger errors (default 30m) */
|
|
77
|
+
aicardDegradeMs?: number;
|
|
78
|
+
/** Enable local learning loop (events/reflections/session notes/global rules) */
|
|
79
|
+
learningEnabled?: boolean;
|
|
80
|
+
/** Auto-apply generated reflections into session notes/global rules (default false) */
|
|
81
|
+
learningAutoApply?: boolean;
|
|
82
|
+
/** Session learning note TTL in milliseconds (default 6h) */
|
|
83
|
+
learningNoteTtlMs?: number;
|
|
84
|
+
/** @deprecated Use learningEnabled */
|
|
85
|
+
feedbackLearningEnabled?: boolean;
|
|
86
|
+
/** @deprecated Use learningAutoApply */
|
|
87
|
+
feedbackLearningAutoApply?: boolean;
|
|
88
|
+
/** @deprecated Use learningNoteTtlMs */
|
|
89
|
+
feedbackLearningNoteTtlMs?: number;
|
|
61
90
|
}
|
|
62
91
|
|
|
63
92
|
/**
|
|
@@ -74,7 +103,9 @@ export interface DingTalkChannelConfig {
|
|
|
74
103
|
dmPolicy?: "open" | "pairing" | "allowlist";
|
|
75
104
|
groupPolicy?: "open" | "allowlist";
|
|
76
105
|
allowFrom?: string[];
|
|
77
|
-
|
|
106
|
+
mediaUrlAllowlist?: string[];
|
|
107
|
+
journalTTLDays?: number;
|
|
108
|
+
ackReaction?: string;
|
|
78
109
|
debug?: boolean;
|
|
79
110
|
messageType?: "markdown" | "card";
|
|
80
111
|
cardTemplateId?: string;
|
|
@@ -87,10 +118,36 @@ export interface DingTalkChannelConfig {
|
|
|
87
118
|
reconnectJitter?: number;
|
|
88
119
|
/** Maximum number of runtime reconnect cycles before giving up (default: 10) */
|
|
89
120
|
maxReconnectCycles?: number;
|
|
121
|
+
/** Maximum time (ms) for a single reconnect cycle before giving up and starting a new cycle (default: 50000) */
|
|
122
|
+
reconnectDeadlineMs?: number;
|
|
123
|
+
/** Whether to use ConnectionManager; when false, use DWClient native keepAlive+autoReconnect */
|
|
124
|
+
useConnectionManager?: boolean;
|
|
125
|
+
/** Maximum inbound media file size in MB (overrides runtime default when set) */
|
|
126
|
+
mediaMaxMb?: number;
|
|
127
|
+
/** Whether to enable underlying stream keepAlive heartbeat; defaults to !useConnectionManager when omitted */
|
|
128
|
+
keepAlive?: boolean;
|
|
129
|
+
/** Bypass system/global HTTP(S) proxy for DingTalk outbound send/card/upload APIs */
|
|
130
|
+
bypassProxyForSend?: boolean;
|
|
90
131
|
proactivePermissionHint?: {
|
|
91
132
|
enabled?: boolean;
|
|
92
133
|
cooldownHours?: number;
|
|
93
134
|
};
|
|
135
|
+
/** Enable real-time card streaming (default false, true = 300ms throttled per-token updates) */
|
|
136
|
+
cardRealTimeStream?: boolean;
|
|
137
|
+
/** AICard degrade duration in milliseconds after trigger errors (default 30m) */
|
|
138
|
+
aicardDegradeMs?: number;
|
|
139
|
+
/** Enable local learning loop (events/reflections/session notes/global rules) */
|
|
140
|
+
learningEnabled?: boolean;
|
|
141
|
+
/** Auto-apply generated reflections into session notes/global rules (default false) */
|
|
142
|
+
learningAutoApply?: boolean;
|
|
143
|
+
/** Session learning note TTL in milliseconds (default 6h) */
|
|
144
|
+
learningNoteTtlMs?: number;
|
|
145
|
+
/** @deprecated Use learningEnabled */
|
|
146
|
+
feedbackLearningEnabled?: boolean;
|
|
147
|
+
/** @deprecated Use learningAutoApply */
|
|
148
|
+
feedbackLearningAutoApply?: boolean;
|
|
149
|
+
/** @deprecated Use learningNoteTtlMs */
|
|
150
|
+
feedbackLearningNoteTtlMs?: number;
|
|
94
151
|
}
|
|
95
152
|
|
|
96
153
|
/**
|
|
@@ -135,6 +192,14 @@ export interface MediaFile {
|
|
|
135
192
|
mimeType: string;
|
|
136
193
|
}
|
|
137
194
|
|
|
195
|
+
export interface DocInfo {
|
|
196
|
+
docId: string;
|
|
197
|
+
title: string;
|
|
198
|
+
docType: string;
|
|
199
|
+
creatorId?: string;
|
|
200
|
+
updatedAt?: number | string;
|
|
201
|
+
}
|
|
202
|
+
|
|
138
203
|
/**
|
|
139
204
|
* DingTalk incoming message (Stream mode)
|
|
140
205
|
*/
|
|
@@ -146,15 +211,22 @@ export interface DingTalkInboundMessage {
|
|
|
146
211
|
content: string;
|
|
147
212
|
isReplyMsg?: boolean; // 是否是回复消息
|
|
148
213
|
repliedMsg?: {
|
|
149
|
-
|
|
214
|
+
msgType?: string;
|
|
215
|
+
msgId?: string;
|
|
216
|
+
senderId?: string;
|
|
217
|
+
createdAt?: number;
|
|
150
218
|
content?: {
|
|
151
219
|
text?: string;
|
|
220
|
+
downloadCode?: string;
|
|
221
|
+
biz_custom_action_url?: string;
|
|
152
222
|
richText?: Array<{
|
|
153
223
|
msgType?: string;
|
|
154
224
|
type?: string;
|
|
155
225
|
content?: string;
|
|
226
|
+
text?: string;
|
|
156
227
|
code?: string;
|
|
157
228
|
atName?: string;
|
|
229
|
+
downloadCode?: string;
|
|
158
230
|
}>;
|
|
159
231
|
};
|
|
160
232
|
};
|
|
@@ -163,13 +235,16 @@ export interface DingTalkInboundMessage {
|
|
|
163
235
|
downloadCode?: string;
|
|
164
236
|
fileName?: string;
|
|
165
237
|
recognition?: string;
|
|
238
|
+
spaceId?: string;
|
|
239
|
+
fileId?: string;
|
|
240
|
+
biz_custom_action_url?: string;
|
|
166
241
|
richText?: Array<{
|
|
167
242
|
type: string;
|
|
168
243
|
text?: string;
|
|
169
244
|
atName?: string;
|
|
170
|
-
downloadCode?: string;
|
|
245
|
+
downloadCode?: string;
|
|
171
246
|
}>;
|
|
172
|
-
quoteContent?: string;
|
|
247
|
+
quoteContent?: string;
|
|
173
248
|
};
|
|
174
249
|
// Legacy 引用格式
|
|
175
250
|
quoteMessage?: {
|
|
@@ -181,6 +256,7 @@ export interface DingTalkInboundMessage {
|
|
|
181
256
|
};
|
|
182
257
|
// 富媒体引用,仅有消息ID的情况(包括手机端和PC端)
|
|
183
258
|
originalMsgId?: string;
|
|
259
|
+
originalProcessQueryKey?: string;
|
|
184
260
|
conversationType: string;
|
|
185
261
|
conversationId: string;
|
|
186
262
|
conversationTitle?: string;
|
|
@@ -191,14 +267,39 @@ export interface DingTalkInboundMessage {
|
|
|
191
267
|
sessionWebhook: string;
|
|
192
268
|
}
|
|
193
269
|
|
|
270
|
+
/**
|
|
271
|
+
* Quoted/reply message metadata extracted from repliedMsg.
|
|
272
|
+
* Populated when isReplyMsg is true; downstream handlers use these fields
|
|
273
|
+
* to download quoted media or look up cached card content.
|
|
274
|
+
*/
|
|
275
|
+
export interface QuotedInfo {
|
|
276
|
+
prefix: string;
|
|
277
|
+
mediaDownloadCode?: string;
|
|
278
|
+
mediaType?: string;
|
|
279
|
+
isQuotedFile?: boolean;
|
|
280
|
+
isQuotedCard?: boolean;
|
|
281
|
+
isQuotedDocCard?: boolean;
|
|
282
|
+
docSpaceId?: string;
|
|
283
|
+
docFileId?: string;
|
|
284
|
+
cardCreatedAt?: number;
|
|
285
|
+
processQueryKey?: string;
|
|
286
|
+
fileCreatedAt?: number;
|
|
287
|
+
msgId?: string;
|
|
288
|
+
}
|
|
289
|
+
|
|
194
290
|
/**
|
|
195
291
|
* Extracted message content for unified processing
|
|
196
292
|
*/
|
|
197
293
|
export interface MessageContent {
|
|
198
294
|
text: string;
|
|
199
295
|
mediaPath?: string;
|
|
296
|
+
mediaPaths?: string[];
|
|
200
297
|
mediaType?: string;
|
|
298
|
+
mediaTypes?: string[];
|
|
201
299
|
messageType: string;
|
|
300
|
+
docSpaceId?: string;
|
|
301
|
+
docFileId?: string;
|
|
302
|
+
quoted?: QuotedInfo;
|
|
202
303
|
}
|
|
203
304
|
|
|
204
305
|
/**
|
|
@@ -208,12 +309,21 @@ export interface SendMessageOptions {
|
|
|
208
309
|
title?: string;
|
|
209
310
|
useMarkdown?: boolean;
|
|
210
311
|
atUserId?: string | null;
|
|
211
|
-
log?:
|
|
312
|
+
log?: Logger;
|
|
313
|
+
conversationId?: string;
|
|
212
314
|
mediaPath?: string;
|
|
213
315
|
filePath?: string;
|
|
214
316
|
mediaUrl?: string;
|
|
215
317
|
mediaType?: "image" | "voice" | "video" | "file";
|
|
216
318
|
accountId?: string;
|
|
319
|
+
storePath?: string;
|
|
320
|
+
cardUpdateMode?: "append";
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
export interface DingTalkTrackingMetadata {
|
|
324
|
+
processQueryKey?: string;
|
|
325
|
+
outTrackId?: string;
|
|
326
|
+
cardInstanceId?: string;
|
|
217
327
|
}
|
|
218
328
|
|
|
219
329
|
/**
|
|
@@ -242,7 +352,7 @@ export interface HandleDingTalkMessageParams {
|
|
|
242
352
|
accountId: string;
|
|
243
353
|
data: DingTalkInboundMessage;
|
|
244
354
|
sessionWebhook: string;
|
|
245
|
-
log?:
|
|
355
|
+
log?: Logger;
|
|
246
356
|
dingtalkConfig: DingTalkConfig;
|
|
247
357
|
}
|
|
248
358
|
|
|
@@ -283,7 +393,7 @@ export interface ResolvedAccount {
|
|
|
283
393
|
export interface AxiosRequestConfig {
|
|
284
394
|
url?: string;
|
|
285
395
|
method?: string;
|
|
286
|
-
data?:
|
|
396
|
+
data?: unknown;
|
|
287
397
|
headers?: Record<string, string>;
|
|
288
398
|
responseType?: "arraybuffer" | "json" | "text";
|
|
289
399
|
}
|
|
@@ -291,7 +401,7 @@ export interface AxiosRequestConfig {
|
|
|
291
401
|
/**
|
|
292
402
|
* HTTP response from axios
|
|
293
403
|
*/
|
|
294
|
-
export interface AxiosResponse<T =
|
|
404
|
+
export interface AxiosResponse<T = unknown> {
|
|
295
405
|
data: T;
|
|
296
406
|
status: number;
|
|
297
407
|
statusText: string;
|
|
@@ -313,15 +423,15 @@ export interface StreamCallbackResponse {
|
|
|
313
423
|
*/
|
|
314
424
|
export interface ReplyDispatchContext {
|
|
315
425
|
responsePrefix?: string;
|
|
316
|
-
deliver: (payload:
|
|
426
|
+
deliver: (payload: unknown) => Promise<{ ok: boolean; error?: string }>;
|
|
317
427
|
}
|
|
318
428
|
|
|
319
429
|
/**
|
|
320
430
|
* Reply dispatcher result
|
|
321
431
|
*/
|
|
322
432
|
export interface ReplyDispatcherResult {
|
|
323
|
-
dispatcher:
|
|
324
|
-
replyOptions:
|
|
433
|
+
dispatcher: unknown;
|
|
434
|
+
replyOptions: unknown;
|
|
325
435
|
markDispatchIdle: () => void;
|
|
326
436
|
}
|
|
327
437
|
|
|
@@ -331,7 +441,7 @@ export interface ReplyDispatcherResult {
|
|
|
331
441
|
export interface RetryOptions {
|
|
332
442
|
maxRetries?: number;
|
|
333
443
|
baseDelayMs?: number;
|
|
334
|
-
log?:
|
|
444
|
+
log?: Logger;
|
|
335
445
|
}
|
|
336
446
|
|
|
337
447
|
/**
|
|
@@ -385,7 +495,7 @@ export interface TargetResolutionResult {
|
|
|
385
495
|
*/
|
|
386
496
|
export interface ResolveTargetParams {
|
|
387
497
|
to?: string | null;
|
|
388
|
-
[key: string]:
|
|
498
|
+
[key: string]: unknown;
|
|
389
499
|
}
|
|
390
500
|
|
|
391
501
|
/**
|
|
@@ -396,7 +506,7 @@ export interface SendTextParams {
|
|
|
396
506
|
to: string;
|
|
397
507
|
text: string;
|
|
398
508
|
accountId?: string;
|
|
399
|
-
[key: string]:
|
|
509
|
+
[key: string]: unknown;
|
|
400
510
|
}
|
|
401
511
|
|
|
402
512
|
/**
|
|
@@ -407,7 +517,7 @@ export interface SendMediaParams {
|
|
|
407
517
|
to: string;
|
|
408
518
|
mediaPath: string;
|
|
409
519
|
accountId?: string;
|
|
410
|
-
[key: string]:
|
|
520
|
+
[key: string]: unknown;
|
|
411
521
|
}
|
|
412
522
|
|
|
413
523
|
/**
|
|
@@ -416,8 +526,8 @@ export interface SendMediaParams {
|
|
|
416
526
|
export interface DingTalkOutboundHandler {
|
|
417
527
|
deliveryMode: "direct" | "queued" | "batch";
|
|
418
528
|
resolveTarget: (params: ResolveTargetParams) => TargetResolutionResult;
|
|
419
|
-
sendText: (params: SendTextParams) => Promise<{ ok: boolean; data?:
|
|
420
|
-
sendMedia?: (params: SendMediaParams) => Promise<{ ok: boolean; data?:
|
|
529
|
+
sendText: (params: SendTextParams) => Promise<{ ok: boolean; data?: unknown; error?: unknown }>;
|
|
530
|
+
sendMedia?: (params: SendMediaParams) => Promise<{ ok: boolean; data?: unknown; error?: unknown }>;
|
|
421
531
|
}
|
|
422
532
|
|
|
423
533
|
/**
|
|
@@ -440,12 +550,17 @@ export type AICardState = (typeof AICardStatus)[keyof typeof AICardStatus];
|
|
|
440
550
|
*/
|
|
441
551
|
export interface AICardInstance {
|
|
442
552
|
cardInstanceId: string;
|
|
553
|
+
processQueryKey?: string;
|
|
443
554
|
accessToken: string;
|
|
444
555
|
conversationId: string;
|
|
556
|
+
accountId?: string;
|
|
557
|
+
storePath?: string;
|
|
445
558
|
createdAt: number;
|
|
446
559
|
lastUpdated: number;
|
|
447
560
|
state: AICardState; // Current card state: PROCESSING, INPUTING, FINISHED, FAILED
|
|
448
561
|
config?: DingTalkConfig; // Store config reference for token refresh
|
|
562
|
+
lastStreamedContent?: string;
|
|
563
|
+
outTrackId?: string;
|
|
449
564
|
}
|
|
450
565
|
|
|
451
566
|
/**
|
|
@@ -472,6 +587,14 @@ export enum ConnectionState {
|
|
|
472
587
|
FAILED = "FAILED",
|
|
473
588
|
}
|
|
474
589
|
|
|
590
|
+
/**
|
|
591
|
+
* Factory function that creates a fresh DWClient with callback listeners
|
|
592
|
+
* already registered. Used by ConnectionManager to create a new client
|
|
593
|
+
* on reconnection so the new WebSocket can start receiving messages
|
|
594
|
+
* while the old zombie socket is still being cleaned up.
|
|
595
|
+
*/
|
|
596
|
+
export type StreamClientFactory = () => import("dingtalk-stream").DWClient;
|
|
597
|
+
|
|
475
598
|
/**
|
|
476
599
|
* Connection manager configuration
|
|
477
600
|
*/
|
|
@@ -482,6 +605,8 @@ export interface ConnectionManagerConfig {
|
|
|
482
605
|
jitter: number;
|
|
483
606
|
/** Maximum number of runtime reconnect cycles before giving up (default: 10) */
|
|
484
607
|
maxReconnectCycles?: number;
|
|
608
|
+
/** Maximum time (ms) for a single reconnect cycle before giving up and starting a new cycle (default: 50000) */
|
|
609
|
+
reconnectDeadlineMs?: number;
|
|
485
610
|
/** Callback invoked when connection state changes */
|
|
486
611
|
onStateChange?: (state: ConnectionState, error?: string) => void;
|
|
487
612
|
}
|
|
@@ -555,7 +680,8 @@ export function resolveDingTalkAccount(
|
|
|
555
680
|
dmPolicy: dingtalk?.dmPolicy,
|
|
556
681
|
groupPolicy: dingtalk?.groupPolicy,
|
|
557
682
|
allowFrom: dingtalk?.allowFrom,
|
|
558
|
-
|
|
683
|
+
journalTTLDays: dingtalk?.journalTTLDays,
|
|
684
|
+
ackReaction: dingtalk?.ackReaction,
|
|
559
685
|
debug: dingtalk?.debug,
|
|
560
686
|
messageType: dingtalk?.messageType,
|
|
561
687
|
cardTemplateId: dingtalk?.cardTemplateId,
|
|
@@ -567,7 +693,20 @@ export function resolveDingTalkAccount(
|
|
|
567
693
|
maxReconnectDelay: dingtalk?.maxReconnectDelay,
|
|
568
694
|
reconnectJitter: dingtalk?.reconnectJitter,
|
|
569
695
|
maxReconnectCycles: dingtalk?.maxReconnectCycles,
|
|
696
|
+
reconnectDeadlineMs: dingtalk?.reconnectDeadlineMs,
|
|
697
|
+
useConnectionManager: dingtalk?.useConnectionManager,
|
|
698
|
+
mediaMaxMb: dingtalk?.mediaMaxMb,
|
|
699
|
+
keepAlive: dingtalk?.keepAlive,
|
|
700
|
+
bypassProxyForSend: dingtalk?.bypassProxyForSend,
|
|
570
701
|
proactivePermissionHint: dingtalk?.proactivePermissionHint,
|
|
702
|
+
cardRealTimeStream: dingtalk?.cardRealTimeStream,
|
|
703
|
+
aicardDegradeMs: dingtalk?.aicardDegradeMs,
|
|
704
|
+
learningEnabled: dingtalk?.learningEnabled ?? dingtalk?.feedbackLearningEnabled,
|
|
705
|
+
learningAutoApply: dingtalk?.learningAutoApply ?? dingtalk?.feedbackLearningAutoApply,
|
|
706
|
+
learningNoteTtlMs: dingtalk?.learningNoteTtlMs ?? dingtalk?.feedbackLearningNoteTtlMs,
|
|
707
|
+
feedbackLearningEnabled: dingtalk?.feedbackLearningEnabled,
|
|
708
|
+
feedbackLearningAutoApply: dingtalk?.feedbackLearningAutoApply,
|
|
709
|
+
feedbackLearningNoteTtlMs: dingtalk?.feedbackLearningNoteTtlMs,
|
|
571
710
|
};
|
|
572
711
|
return {
|
|
573
712
|
...config,
|
|
@@ -576,13 +715,17 @@ export function resolveDingTalkAccount(
|
|
|
576
715
|
};
|
|
577
716
|
}
|
|
578
717
|
|
|
579
|
-
// If named account,
|
|
718
|
+
// If named account, merge channel-level defaults with account-level overrides
|
|
580
719
|
const accountConfig = dingtalk?.accounts?.[id];
|
|
581
720
|
if (accountConfig) {
|
|
721
|
+
const merged = mergeAccountWithDefaults(
|
|
722
|
+
dingtalk as DingTalkConfig,
|
|
723
|
+
accountConfig,
|
|
724
|
+
);
|
|
582
725
|
return {
|
|
583
|
-
...
|
|
726
|
+
...merged,
|
|
584
727
|
accountId: id,
|
|
585
|
-
configured: Boolean(
|
|
728
|
+
configured: Boolean(merged.clientId && merged.clientSecret),
|
|
586
729
|
};
|
|
587
730
|
}
|
|
588
731
|
|