@yaoyuanchao/dingtalk 1.3.3 → 1.3.5
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 +33 -0
- package/package.json +1 -1
- package/src/channel.ts +21 -2
- package/src/monitor.ts +5 -0
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,39 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [1.3.5] - 2026-01-28
|
|
9
|
+
|
|
10
|
+
### Fixed
|
|
11
|
+
|
|
12
|
+
- **Outbound `to` parameter parsing** — bare userId (no `dm:` prefix) now correctly treated as DM target; previously silently dropped with ok:true
|
|
13
|
+
- **SessionWebhook response validation** — `sendViaSessionWebhook()` and `sendMarkdownViaSessionWebhook()` now return errcode/errmsg and check `.ok`; failures trigger REST API fallback instead of being silently ignored
|
|
14
|
+
- **Stream ACK timing** — immediately call `socketResponse()` on message receipt to prevent DingTalk 60-second retry timeout; previously awaited full AI processing before ACK
|
|
15
|
+
- **`resolveDeliverText()` type safety** — check `typeof payload.markdown === 'string'` to avoid treating boolean flags as text content
|
|
16
|
+
|
|
17
|
+
### Changed
|
|
18
|
+
|
|
19
|
+
- **`parseOutboundTo()` enhanced** — handles `"dm:id"`, `"group:id"`, `"dingtalk:dm:id"`, `"dingtalk:group:id"`, and bare `"id"` (defaults to DM)
|
|
20
|
+
- **`deliverReply()` error propagation** — throws on sessionWebhook rejection to trigger retry + REST API fallback
|
|
21
|
+
- **Media URL merging** — `resolveDeliverText()` merges `payload.mediaUrl`/`payload.imageUrl` into text as markdown image syntax
|
|
22
|
+
- **Webhook functions** return `{ ok, errcode, errmsg }` for proper error inspection
|
|
23
|
+
|
|
24
|
+
## [1.3.0] - 2026-01-28
|
|
25
|
+
|
|
26
|
+
### Added
|
|
27
|
+
|
|
28
|
+
- **Full SDK Pipeline** — runtime feature detection for `dispatchReplyFromConfig` with 9-step SDK integration (routing, session, envelope, dispatch)
|
|
29
|
+
- **Media support** — image download via `downloadPicture()`, audio/video/file recognition via `downloadMediaFile()`
|
|
30
|
+
- **Smart Markdown detection** — `messageFormat: 'auto'` option with regex-based content detection
|
|
31
|
+
- **Thinking indicator** — `showThinking` config option sends "正在思考..." before AI processing
|
|
32
|
+
- **Activity recording** — `runtime.channel.activity.record()` calls for start/stop/message events
|
|
33
|
+
- **`cleanupOldMedia()`** — generalized media cleanup (replaces `cleanupOldPictures`)
|
|
34
|
+
|
|
35
|
+
### Changed
|
|
36
|
+
|
|
37
|
+
- **Message extraction refactored** — `extractMessageContent()` switch-case structure for text/richText/picture/audio/video/file
|
|
38
|
+
- **Config schema** — added `showThinking`, `messageFormat: 'auto'` option
|
|
39
|
+
- **`sendMedia()` outbound** — uses markdown image syntax instead of plain URL text
|
|
40
|
+
|
|
8
41
|
## [1.2.0] - 2026-01-28
|
|
9
42
|
|
|
10
43
|
### 🎉 Major Features - Official Plugin Release
|
package/package.json
CHANGED
package/src/channel.ts
CHANGED
|
@@ -4,6 +4,25 @@ import { startDingTalkMonitor } from './monitor.js';
|
|
|
4
4
|
import { sendDingTalkRestMessage } from './api.js';
|
|
5
5
|
import { probeDingTalk } from './probe.js';
|
|
6
6
|
|
|
7
|
+
/**
|
|
8
|
+
* Parse outbound `to` address, stripping optional channel prefix.
|
|
9
|
+
* Handles: "dm:id", "group:id", "dingtalk:dm:id", "dingtalk:group:id",
|
|
10
|
+
* and bare "id" (treated as DM userId).
|
|
11
|
+
*/
|
|
12
|
+
function parseOutboundTo(to: string): { type: string; id: string } {
|
|
13
|
+
const parts = to.split(':');
|
|
14
|
+
// Strip channel prefix: "dingtalk:dm:id" → "dm:id"
|
|
15
|
+
if (parts[0] === 'dingtalk' && parts.length > 2) {
|
|
16
|
+
parts.shift();
|
|
17
|
+
}
|
|
18
|
+
// Known types
|
|
19
|
+
if (parts[0] === 'dm' || parts[0] === 'group') {
|
|
20
|
+
return { type: parts[0], id: parts.slice(1).join(':') };
|
|
21
|
+
}
|
|
22
|
+
// Bare ID (no type prefix) — treat as DM userId
|
|
23
|
+
return { type: 'dm', id: to };
|
|
24
|
+
}
|
|
25
|
+
|
|
7
26
|
export const dingtalkPlugin = {
|
|
8
27
|
id: 'dingtalk',
|
|
9
28
|
|
|
@@ -166,7 +185,7 @@ export const dingtalkPlugin = {
|
|
|
166
185
|
|
|
167
186
|
async sendText({ to, text, accountId, cfg }) {
|
|
168
187
|
const account = resolveDingTalkAccount({ cfg, accountId });
|
|
169
|
-
const
|
|
188
|
+
const { type, id } = parseOutboundTo(to);
|
|
170
189
|
|
|
171
190
|
if (type === 'dm') {
|
|
172
191
|
await sendDingTalkRestMessage({
|
|
@@ -204,7 +223,7 @@ export const dingtalkPlugin = {
|
|
|
204
223
|
}
|
|
205
224
|
|
|
206
225
|
const account = resolveDingTalkAccount({ cfg, accountId });
|
|
207
|
-
const
|
|
226
|
+
const { type, id } = parseOutboundTo(to);
|
|
208
227
|
|
|
209
228
|
// Build text message with image URL as markdown image
|
|
210
229
|
const imageMarkdown = ``;
|
package/src/monitor.ts
CHANGED
|
@@ -52,6 +52,11 @@ export async function startDingTalkMonitor(ctx: DingTalkMonitorContext): Promise
|
|
|
52
52
|
});
|
|
53
53
|
|
|
54
54
|
client.registerCallbackListener(TOPIC_ROBOT, async (downstream: any) => {
|
|
55
|
+
// Immediately ACK to prevent DingTalk from retrying (60s timeout)
|
|
56
|
+
try {
|
|
57
|
+
client.socketResponse(downstream.headers.messageId, { status: 'SUCCESS' });
|
|
58
|
+
} catch (_) { /* best-effort ACK */ }
|
|
59
|
+
|
|
55
60
|
try {
|
|
56
61
|
const data: DingTalkRobotMessage = typeof downstream.data === "string"
|
|
57
62
|
? JSON.parse(downstream.data) : downstream.data;
|