@jeik/dingtalk-connector 0.8.28 → 0.8.30
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/CHANGELOG.md +40 -30
- package/README.en.md +114 -130
- package/README.md +112 -131
- package/dist/{background-work-Cxb4b-91.mjs → background-work-DkaSDqWk.mjs} +12 -1
- package/dist/card-content-cache-C7-XHhHw.mjs +2 -0
- package/dist/{card-content-cache-bDQFz2u8.mjs → card-content-cache-DT_OYThh.mjs} +15 -1
- package/dist/chunk-upload-BKM1y4Ba.mjs +2 -0
- package/dist/{chunk-upload-BE71drPg.mjs → chunk-upload-CIU5G_ay.mjs} +1 -1
- package/dist/{common-BZiVgd3A.mjs → common-BfIYs1yC.mjs} +3 -3
- package/dist/{common-DgL28gCZ.mjs → common-C0Oaf0z-.mjs} +1 -1
- package/dist/{connection-CZ7ZoN5_.mjs → connection-obtrPkj4.mjs} +56 -65
- package/dist/entry-bundled.mjs +1 -1
- package/dist/{gateway-methods-kNX3qvqw.mjs → gateway-methods-BdcpfxEZ.mjs} +1 -1
- package/dist/gateway-methods-DQ6TwOAr.mjs +2 -0
- package/dist/index.mjs +2 -2
- package/dist/{logger-mZ9OSbmD.mjs → logger-CnBTcwyq.mjs} +16 -2
- package/dist/logger-D8H2IcYz.mjs +2 -0
- package/dist/{media-BqpUGCni.mjs → media-DDtX37T2.mjs} +1 -1
- package/dist/{media-DnQB2BrL.mjs → media-g8tJtpfU.mjs} +29 -20
- package/dist/{message-handler-B1usz1wb.mjs → message-handler-BeTQQCUe.mjs} +33 -30
- package/dist/{messaging-DVS3UKOp.mjs → messaging-CK0Wz3Ze.mjs} +18 -20
- package/dist/{runtime-A6G7WAWn.mjs → runtime-CjE4Z9G5.mjs} +6 -5
- package/dist/{utils-Bjh4r_qS.mjs → utils-Bwz2Fls_.mjs} +1 -1
- package/docs/RELEASE_NOTES_V0.8.28.md +4 -4
- package/docs/RELEASE_NOTES_V0.8.29.md +72 -0
- package/openclaw.plugin.json +9 -5
- package/package.json +1 -1
- package/src/config/schema.ts +2 -1
- package/src/core/connection.ts +90 -113
- package/src/core/message-handler.ts +24 -16
- package/src/reply-dispatcher.ts +33 -20
- package/src/services/media.ts +60 -27
- package/src/services/messaging/card-content-cache.ts +11 -6
- package/src/services/messaging.ts +52 -38
- package/src/utils/background-work.ts +3 -1
- package/src/utils/logger.ts +23 -2
- package/dist/card-content-cache-c4Ls96eJ.mjs +0 -2
- package/dist/chunk-upload-PwhogwfE.mjs +0 -2
- package/dist/gateway-methods-BkI1gKaC.mjs +0 -2
- package/dist/logger-BmJkQkm1.mjs +0 -2
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { a as resolveDingtalkAccount, t as listDingtalkAccountIds } from "./accounts-BAzdqkAV.mjs";
|
|
2
2
|
import { t as dingtalkHttp } from "./http-client-DFWZgO1n.mjs";
|
|
3
3
|
import { r as getAccessToken, t as DINGTALK_API } from "./utils-CIfI_3Jh.mjs";
|
|
4
|
-
import { c as prepareMultiBotMentions, d as finishAICard, i as sendProactive, s as buildBotMentionTable } from "./messaging-
|
|
4
|
+
import { c as prepareMultiBotMentions, d as finishAICard, i as sendProactive, s as buildBotMentionTable } from "./messaging-CK0Wz3Ze.mjs";
|
|
5
5
|
import { d as getUnionId, h as recallEmotionReply } from "./utils-legacy-DQ3HeGHh.mjs";
|
|
6
6
|
//#region src/docs.ts
|
|
7
7
|
var DingtalkDocsClient = class {
|
package/dist/index.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { a as initDingtalkPluginConfigSchema, i as dingtalkPlugin, n as setDingtalkRuntime } from "./runtime-
|
|
2
|
-
import { t as registerGatewayMethods } from "./gateway-methods-
|
|
1
|
+
import { a as initDingtalkPluginConfigSchema, i as dingtalkPlugin, n as setDingtalkRuntime } from "./runtime-CjE4Z9G5.mjs";
|
|
2
|
+
import { t as registerGatewayMethods } from "./gateway-methods-BdcpfxEZ.mjs";
|
|
3
3
|
//#region index.ts
|
|
4
4
|
/**
|
|
5
5
|
* 检测同一 plugin id 在多个路径被加载的情况。
|
|
@@ -1,8 +1,21 @@
|
|
|
1
1
|
//#region src/utils/logger.ts
|
|
2
2
|
/**
|
|
3
3
|
* 日志工具模块
|
|
4
|
-
*
|
|
4
|
+
* 根据配置里的 debug 控制日志输出(无需环境变量)
|
|
5
5
|
*/
|
|
6
|
+
/** 任一账号/连接开启过 debug 后为 true;默认静默 */
|
|
7
|
+
let pluginDebugEnabled = false;
|
|
8
|
+
/**
|
|
9
|
+
* 设置插件全局 debug(由配置 `debug: true` 驱动)
|
|
10
|
+
* 仅在 true 时打开;避免多账号中未开 debug 的账号把开关关掉。
|
|
11
|
+
*/
|
|
12
|
+
function setDingtalkDebug(enabled) {
|
|
13
|
+
if (enabled) pluginDebugEnabled = true;
|
|
14
|
+
}
|
|
15
|
+
/** 是否输出图片/引用/队列等详细诊断日志 */
|
|
16
|
+
function isDingtalkDebug() {
|
|
17
|
+
return pluginDebugEnabled;
|
|
18
|
+
}
|
|
6
19
|
/**
|
|
7
20
|
* 创建日志记录器
|
|
8
21
|
* @param debug - 是否启用 debug 模式
|
|
@@ -10,6 +23,7 @@
|
|
|
10
23
|
* @returns 日志记录器对象
|
|
11
24
|
*/
|
|
12
25
|
function createLogger(debug = false, prefix = "") {
|
|
26
|
+
if (debug) setDingtalkDebug(true);
|
|
13
27
|
return {
|
|
14
28
|
/**
|
|
15
29
|
* 打印 info 级别日志
|
|
@@ -55,4 +69,4 @@ function createLoggerFromConfig(config, prefix = "") {
|
|
|
55
69
|
return createLogger(!!config?.debug, prefix);
|
|
56
70
|
}
|
|
57
71
|
//#endregion
|
|
58
|
-
export { createLoggerFromConfig as n, createLogger as t };
|
|
72
|
+
export { setDingtalkDebug as i, createLoggerFromConfig as n, isDingtalkDebug as r, createLogger as t };
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { _ as toLocalPath, d as processLocalImages, f as processRawMediaPaths, h as sendFileProactive, o as hasResidualLocalMdImagesOutsideCode, p as processVideoMarkers } from "./media-
|
|
1
|
+
import { _ as toLocalPath, d as processLocalImages, f as processRawMediaPaths, h as sendFileProactive, o as hasResidualLocalMdImagesOutsideCode, p as processVideoMarkers } from "./media-g8tJtpfU.mjs";
|
|
2
2
|
export { hasResidualLocalMdImagesOutsideCode, processLocalImages, processRawMediaPaths, processVideoMarkers, sendFileProactive, toLocalPath };
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { r as isDingtalkDebug } from "./logger-CnBTcwyq.mjs";
|
|
1
2
|
import { n as dingtalkOapiHttp, t as dingtalkHttp } from "./http-client-DFWZgO1n.mjs";
|
|
2
3
|
import { n as DINGTALK_OAPI } from "./utils-CIfI_3Jh.mjs";
|
|
3
4
|
import { createRequire } from "node:module";
|
|
@@ -76,9 +77,8 @@ function toLocalPath(raw) {
|
|
|
76
77
|
return filePath;
|
|
77
78
|
}
|
|
78
79
|
/**
|
|
79
|
-
*
|
|
80
|
-
*
|
|
81
|
-
* 决策路径(匹配/exists/上传成败/残留)务必 always-on,方便查灰图。
|
|
80
|
+
* 本地图诊断日志。
|
|
81
|
+
* 默认静默:无图/空扫描不再刷屏。仅在上传/失败/灰图风险,或 debug: true 时输出。
|
|
82
82
|
*/
|
|
83
83
|
function logLocalImage(log, step, detail, verbose = false) {
|
|
84
84
|
const line = detail ? `[DingTalk][LocalImage] ${step} | ${detail}` : `[DingTalk][LocalImage] ${step}`;
|
|
@@ -88,6 +88,12 @@ function logLocalImage(log, step, detail, verbose = false) {
|
|
|
88
88
|
} catch {}
|
|
89
89
|
return;
|
|
90
90
|
}
|
|
91
|
+
if (!(isDingtalkDebug() || /失败|灰图|残留|上传成功|上传失败|下载成功|下载失败|重试|remote|Remote/i.test(`${step} ${detail || ""}`))) {
|
|
92
|
+
try {
|
|
93
|
+
log?.debug?.(line);
|
|
94
|
+
} catch {}
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
91
97
|
console.log(line);
|
|
92
98
|
}
|
|
93
99
|
/** 钉钉 mediaId 形态(oapi 返回常带 @) */
|
|
@@ -117,7 +123,7 @@ function logMediaIdTrace(stage, content, extra, force = false) {
|
|
|
117
123
|
const residualLocal = mdTargets.filter((t) => isLocalImageRef(t));
|
|
118
124
|
const httpCount = (text.match(/https?:\/\//gi) || []).length;
|
|
119
125
|
const suspiciousBare = /type=image|sampleImage|photoURL/i.test(`${stage} ${extra || ""}`) ? [] : bareIds;
|
|
120
|
-
if (!(force || suspiciousBare.length > 0 || residualLocal.length > 0
|
|
126
|
+
if (!(force || isDingtalkDebug() || suspiciousBare.length > 0 || residualLocal.length > 0)) return;
|
|
121
127
|
const preview = text.replace(/\n/g, "\\n").slice(0, 200);
|
|
122
128
|
console.log(`[DingTalk][MediaIdTrace] ${stage} | len=${text.length} mediaIdCount=${ids.length}` + (ids.length ? ` ids=[${ids.slice(0, 4).join(",")}]` : "") + ` BARE_ids=${suspiciousBare.length ? suspiciousBare.join(",") : "无"} mdImgs=[${mdImgs.length ? mdImgs.join(" || ") : "-"}] httpCount=${httpCount}` + (residualLocal.length ? ` residualLocal=${residualLocal.length}:${residualLocal.slice(0, 3).map((p) => p.slice(0, 80)).join("|")}` : " residualLocal=0") + (extra ? ` ${extra}` : "") + ` preview="${preview}"`);
|
|
123
129
|
}
|
|
@@ -277,7 +283,7 @@ async function downloadRemoteUrlToTemp(url) {
|
|
|
277
283
|
}
|
|
278
284
|
const tmp = path.join(os.tmpdir(), `dingtalk-md-remote-${Date.now()}-${Math.random().toString(36).slice(2, 8)}${ext}`);
|
|
279
285
|
fs.writeFileSync(tmp, buf);
|
|
280
|
-
console.log(`[DingTalk][MediaIdTrace] 远程图下载成功 | bytes=${buf.length} tmp=${tmp}`);
|
|
286
|
+
if (isDingtalkDebug()) console.log(`[DingTalk][MediaIdTrace] 远程图下载成功 | bytes=${buf.length} tmp=${tmp}`);
|
|
281
287
|
return tmp;
|
|
282
288
|
} catch (e) {
|
|
283
289
|
console.warn(`[DingTalk][MediaIdTrace] 远程图下载异常 | ${e?.message || e}`);
|
|
@@ -312,27 +318,29 @@ function replaceOutsideImageTargets(content, original, replacement) {
|
|
|
312
318
|
* - 本地:正文重复的本地路径换成 down.dingtalk.com 可点链接(仍同一条消息)
|
|
313
319
|
* - **不再拆第二条 text 消息**
|
|
314
320
|
*
|
|
315
|
-
*
|
|
316
|
-
* -
|
|
321
|
+
* 日志约定(默认静默;配置 debug: true 全量):
|
|
322
|
+
* - 有图上传/失败/灰图残留才 console;无图路径不刷屏
|
|
317
323
|
*/
|
|
318
324
|
async function processImagesForOutbound(content, oapiToken, log) {
|
|
319
325
|
logLocalImage(log, "processImagesForOutbound 开始", `contentLen=${content?.length ?? 0} hasToken=${!!oapiToken}`);
|
|
320
326
|
if (!oapiToken) {
|
|
321
|
-
|
|
322
|
-
|
|
327
|
+
if (/!\[[^\]]*\]\([^)]+\)/.test(content || "")) {
|
|
328
|
+
logLocalImage(log, "processImagesForOutbound 跳过", "无 oapiToken(本地路径无法上传→必灰图)");
|
|
329
|
+
logMediaIdTrace("processImagesForOutbound:skip-no-token", content);
|
|
330
|
+
}
|
|
323
331
|
return {
|
|
324
332
|
text: content || "",
|
|
325
333
|
followUpUrls: []
|
|
326
334
|
};
|
|
327
335
|
}
|
|
328
336
|
if (!content || typeof content !== "string") {
|
|
329
|
-
logLocalImage(log, "processImagesForOutbound 跳过", "content 为空");
|
|
337
|
+
logLocalImage(log, "processImagesForOutbound 跳过", "content 为空", true);
|
|
330
338
|
return {
|
|
331
339
|
text: content || "",
|
|
332
340
|
followUpUrls: []
|
|
333
341
|
};
|
|
334
342
|
}
|
|
335
|
-
logMediaIdTrace("processImagesForOutbound:in", content
|
|
343
|
+
logMediaIdTrace("processImagesForOutbound:in", content);
|
|
336
344
|
const codeRanges = getMarkdownCodeRanges(content);
|
|
337
345
|
if (codeRanges.length > 0) logLocalImage(log, "processImagesForOutbound 代码区域", `count=${codeRanges.length}(围栏/行内 code 内的图路径将跳过)`);
|
|
338
346
|
const mdMatches = [...content.matchAll(LOCAL_IMAGE_RE)];
|
|
@@ -435,9 +443,10 @@ async function processImagesForOutbound(content, oapiToken, log) {
|
|
|
435
443
|
if (m.index !== void 0 && isIndexInCodeRange(m.index, getMarkdownCodeRanges(result))) return false;
|
|
436
444
|
return isLocalImageRef((m[2] || "").trim());
|
|
437
445
|
}).map((m) => (m[2] || "").trim());
|
|
438
|
-
logLocalImage(log, "processImagesForOutbound 完成", `uploads=${uploadCount} localTried=${localTried} remoteTried=${remoteTried} skippedCode=${skippedCode} skippedOther=${skippedOther} outLen=${result.length}` + (residual.length ? ` ⚠️residualLocal=${residual.length}:${residual.slice(0, 3).join("|")}` : " residualLocal=0"));
|
|
446
|
+
if (uploadCount > 0 || localTried > 0 || remoteTried > 0 || residual.length > 0) logLocalImage(log, residual.length ? "processImagesForOutbound 完成(有残留)" : "processImagesForOutbound 上传成功", `uploads=${uploadCount} localTried=${localTried} remoteTried=${remoteTried} skippedCode=${skippedCode} skippedOther=${skippedOther} outLen=${result.length}` + (residual.length ? ` ⚠️residualLocal=${residual.length}:${residual.slice(0, 3).join("|")}` : " residualLocal=0"));
|
|
447
|
+
else logLocalImage(log, "processImagesForOutbound 完成", `uploads=0 outLen=${result.length}`, true);
|
|
439
448
|
if (residual.length) logLocalImage(log, "processImagesForOutbound ⚠️仍有代码块外本地路径未替换(钉钉必灰图)", residual.join(" | "));
|
|
440
|
-
logMediaIdTrace("processImagesForOutbound:out", result
|
|
449
|
+
logMediaIdTrace("processImagesForOutbound:out", result);
|
|
441
450
|
return {
|
|
442
451
|
text: result,
|
|
443
452
|
followUpUrls: []
|
|
@@ -658,7 +667,7 @@ async function extractAudioDuration(filePath, log) {
|
|
|
658
667
|
*/
|
|
659
668
|
async function sendVideoMessage(config, sessionWebhook, fileName, mediaId, log, metadata) {
|
|
660
669
|
try {
|
|
661
|
-
const token = await (await import("./utils-
|
|
670
|
+
const token = await (await import("./utils-Bwz2Fls_.mjs")).getAccessToken(config);
|
|
662
671
|
const videoMessage = {
|
|
663
672
|
msgtype: "video",
|
|
664
673
|
video: {
|
|
@@ -686,8 +695,8 @@ async function sendVideoMessage(config, sessionWebhook, fileName, mediaId, log,
|
|
|
686
695
|
*/
|
|
687
696
|
async function sendVideoProactive(config, target, videoMediaId, picMediaId, metadata, log) {
|
|
688
697
|
try {
|
|
689
|
-
const token = await (await import("./utils-
|
|
690
|
-
const { DINGTALK_API } = await import("./utils-
|
|
698
|
+
const token = await (await import("./utils-Bwz2Fls_.mjs")).getAccessToken(config);
|
|
699
|
+
const { DINGTALK_API } = await import("./utils-Bwz2Fls_.mjs");
|
|
691
700
|
const msgParam = {
|
|
692
701
|
duration: metadata?.duration.toString() || "60000",
|
|
693
702
|
videoMediaId,
|
|
@@ -732,8 +741,8 @@ async function sendVideoProactive(config, target, videoMediaId, picMediaId, meta
|
|
|
732
741
|
*/
|
|
733
742
|
async function sendAudioProactive(config, target, fileName, mediaId, log, durationMs) {
|
|
734
743
|
try {
|
|
735
|
-
const token = await (await import("./utils-
|
|
736
|
-
const { DINGTALK_API } = await import("./utils-
|
|
744
|
+
const token = await (await import("./utils-Bwz2Fls_.mjs")).getAccessToken(config);
|
|
745
|
+
const { DINGTALK_API } = await import("./utils-Bwz2Fls_.mjs");
|
|
737
746
|
const msgParam = {
|
|
738
747
|
mediaId,
|
|
739
748
|
duration: durationMs && durationMs > 0 ? durationMs.toString() : "60000"
|
|
@@ -770,8 +779,8 @@ async function sendAudioProactive(config, target, fileName, mediaId, log, durati
|
|
|
770
779
|
*/
|
|
771
780
|
async function sendFileProactive(config, target, fileInfo, mediaId, log) {
|
|
772
781
|
try {
|
|
773
|
-
const token = await (await import("./utils-
|
|
774
|
-
const { DINGTALK_API } = await import("./utils-
|
|
782
|
+
const token = await (await import("./utils-Bwz2Fls_.mjs")).getAccessToken(config);
|
|
783
|
+
const { DINGTALK_API } = await import("./utils-Bwz2Fls_.mjs");
|
|
775
784
|
const resolvedFileName = fileInfo.fileName || path.basename(fileInfo.path);
|
|
776
785
|
const msgParam = {
|
|
777
786
|
mediaId,
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
import { a as resolveDingtalkAccount } from "./accounts-BAzdqkAV.mjs";
|
|
2
|
-
import { r as CHANNEL_ID, t as getDingtalkRuntime } from "./runtime-
|
|
3
|
-
import { n as createLoggerFromConfig } from "./logger-
|
|
2
|
+
import { r as CHANNEL_ID, t as getDingtalkRuntime } from "./runtime-CjE4Z9G5.mjs";
|
|
3
|
+
import { n as createLoggerFromConfig, r as isDingtalkDebug } from "./logger-CnBTcwyq.mjs";
|
|
4
4
|
import { t as dingtalkHttp } from "./http-client-DFWZgO1n.mjs";
|
|
5
5
|
import { i as getOapiAccessToken } from "./utils-CIfI_3Jh.mjs";
|
|
6
|
-
import { S as finalClean, _ as FINAL_TAG, a as sendTextMessage, b as estimateTokens, d as finishAICard, g as unregisterActiveCard, h as streamAICard, i as sendProactive, m as registerActiveCard, p as isQpsLimitError, r as sendMessage, t as sendMarkdownMessage, u as createAICardForTarget, v as PROCESS_TAG, x as extractFinal, y as displayClean } from "./messaging-
|
|
6
|
+
import { S as finalClean, _ as FINAL_TAG, a as sendTextMessage, b as estimateTokens, d as finishAICard, g as unregisterActiveCard, h as streamAICard, i as sendProactive, m as registerActiveCard, p as isQpsLimitError, r as sendMessage, t as sendMarkdownMessage, u as createAICardForTarget, v as PROCESS_TAG, x as extractFinal, y as displayClean } from "./messaging-CK0Wz3Ze.mjs";
|
|
7
7
|
import { a as QUEUE_BUSY_ACK_PHRASES, n as normalizeSlashCommand, t as buildSessionContext } from "./session-DJ4jYqPv.mjs";
|
|
8
8
|
import { c as formatSenderRoles, f as getUserProfile, h as recallEmotionReply, l as getAccessToken, o as formatHiredDateShanghai, r as addEmotionReply, s as formatSenderDisplayLabel, t as DINGTALK_API, u as getOapiAccessToken$1 } from "./utils-legacy-DQ3HeGHh.mjs";
|
|
9
|
-
import { r as trackBackgroundWork } from "./background-work-
|
|
10
|
-
import "./chunk-upload-
|
|
11
|
-
import { a as toLocalPath, i as VIDEO_MARKER_PATTERN, o as uploadMediaToDingTalk, r as FILE_MARKER_PATTERN, t as AUDIO_MARKER_PATTERN } from "./common-
|
|
12
|
-
import { n as lookupCardContent, t as collectCardLookupIds } from "./card-content-cache-
|
|
9
|
+
import { r as trackBackgroundWork } from "./background-work-DkaSDqWk.mjs";
|
|
10
|
+
import "./chunk-upload-CIU5G_ay.mjs";
|
|
11
|
+
import { a as toLocalPath, i as VIDEO_MARKER_PATTERN, o as uploadMediaToDingTalk, r as FILE_MARKER_PATTERN, t as AUDIO_MARKER_PATTERN } from "./common-BfIYs1yC.mjs";
|
|
12
|
+
import { n as lookupCardContent, t as collectCardLookupIds } from "./card-content-cache-DT_OYThh.mjs";
|
|
13
13
|
import * as fs from "fs";
|
|
14
14
|
import * as path from "path";
|
|
15
15
|
import * as os from "node:os";
|
|
@@ -63,7 +63,7 @@ function resolveAgentWorkspaceDir(cfg, agentId) {
|
|
|
63
63
|
* 直接复用 media.ts 权威实现,避免 reply 路径与 message 路径两套逻辑分叉。
|
|
64
64
|
*/
|
|
65
65
|
async function processLocalImages(content, oapiToken, log) {
|
|
66
|
-
const { processLocalImages: impl } = await import("./media-
|
|
66
|
+
const { processLocalImages: impl } = await import("./media-DDtX37T2.mjs");
|
|
67
67
|
return impl(content, oapiToken, log);
|
|
68
68
|
}
|
|
69
69
|
//#endregion
|
|
@@ -606,22 +606,20 @@ function createDingtalkReplyDispatcher(params) {
|
|
|
606
606
|
type: "group",
|
|
607
607
|
openConversationId: conversationId
|
|
608
608
|
};
|
|
609
|
-
console.log(`[DingTalk][LocalImage] closeStreaming 开始媒体处理 | target=${JSON.stringify(target)} hasToken=${!!oapiToken} textLen=${finalText.length}`);
|
|
610
609
|
const mdImgCount = (finalText.match(/!\[[^\]]*\]\([^)]+\)/g) || []).length;
|
|
611
|
-
|
|
610
|
+
if (mdImgCount > 0 || isDingtalkDebug()) log.info(`[DingTalk][LocalImage] closeStreaming 媒体处理 | target=${JSON.stringify(target)} hasToken=${!!oapiToken} textLen=${finalText.length} mdImgs=${mdImgCount}`);
|
|
612
611
|
if (oapiToken) {
|
|
613
612
|
const beforeImg = finalText;
|
|
614
613
|
finalText = await processLocalImages(finalText, oapiToken, log);
|
|
615
|
-
if (beforeImg !== finalText)
|
|
614
|
+
if (beforeImg !== finalText) log.info(`[DingTalk][LocalImage] closeStreaming 图片已处理 | ${beforeImg.length}→${finalText.length}`);
|
|
616
615
|
try {
|
|
617
|
-
const { hasResidualLocalMdImagesOutsideCode } = await import("./media-
|
|
618
|
-
if (hasResidualLocalMdImagesOutsideCode(finalText))
|
|
616
|
+
const { hasResidualLocalMdImagesOutsideCode } = await import("./media-DDtX37T2.mjs");
|
|
617
|
+
if (hasResidualLocalMdImagesOutsideCode(finalText)) log.warn(`[DingTalk][LocalImage] closeStreaming 定稿后仍有代码块外的本地 MD 图未上传,钉钉可能灰图`);
|
|
619
618
|
} catch {}
|
|
620
619
|
finalText = await processVideoMarkers(finalText, "", account.config, oapiToken, log, true, target);
|
|
621
620
|
finalText = await processAudioMarkers(finalText, "", account.config, oapiToken, log, true, target);
|
|
622
621
|
finalText = await uploadAndReplaceFileMarkers(finalText, "", account.config, oapiToken, log, true, target);
|
|
623
|
-
|
|
624
|
-
const { processRawMediaPaths } = await import("./media-BqpUGCni.mjs");
|
|
622
|
+
const { processRawMediaPaths } = await import("./media-DDtX37T2.mjs");
|
|
625
623
|
finalText = await processRawMediaPaths(finalText, account.config, oapiToken, log, target);
|
|
626
624
|
log.info(`[DingTalk][closeStreaming] processRawMediaPaths 处理完成`);
|
|
627
625
|
} else log.warn(`[DingTalk][closeStreaming] oapiToken 为空,跳过媒体处理`);
|
|
@@ -774,11 +772,8 @@ function createDingtalkReplyDispatcher(params) {
|
|
|
774
772
|
onSkip: (payload, info) => {
|
|
775
773
|
const raw = readPayloadRawError(payload);
|
|
776
774
|
const isErr = Boolean(payload?.isError);
|
|
777
|
-
if (!raw && !isErr)
|
|
778
|
-
|
|
779
|
-
return;
|
|
780
|
-
}
|
|
781
|
-
log.warn(`[DingTalk][onSkip] kind=${info?.kind} reason=${info?.reason} isError=${isErr} rawLen=${raw.length}(群聊静默失败常见)`);
|
|
775
|
+
if (!raw && !isErr) return;
|
|
776
|
+
log.warn(`[DingTalk][onSkip] 群聊静默失败 kind=${info?.kind} reason=${info?.reason} rawLen=${raw.length}`);
|
|
782
777
|
captureErrorFromPayload(payload, `onSkip:${info?.kind ?? "?"}:${info?.reason ?? "?"}`);
|
|
783
778
|
},
|
|
784
779
|
onReplyStart: () => {
|
|
@@ -815,6 +810,13 @@ function createDingtalkReplyDispatcher(params) {
|
|
|
815
810
|
await startStreaming();
|
|
816
811
|
if (isNonAnswerPayload(payload)) {
|
|
817
812
|
const isModelErrorFinal = Boolean(payload.isError) && info?.kind === "final" && Boolean(text.trim());
|
|
813
|
+
const existingAnswerText = (lastAnswerText.trim() || accumulatedText.trim()).trim();
|
|
814
|
+
if (isModelErrorFinal && /Agent couldn't generate a response/i.test(text) && existingAnswerText.length >= 20 && !/Agent couldn't generate a response/i.test(existingAnswerText)) {
|
|
815
|
+
pendingErrorText = null;
|
|
816
|
+
log.warn(`[DingTalk][deliver] 忽略 incomplete_turn 误报 isError final(卡片已有真实答案 len=${existingAnswerText.length}),不定格错误卡`);
|
|
817
|
+
await closeStreaming();
|
|
818
|
+
return;
|
|
819
|
+
}
|
|
818
820
|
if (isModelErrorFinal) {
|
|
819
821
|
accumulatedText = text;
|
|
820
822
|
log.info(`[DingTalk][deliver] 将上游异常 final 文本存入 accumulatedText(len=${text.length}),防止 onIdle 覆盖`);
|
|
@@ -846,7 +848,7 @@ function createDingtalkReplyDispatcher(params) {
|
|
|
846
848
|
const oapiToken = await getOapiAccessToken(account.config);
|
|
847
849
|
if (oapiToken) {
|
|
848
850
|
log.info(`[DingTalk][deliver] 检测到 final 响应,准备处理裸露文件路径`);
|
|
849
|
-
const { processRawMediaPaths } = await import("./media-
|
|
851
|
+
const { processRawMediaPaths } = await import("./media-DDtX37T2.mjs");
|
|
850
852
|
text = await processRawMediaPaths(text, account.config, oapiToken, log, target);
|
|
851
853
|
log.info(`[DingTalk][deliver] 裸露文件路径处理完成`);
|
|
852
854
|
}
|
|
@@ -976,7 +978,7 @@ function createDingtalkReplyDispatcher(params) {
|
|
|
976
978
|
currentToolLine = "";
|
|
977
979
|
await startStreaming();
|
|
978
980
|
if (currentCardTarget) try {
|
|
979
|
-
const { FILE_MARKER_PATTERN, VIDEO_MARKER_PATTERN, AUDIO_MARKER_PATTERN } = await import("./common-
|
|
981
|
+
const { FILE_MARKER_PATTERN, VIDEO_MARKER_PATTERN, AUDIO_MARKER_PATTERN } = await import("./common-C0Oaf0z-.mjs");
|
|
980
982
|
await enqueueCardStream(buildCardContent().replace(FILE_MARKER_PATTERN, "").replace(VIDEO_MARKER_PATTERN, "").replace(AUDIO_MARKER_PATTERN, "").trim(), { force: true });
|
|
981
983
|
} catch (err) {
|
|
982
984
|
if (!isQpsLimitError(err)) log.error(`[DingTalk][onPartialReply] final-marker 刷卡失败:${err.message}`);
|
|
@@ -989,7 +991,7 @@ function createDingtalkReplyDispatcher(params) {
|
|
|
989
991
|
if (payload.text?.trim()) hasModelStreamText = true;
|
|
990
992
|
currentToolLine = "";
|
|
991
993
|
try {
|
|
992
|
-
const { FILE_MARKER_PATTERN, VIDEO_MARKER_PATTERN, AUDIO_MARKER_PATTERN } = await import("./common-
|
|
994
|
+
const { FILE_MARKER_PATTERN, VIDEO_MARKER_PATTERN, AUDIO_MARKER_PATTERN } = await import("./common-C0Oaf0z-.mjs");
|
|
993
995
|
await enqueueCardStream(buildCardContent().replace(FILE_MARKER_PATTERN, "").replace(VIDEO_MARKER_PATTERN, "").replace(AUDIO_MARKER_PATTERN, "").trim());
|
|
994
996
|
} catch (err) {
|
|
995
997
|
if (isQpsLimitError(err)) log.warn(`[DingTalk][onPartialReply] QPS 限流,已排队尾随重试 latestLen=${latestCardContent.length}`);
|
|
@@ -1184,8 +1186,9 @@ function extractQuotedMsgText(container, maxDepth, conversationId) {
|
|
|
1184
1186
|
conversationId,
|
|
1185
1187
|
allowConversationRecent: false
|
|
1186
1188
|
}) || "";
|
|
1187
|
-
if (cardText)
|
|
1188
|
-
|
|
1189
|
+
if (cardText) {
|
|
1190
|
+
if (isDingtalkDebug()) console.log(`[DingTalk][Quote] interactiveCard 已从 CardCache 精确回填 | ids=${ids.join(",") || "-"} len=${cardText.length}`);
|
|
1191
|
+
} else if (isDingtalkDebug()) {
|
|
1189
1192
|
const dump = JSON.stringify(repliedMsg ?? {}).slice(0, 800);
|
|
1190
1193
|
console.log(`[DingTalk][Quote] interactiveCard 无正文且缓存未命中(未使用会话最近兜底) | conv=${conversationId || "-"} keys=${Object.keys(contentObj || {}).join(",")} repliedMsg=${dump}`);
|
|
1191
1194
|
}
|
|
@@ -1208,13 +1211,13 @@ function extractQuotedMsgText(container, maxDepth, conversationId) {
|
|
|
1208
1211
|
});
|
|
1209
1212
|
if (cached) {
|
|
1210
1213
|
bodyText = cached;
|
|
1211
|
-
console.log(`[DingTalk][Quote] msgType=${msgType} 已从 CardCache 精确回填 | ids=${ids.join(",") || "-"} len=${cached.length}`);
|
|
1214
|
+
if (isDingtalkDebug()) console.log(`[DingTalk][Quote] msgType=${msgType} 已从 CardCache 精确回填 | ids=${ids.join(",") || "-"} len=${cached.length}`);
|
|
1212
1215
|
} else if (/card|interactive/i.test(String(msgType || "")) || ids.length > 0) {
|
|
1213
1216
|
bodyText = "钉钉卡片消息。";
|
|
1214
|
-
console.log(`[DingTalk][Quote] 未知卡片类引用 msgType=${msgType} 已简化占位 | keys=${Object.keys(contentObj || {}).join(",")}`);
|
|
1215
|
-
} else console.log(`[DingTalk][Quote] 未知引用类型 msgType=${msgType} keys=${Object.keys(contentObj || {}).join(",")} dump=${JSON.stringify(repliedMsg ?? {}).slice(0, 600)}`);
|
|
1217
|
+
if (isDingtalkDebug()) console.log(`[DingTalk][Quote] 未知卡片类引用 msgType=${msgType} 已简化占位 | keys=${Object.keys(contentObj || {}).join(",")}`);
|
|
1218
|
+
} else if (isDingtalkDebug()) console.log(`[DingTalk][Quote] 未知引用类型 msgType=${msgType} keys=${Object.keys(contentObj || {}).join(",")} dump=${JSON.stringify(repliedMsg ?? {}).slice(0, 600)}`);
|
|
1216
1219
|
} catch {
|
|
1217
|
-
console.log(`[DingTalk][Quote] 未知引用类型 msgType=${msgType} keys=${Object.keys(contentObj || {}).join(",")}`);
|
|
1220
|
+
if (isDingtalkDebug()) console.log(`[DingTalk][Quote] 未知引用类型 msgType=${msgType} keys=${Object.keys(contentObj || {}).join(",")}`);
|
|
1218
1221
|
}
|
|
1219
1222
|
break;
|
|
1220
1223
|
}
|
|
@@ -2320,7 +2323,7 @@ async function handleDingTalkMessageInternal(params) {
|
|
|
2320
2323
|
finalText = await processVideoMarkers(finalText, "", config, oapiToken, log, true, mediaTarget);
|
|
2321
2324
|
finalText = await processAudioMarkers(finalText, "", config, oapiToken, log, true, mediaTarget);
|
|
2322
2325
|
finalText = await uploadAndReplaceFileMarkers(finalText, "", config, oapiToken, log, true, mediaTarget);
|
|
2323
|
-
const { processRawMediaPaths } = await import("./media-
|
|
2326
|
+
const { processRawMediaPaths } = await import("./media-DDtX37T2.mjs");
|
|
2324
2327
|
finalText = await processRawMediaPaths(finalText, config, oapiToken, log, mediaTarget);
|
|
2325
2328
|
}
|
|
2326
2329
|
const textToSend = finalText.trim() || "✅ 任务执行完成(无文本输出)";
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { c as logMediaIdTrace, d as processLocalImages, u as processImagesForOutbound, y as uploadMediaToDingTalk } from "./media-
|
|
2
|
-
import { n as createLoggerFromConfig } from "./logger-
|
|
1
|
+
import { c as logMediaIdTrace, d as processLocalImages, u as processImagesForOutbound, y as uploadMediaToDingTalk } from "./media-g8tJtpfU.mjs";
|
|
2
|
+
import { n as createLoggerFromConfig, r as isDingtalkDebug } from "./logger-CnBTcwyq.mjs";
|
|
3
3
|
import { t as dingtalkHttp } from "./http-client-DFWZgO1n.mjs";
|
|
4
4
|
import { i as getOapiAccessToken, r as getAccessToken, t as DINGTALK_API } from "./utils-CIfI_3Jh.mjs";
|
|
5
5
|
import { r as MEDIA_MSG_TYPES } from "./session-DJ4jYqPv.mjs";
|
|
@@ -371,7 +371,7 @@ async function finishAICard(card, content, config, log, contentVar, skipInputing
|
|
|
371
371
|
const fixedContent = ensureTableBlankLines(cleanContent);
|
|
372
372
|
log?.info?.(`[DingTalk][AICard] 开始 finish(一次性定稿,无流式回放),最终内容长度=${fixedContent.length}`);
|
|
373
373
|
try {
|
|
374
|
-
const { rememberCardContent } = await import("./card-content-cache-
|
|
374
|
+
const { rememberCardContent } = await import("./card-content-cache-C7-XHhHw.mjs");
|
|
375
375
|
rememberCardContent({
|
|
376
376
|
text: fixedContent,
|
|
377
377
|
outTrackId: card.cardInstanceId,
|
|
@@ -821,7 +821,7 @@ function isImageMediaPath(mediaUrl) {
|
|
|
821
821
|
async function downloadRemoteMediaToTemp(url, log) {
|
|
822
822
|
const tag = "[DingTalk][RemoteMedia]";
|
|
823
823
|
try {
|
|
824
|
-
console.log(`${tag} 开始下载 | ${url}`);
|
|
824
|
+
if (isDingtalkDebug()) console.log(`${tag} 开始下载 | ${url}`);
|
|
825
825
|
const res = await fetch(url, {
|
|
826
826
|
redirect: "follow",
|
|
827
827
|
signal: AbortSignal.timeout(6e4),
|
|
@@ -858,7 +858,7 @@ async function downloadRemoteMediaToTemp(url, log) {
|
|
|
858
858
|
const { writeFileSync } = await import("node:fs");
|
|
859
859
|
const tmp = path.join(os.tmpdir(), `dingtalk-remote-${Date.now()}-${Math.random().toString(36).slice(2, 8)}${ext}`);
|
|
860
860
|
writeFileSync(tmp, buf);
|
|
861
|
-
console.log(`${tag} 下载成功 | bytes=${buf.length} ct=${ct || "-"} tmp=${tmp}`);
|
|
861
|
+
if (isDingtalkDebug()) console.log(`${tag} 下载成功 | bytes=${buf.length} ct=${ct || "-"} tmp=${tmp}`);
|
|
862
862
|
return tmp;
|
|
863
863
|
} catch (err) {
|
|
864
864
|
console.warn(`${tag} 下载异常 | ${err?.message || err}`);
|
|
@@ -876,7 +876,7 @@ async function resolveMediaSourceToLocalFile(mediaUrl, mediaLocalRoots, log) {
|
|
|
876
876
|
cleanup: tmp
|
|
877
877
|
};
|
|
878
878
|
}
|
|
879
|
-
const { toLocalPath } = await import("./media-
|
|
879
|
+
const { toLocalPath } = await import("./media-DDtX37T2.mjs");
|
|
880
880
|
const _fs = await import("fs");
|
|
881
881
|
const _path = await import("path");
|
|
882
882
|
let resolved = toLocalPath(mediaUrl);
|
|
@@ -911,24 +911,22 @@ async function sendTextToDingTalk(params) {
|
|
|
911
911
|
};
|
|
912
912
|
}
|
|
913
913
|
const targetParam = resolveOutboundTarget(target);
|
|
914
|
-
console.log(`[DingTalk][LocalImage] sendTextToDingTalk 入口 | target=${target} textLen=${text?.length ?? 0}`);
|
|
915
|
-
logMediaIdTrace("sendTextToDingTalk:in", text, `target=${target}`, true);
|
|
916
914
|
const beforeLen = text?.length ?? 0;
|
|
915
|
+
const hasMdImg = /!\[[^\]]*\]\([^)]+\)/.test(text || "");
|
|
916
|
+
if (hasMdImg || isDingtalkDebug()) logMediaIdTrace("sendTextToDingTalk:in", text, `target=${target}`);
|
|
917
917
|
try {
|
|
918
918
|
const oapiToken = await getOapiAccessToken(config);
|
|
919
|
-
console.log(`[DingTalk][LocalImage] sendTextToDingTalk 入口 | target=${target} textLen=${beforeLen} hasToken=${!!oapiToken}`);
|
|
920
919
|
if (oapiToken && text) {
|
|
921
920
|
text = (await processImagesForOutbound(text, oapiToken, log)).text;
|
|
922
|
-
console.log(`[DingTalk][LocalImage] sendTextToDingTalk 处理后 | ${beforeLen}→${text.length} 字`);
|
|
923
|
-
logMediaIdTrace("sendTextToDingTalk:after-process", text
|
|
924
|
-
} else if (!oapiToken) console.warn(`[DingTalk][LocalImage] sendTextToDingTalk 无 oapiToken,跳过图片上传(本地 MD 图会灰)`);
|
|
921
|
+
if (beforeLen !== text.length && (hasMdImg || isDingtalkDebug())) console.log(`[DingTalk][LocalImage] sendTextToDingTalk 处理后 | ${beforeLen}→${text.length} 字`);
|
|
922
|
+
if (hasMdImg || isDingtalkDebug()) logMediaIdTrace("sendTextToDingTalk:after-process", text);
|
|
923
|
+
} else if (!oapiToken && hasMdImg) console.warn(`[DingTalk][LocalImage] sendTextToDingTalk 无 oapiToken,跳过图片上传(本地 MD 图会灰)`);
|
|
925
924
|
} catch (err) {
|
|
926
925
|
console.warn(`[DingTalk][LocalImage] sendTextToDingTalk 图片处理失败: ${err?.message || err}`);
|
|
927
926
|
}
|
|
928
927
|
const msgType = shouldSendAsMarkdown(text) ? "markdown" : "text";
|
|
929
928
|
const cardOpts = messageToolProactiveCardOptions(config);
|
|
930
|
-
logMediaIdTrace("sendTextToDingTalk:API前", text, `msgType=${msgType} messageAnswerCard=${isMessageAnswerCardEnabled(config)} useAICard=${cardOpts.useAICard}
|
|
931
|
-
console.log(`[DingTalk][MessageCard] sendTextToDingTalk | messageAnswerCard=${isMessageAnswerCardEnabled(config)} useAICard=${cardOpts.useAICard} tpl=${cardOpts.cardTemplateId || "-"}`);
|
|
929
|
+
if (hasMdImg || isDingtalkDebug()) logMediaIdTrace("sendTextToDingTalk:API前", text, `msgType=${msgType} messageAnswerCard=${isMessageAnswerCardEnabled(config)} useAICard=${cardOpts.useAICard}`);
|
|
932
930
|
return sendProactive(config, targetParam, text, {
|
|
933
931
|
msgType,
|
|
934
932
|
replyToId,
|
|
@@ -1090,7 +1088,7 @@ async function sendMediaToDingTalk(params) {
|
|
|
1090
1088
|
const mediaId = uploadResult.mediaId;
|
|
1091
1089
|
const imgsInCaption = (caption.match(/!\[[^\]]*\]\([^)]+\)/g) || []).length;
|
|
1092
1090
|
const mergeMd = config.messageImageMd === true && caption.length > 0 && imgsInCaption >= 1;
|
|
1093
|
-
console.log(`[DingTalk][LocalImage] sendMedia 图片策略 | messageImageMd=${config.messageImageMd === true} imgsInCaption=${imgsInCaption} mergeMd=${mergeMd} remote=${isRemoteHttpUrl(mediaUrl)}`);
|
|
1091
|
+
if (isDingtalkDebug()) console.log(`[DingTalk][LocalImage] sendMedia 图片策略 | messageImageMd=${config.messageImageMd === true} imgsInCaption=${imgsInCaption} mergeMd=${mergeMd} remote=${isRemoteHttpUrl(mediaUrl)}`);
|
|
1094
1092
|
if (mergeMd) {
|
|
1095
1093
|
const result = await sendProactive(config, targetParam, `${caption}\n\n`, {
|
|
1096
1094
|
msgType: "markdown",
|
|
@@ -1145,7 +1143,7 @@ async function sendMediaToDingTalk(params) {
|
|
|
1145
1143
|
const fileName = mediaUrl.split("/").filter(Boolean).pop()?.split("?")[0] || "file";
|
|
1146
1144
|
if (mediaType === "video") {
|
|
1147
1145
|
const videoMarker = `[DINGTALK_VIDEO]{"path":"${resolvedMediaUrl}"}[/DINGTALK_VIDEO]`;
|
|
1148
|
-
const { processVideoMarkers } = await import("./media-
|
|
1146
|
+
const { processVideoMarkers } = await import("./media-DDtX37T2.mjs");
|
|
1149
1147
|
await processVideoMarkers(videoMarker, "", config, oapiToken, console, true, targetParam);
|
|
1150
1148
|
return {
|
|
1151
1149
|
ok: true,
|
|
@@ -1164,7 +1162,7 @@ async function sendMediaToDingTalk(params) {
|
|
|
1164
1162
|
fileName,
|
|
1165
1163
|
fileType: ext && ext.length < 12 ? ext : "file"
|
|
1166
1164
|
};
|
|
1167
|
-
const { sendFileProactive } = await import("./media-
|
|
1165
|
+
const { sendFileProactive } = await import("./media-DDtX37T2.mjs");
|
|
1168
1166
|
await sendFileProactive(config, targetParam, fileInfo, uploadResult.mediaId, log);
|
|
1169
1167
|
return {
|
|
1170
1168
|
ok: true,
|
|
@@ -1174,7 +1172,7 @@ async function sendMediaToDingTalk(params) {
|
|
|
1174
1172
|
} finally {
|
|
1175
1173
|
if (cleanupTemp) try {
|
|
1176
1174
|
_fs.unlinkSync(cleanupTemp);
|
|
1177
|
-
console.log(`[DingTalk][RemoteMedia] 已清理临时文件 | ${cleanupTemp}`);
|
|
1175
|
+
if (isDingtalkDebug()) console.log(`[DingTalk][RemoteMedia] 已清理临时文件 | ${cleanupTemp}`);
|
|
1178
1176
|
} catch {}
|
|
1179
1177
|
}
|
|
1180
1178
|
} catch (err) {
|
|
@@ -1249,7 +1247,7 @@ async function sendProactiveInternal(config, target, content, options) {
|
|
|
1249
1247
|
const card = await createAICardForTarget(config, target, externalLog, cardTemplateId);
|
|
1250
1248
|
if (card) {
|
|
1251
1249
|
await finishAICard(card, content, config, externalLog, void 0, skipInputingWalk);
|
|
1252
|
-
console.log(`[DingTalk][MessageCard] AI Card 发送成功 | outTrack=${card.cardInstanceId} tpl=${cardTemplateId || "default"} skipInputing=${skipInputingWalk}`);
|
|
1250
|
+
if (isDingtalkDebug()) console.log(`[DingTalk][MessageCard] AI Card 发送成功 | outTrack=${card.cardInstanceId} tpl=${cardTemplateId || "default"} skipInputing=${skipInputingWalk}`);
|
|
1253
1251
|
return {
|
|
1254
1252
|
ok: true,
|
|
1255
1253
|
cardInstanceId: card.cardInstanceId,
|
|
@@ -1292,7 +1290,7 @@ async function sendProactiveInternal(config, target, content, options) {
|
|
|
1292
1290
|
usedAICard: false
|
|
1293
1291
|
};
|
|
1294
1292
|
}
|
|
1295
|
-
logMediaIdTrace("API出站", content, `msgKey=${payload.msgKey} type=${msgType}
|
|
1293
|
+
if (/!\[[^\]]*\]\([^)]+\)/.test(content || "") || isDingtalkDebug()) logMediaIdTrace("API出站", content, `msgKey=${payload.msgKey} type=${msgType}`);
|
|
1296
1294
|
const body = {
|
|
1297
1295
|
robotCode: String(config.clientId),
|
|
1298
1296
|
msgKey: payload.msgKey,
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { b as __exportAll } from "./media-
|
|
1
|
+
import { b as __exportAll } from "./media-g8tJtpfU.mjs";
|
|
2
2
|
import { a as resolveDingtalkAccount, c as addWildcardAllowFrom, d as hasConfiguredSecretInput, f as normalizeAccountId, l as createDefaultChannelRuntimeState, m as resolveDefaultGroupPolicy, o as resolveDingtalkCredentials, p as resolveAllowlistProviderRuntimeGroupPolicy, r as resolveDefaultDingtalkAccountId, s as DEFAULT_ACCOUNT_ID, t as listDingtalkAccountIds, u as formatDocsLink } from "./accounts-BAzdqkAV.mjs";
|
|
3
|
-
import { t as createLogger } from "./logger-
|
|
3
|
+
import { t as createLogger } from "./logger-CnBTcwyq.mjs";
|
|
4
4
|
import { t as dingtalkHttp } from "./http-client-DFWZgO1n.mjs";
|
|
5
5
|
import "./utils-CIfI_3Jh.mjs";
|
|
6
|
-
import { S as finalClean, f as getActiveCardForConversation, n as sendMediaToDingTalk, o as sendTextToDingTalk } from "./messaging-
|
|
6
|
+
import { S as finalClean, f as getActiveCardForConversation, n as sendMediaToDingTalk, o as sendTextToDingTalk } from "./messaging-CK0Wz3Ze.mjs";
|
|
7
7
|
import { createRequire } from "node:module";
|
|
8
8
|
import { z, z as z$1 } from "zod";
|
|
9
9
|
//#region src/secret-input.ts
|
|
@@ -92,6 +92,7 @@ const DingtalkSharedConfigShape = {
|
|
|
92
92
|
asyncMode: z$1.boolean().optional(),
|
|
93
93
|
ackText: z$1.string().optional(),
|
|
94
94
|
endpoint: z$1.string().optional(),
|
|
95
|
+
/** 调试日志:连接/入站摘要、图片 mediaId 追踪、引用回填、队列计数等(默认关,生产勿开) */
|
|
95
96
|
debug: z$1.boolean().optional(),
|
|
96
97
|
enableMediaUpload: z$1.boolean().optional(),
|
|
97
98
|
systemPrompt: z$1.string().optional(),
|
|
@@ -955,8 +956,8 @@ async function monitorDingtalkProvider(opts = {}) {
|
|
|
955
956
|
const log = createLogger(cfg.channels?.["dingtalk-connector"]?.debug ?? false);
|
|
956
957
|
const [accountsModule, monitorAccountModule, monitorSingleModule] = await Promise.all([
|
|
957
958
|
import("./accounts-BQptOmgB.mjs"),
|
|
958
|
-
import("./message-handler-
|
|
959
|
-
import("./connection-
|
|
959
|
+
import("./message-handler-BeTQQCUe.mjs"),
|
|
960
|
+
import("./connection-obtrPkj4.mjs")
|
|
960
961
|
]);
|
|
961
962
|
const { resolveDingtalkAccount, listEnabledDingtalkAccounts } = accountsModule;
|
|
962
963
|
const { handleDingTalkMessage } = monitorAccountModule;
|
|
@@ -2,13 +2,13 @@
|
|
|
2
2
|
|
|
3
3
|
**发布日期:** 2026-07-25
|
|
4
4
|
**npm:** `@jeik/dingtalk-connector@0.8.28`
|
|
5
|
-
**定位:** 基于官方 **0.8.24
|
|
5
|
+
**定位:** 基于官方 **0.8.24**,叠加本仓库独有优化的正式版
|
|
6
6
|
|
|
7
7
|
---
|
|
8
8
|
|
|
9
9
|
## 一句话
|
|
10
10
|
|
|
11
|
-
连接更稳、消息更少丢、模型出错时提示更清楚;官方 0.8.24
|
|
11
|
+
连接更稳、消息更少丢、模型出错时提示更清楚;官方 0.8.24 的长连接改进已吸收,**本仓库独有**的图片/答案卡等优化继续保留。
|
|
12
12
|
|
|
13
13
|
---
|
|
14
14
|
|
|
@@ -22,13 +22,13 @@
|
|
|
22
22
|
|
|
23
23
|
---
|
|
24
24
|
|
|
25
|
-
##
|
|
25
|
+
## 本仓库额外优化(效果)
|
|
26
26
|
|
|
27
27
|
1. **真正能收消息才显示已连接** — 减少「显示在线、发了没反应」
|
|
28
28
|
2. **连发 / 错误后 / 刚回完再发** — 消息进网关的成功率明显提高
|
|
29
29
|
3. **上一条还在跑时再发** — 更容易马上看到排队提示和思考中表情
|
|
30
30
|
4. **模型 503、欠费、无可用线路等** — 更容易定格成中文错误说明,少卡转圈
|
|
31
|
-
5.
|
|
31
|
+
5. **本仓库独有能力** — 大段答案独立卡片、图片全路径、中文错误映射等均保留
|
|
32
32
|
|
|
33
33
|
---
|
|
34
34
|
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
# Release Notes · v0.8.29
|
|
2
|
+
|
|
3
|
+
**发布日期:** 2026-07-25
|
|
4
|
+
**npm:** `@jeik/dingtalk-connector@0.8.29`
|
|
5
|
+
**定位:** 正式加固版(日志 / 排障 / 文档)
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## 一句话
|
|
10
|
+
|
|
11
|
+
默认日志更干净;排障只需配置 `"debug": true`。连接、消息、错误卡能力继承 0.8.28。
|
|
12
|
+
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
## 本版变更
|
|
16
|
+
|
|
17
|
+
1. **默认静默** — 无图正常回复不再刷 LocalImage / MediaIdTrace / CardCache
|
|
18
|
+
2. **debug 配置** — 打开后输出连接、图片 mediaId、引用回填、队列等详细日志(无需环境变量)
|
|
19
|
+
3. **文档** — 安装改为三条递进命令(最新 → 指定版本 → 官方源)
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
## 排障
|
|
24
|
+
|
|
25
|
+
```json
|
|
26
|
+
"channels": {
|
|
27
|
+
"dingtalk-connector": {
|
|
28
|
+
"debug": true
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
改完后:`openclaw gateway restart`。用完请改回 `false`。
|
|
34
|
+
|
|
35
|
+
---
|
|
36
|
+
|
|
37
|
+
## 安装
|
|
38
|
+
|
|
39
|
+
**npx(一键扫码,按顺序试):**
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
# 1)装最新
|
|
43
|
+
npx @jeik/dingtalk-connector install --force && openclaw gateway restart
|
|
44
|
+
|
|
45
|
+
# 2)若不是最新,指定版本
|
|
46
|
+
npx @jeik/dingtalk-connector@0.8.29 install --force && openclaw gateway restart
|
|
47
|
+
|
|
48
|
+
# 3)仍失败时走 npm 官方源
|
|
49
|
+
NPM_CONFIG_REGISTRY=https://registry.npmjs.org npx @jeik/dingtalk-connector@0.8.29 install --force && openclaw gateway restart
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
**openclaw plugins install(只装插件,按顺序试):**
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
# 1)装最新
|
|
56
|
+
openclaw plugins install @jeik/dingtalk-connector --force && openclaw gateway restart
|
|
57
|
+
|
|
58
|
+
# 2)若不是最新,指定版本
|
|
59
|
+
openclaw plugins install @jeik/dingtalk-connector@0.8.29 --force && openclaw gateway restart
|
|
60
|
+
|
|
61
|
+
# 3)仍失败时走 npm 官方源
|
|
62
|
+
NPM_CONFIG_REGISTRY=https://registry.npmjs.org openclaw plugins install @jeik/dingtalk-connector@0.8.29 --force && openclaw gateway restart
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
---
|
|
66
|
+
|
|
67
|
+
## 建议验收
|
|
68
|
+
|
|
69
|
+
1. 默认:纯文本对话日志无 LocalImage / MediaIdTrace 刷屏
|
|
70
|
+
2. `"debug": true` 重启后:可见图片/引用类详细日志
|
|
71
|
+
3. 模型 503:错误卡中文定稿,不永久转圈
|
|
72
|
+
4. 任务进行中再发:有排队/处理中反馈
|