@yaoyuanchao/dingtalk 1.3.4 → 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 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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yaoyuanchao/dingtalk",
3
- "version": "1.3.4",
3
+ "version": "1.3.5",
4
4
  "type": "module",
5
5
  "description": "DingTalk channel plugin for Clawdbot with Stream Mode support",
6
6
  "license": "MIT",
package/src/channel.ts CHANGED
@@ -6,14 +6,21 @@ import { probeDingTalk } from './probe.js';
6
6
 
7
7
  /**
8
8
  * Parse outbound `to` address, stripping optional channel prefix.
9
- * Handles both "dm:id" and "dingtalk:dm:id" formats.
9
+ * Handles: "dm:id", "group:id", "dingtalk:dm:id", "dingtalk:group:id",
10
+ * and bare "id" (treated as DM userId).
10
11
  */
11
12
  function parseOutboundTo(to: string): { type: string; id: string } {
12
13
  const parts = to.split(':');
14
+ // Strip channel prefix: "dingtalk:dm:id" → "dm:id"
13
15
  if (parts[0] === 'dingtalk' && parts.length > 2) {
14
16
  parts.shift();
15
17
  }
16
- return { type: parts[0], id: parts.slice(1).join(':') };
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 };
17
24
  }
18
25
 
19
26
  export const dingtalkPlugin = {