n8n-nodes-dingtalk-card 0.4.0 → 0.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/CHANGELOG.md CHANGED
@@ -1,5 +1,15 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.5.0 (stable)
4
+
5
+ Promotes the production-accepted v0.5.0-beta.1 normalized Trigger envelope without runtime changes. Production acceptance covers one request-button/action-callback path, including legacy downstream expression compatibility. Form and Selection remain unverified and deferred; no broader live interaction claim is made. The npm `beta` channel remains on `0.5.0-beta.1`.
6
+
7
+ ## 0.5.0-beta.1 (published beta; production acceptance complete)
8
+
9
+ - Add the v1 normalized interaction envelope and configurable raw callback serialization.
10
+ - Preserve existing top-level callback fields and callback extraction behavior.
11
+ - Production acceptance passed for the request-button/action-callback path, including the additive normalized envelope and legacy downstream expression compatibility. Form and Selection remain unverified and deferred. Beta.1 is eligible for stable promotion; see [verification](docs/VERIFICATION.md#v050-beta1-production-acceptance--2026-10-25).
12
+
3
13
  ## 0.4.0 (stable)
4
14
 
5
15
  Promotes the production-accepted v0.4.0-beta.2 Presentation Contract & Template Kit to stable. No functional changes from beta.2: adds the fixed AI-host compatibility value `flowStatus: "3"` to Presentation `cardParamMap`, preserving all 13 Presentation contract fields. Production acceptance passed for true Presentation-mode status rendering and Create & Deliver across alert, status, digest, action, and report. No private identifiers are recorded. The package ships no DingTalk templates. The npm `beta` channel remains on `0.4.0-beta.2`.
package/README.md CHANGED
@@ -2,11 +2,13 @@
2
2
 
3
3
  Focused n8n community nodes for the **DingTalk Card Platform lifecycle and Stream card callbacks**.
4
4
 
5
- **v0.4.0 is the stable release.** It adds the Presentation Contract & Template Kit, including five descriptor families and deterministic mapping, while preserving the existing lifecycle behavior. Production acceptance is recorded in [release verification](docs/VERIFICATION.md). This does not certify v1.0 or untested platform/runtime behavior. This project is not n8n-verified and is not affiliated with DingTalk or n8n.
5
+ **v0.5.0 is the stable release.** It promotes the v0.5.0-beta.1 normalized Trigger envelope without runtime changes. Production acceptance covers the request-button/action-callback path only; Form and Selection remain unverified and deferred. This does not certify v1.0 or untested platform/runtime behavior. This project is not n8n-verified and is not affiliated with DingTalk or n8n. See [release verification](docs/VERIFICATION.md).
6
6
 
7
- **v0.4.0-beta.2 remains available on the beta channel.** Its production acceptance established the functional baseline for stable v0.4.0. A true Presentation-mode status card rendered correctly in Mac DingTalk without workflow-supplied `flowStatus` or a JSON request body; the final live Create & Deliver regression passed for alert, status, digest, action, and report. The package ships no DingTalk templates. See the [presentation contract](docs/PRESENTATION.md) and [release verification](docs/VERIFICATION.md).
7
+ The published **v0.4.0-beta.2** established the functional baseline for stable v0.4.0. A true Presentation-mode status card rendered correctly in Mac DingTalk without workflow-supplied `flowStatus` or a JSON request body; the final live Create & Deliver regression passed for alert, status, digest, action, and report. The package ships no DingTalk templates. See the [presentation contract](docs/PRESENTATION.md) and [release verification](docs/VERIFICATION.md).
8
8
 
9
- The npm `latest` dist-tag resolves to `0.4.0`; `beta` remains `0.4.0-beta.2`. Releases use GitHub Actions Trusted Publisher/OIDC with provenance. Beta publication leaves `latest` unchanged now that a stable version exists.
9
+ The published **v0.5.0-beta.1** remains available on the beta channel and is the functional baseline for stable v0.5.0. Its optional normalized Trigger envelope passed production acceptance for one real request-button/action-callback path, with existing downstream expressions continuing to work. Form and Selection remain unverified and deferred. See [release verification](docs/VERIFICATION.md#v050-beta1-production-acceptance--2026-10-25).
10
+
11
+ The npm `latest` dist-tag resolves to `0.5.0`; `beta` remains `0.5.0-beta.1`. Releases use GitHub Actions Trusted Publisher/OIDC with provenance. Beta publication leaves `latest` unchanged now that a stable version exists.
10
12
 
11
13
  It provides **DingTalk Card**, **DingTalk Card Trigger**, and the shared **DingTalk Card API** enterprise app credential. It does not implement OA, todo, tables or general robot messaging, and does not depend on `@cryozerolabs/n8n-nodes-dingtalk`. Robot delivery fields here exist only to deliver Card Platform instances.
12
14
 
@@ -59,6 +61,8 @@ The trigger subscribes **only** to `CALLBACK /v1.0/card/instances/callback`. It
59
61
 
60
62
  Items include `type`, `specVersion`, `headers`, `topic`, `messageId`, ISO `receivedAt`, parsed `data`, and unchanged `rawData`. JSON `content` is exposed if it is an object; `cardPrivateData`, `params` (including `content.cardPrivateData.params`), and supplied `outTrackId`, `userId`, `userIdType`, `openId`, `unionId`, `operatorId`, `operatorUserId` retain source names/values. Missing optional fields stay absent; no identifier types are inferred. Invalid data JSON still receives an ACK and is emitted as a raw string. Invalid outer envelopes, missing message IDs and other topics are ignored. Callback payloads can contain private form/user data: control execution-data access and retention.
61
63
 
64
+ The trigger adds a versioned `normalized` object while retaining all existing top-level fields; existing workflows need no migration. Raw callback serialization remains enabled by default and can be omitted with **Include Raw Callback Data**. This reduces duplicate raw serialization but does not remove sensitive callback content. See [the v1 interaction contract](docs/INTERACTIONS.md). Only the existing request-button/action callback path is live-verified; form and selection inputs remain deferred.
65
+
62
66
  The self-contained transport deliberately avoids the upstream `dingtalk-stream` SDK following verified ticket-bearing URL logging risk on SDK error paths. It uses Node 24+ native WebSocket, n8n’s HTTP helper, validated `wss:` endpoints and `URL.searchParams`; no SDK copy, runtime dependency or global console patch. Gateway bodies, tickets, secrets, URLs and original connection errors never enter its diagnostics. It answers SYSTEM ping with the supplied opaque value, reconnects on SYSTEM disconnect/unexpected close/errors, and watches opening (30s) and idle connections (120s). Reconnect delays are bounded at 1, 2, 4, 8, 16, 30 seconds, then 30 seconds until traffic resumes; each attempt gets a fresh ticket. Lookup/connect failures log generic diagnostics and retry while the workflow stays active. Deactivation aborts gateway lookup, closes pending/active sockets, cancels timers and releases the local lock.
63
67
 
64
68
  The real button callback E2E on 2026-10-24 used the same enterprise-app Client ID for creation and listening. DingTalk Card Trigger activated successfully, and a request-button card with `callbackType=STREAM` was delivered. One real button click produced a `CALLBACK /v1.0/card/instances/callback` trigger execution; normalized `params` contained the expected button id/text. Downstream asynchronous Update returned success, the card visibly changed, and execution completed successfully. This validates the tested button path and immediate receipt ACK transport with asynchronous downstream execution in practice. It does not certify every template, form submission, reconnect or failure mode; synchronous local-update ACKs remain unsupported.
@@ -31,15 +31,24 @@ class DingTalkCardTrigger {
31
31
  type: 'notice',
32
32
  default: '',
33
33
  },
34
+ {
35
+ displayName: 'Include Raw Callback Data',
36
+ name: 'includeRawData',
37
+ type: 'boolean',
38
+ default: true,
39
+ description: 'Whether to include the original callback serialization in rawData. Disabling reduces duplicate raw serialization but does not remove sensitive callback content.',
40
+ },
34
41
  ],
35
42
  };
36
43
  this.methods = new DingTalkCard_node_1.DingTalkCard().methods;
37
44
  }
38
45
  async trigger() {
46
+ var _a, _b;
39
47
  const credential = await this.getCredentials('dingTalkCardApi');
40
48
  try {
41
49
  const stream = (0, stream_1.createCardStream)(credential.appKey, credential.appSecret, {
42
50
  request: (options) => this.helpers.httpRequest(options),
51
+ includeRawData: ((_b = (_a = this.getNodeParameter) === null || _a === void 0 ? void 0 : _a.call(this, 'includeRawData', true)) !== null && _b !== void 0 ? _b : true),
43
52
  emit: (item) => this.emit([[{ json: item }]]),
44
53
  warn: (message) => this.logger.warn(message),
45
54
  });
@@ -16,8 +16,8 @@ function parse(value) {
16
16
  return value;
17
17
  }
18
18
  }
19
- function normalizeCallback(frame, receivedAt = new Date().toISOString()) {
20
- var _a, _b, _c, _d, _e, _f;
19
+ function normalizeCallback(frame, receivedAt = new Date().toISOString(), includeRawData = true) {
20
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j;
21
21
  const headers = (0, transport_1.object)(frame.headers) ? frame.headers : {};
22
22
  const data = parse(frame.data);
23
23
  const body = (0, transport_1.object)(data) ? data : {};
@@ -31,16 +31,68 @@ function normalizeCallback(frame, receivedAt = new Date().toISOString()) {
31
31
  messageId: headers.messageId,
32
32
  receivedAt,
33
33
  data: data !== null && data !== void 0 ? data : null,
34
- rawData: (_b = frame.data) !== null && _b !== void 0 ? _b : null,
35
34
  };
35
+ if (includeRawData)
36
+ result.rawData = (_b = frame.data) !== null && _b !== void 0 ? _b : null;
36
37
  if ((0, transport_1.object)(content))
37
38
  result.content = content;
38
- const privateData = parse((_c = body.cardPrivateData) !== null && _c !== void 0 ? _c : details.cardPrivateData);
39
+ const directPrivate = (_c = body.cardPrivateData) !== null && _c !== void 0 ? _c : details.cardPrivateData;
40
+ const officialAction = (_d = body.cardActionData) !== null && _d !== void 0 ? _d : details.cardActionData;
41
+ const officialPrivate = (0, transport_1.object)(officialAction) ? officialAction.cardPrivateData : undefined;
42
+ const privateData = parse(directPrivate !== null && directPrivate !== void 0 ? directPrivate : officialPrivate);
39
43
  if (privateData !== undefined)
40
44
  result.cardPrivateData = privateData;
41
- const params = (_e = (_d = body.params) !== null && _d !== void 0 ? _d : details.params) !== null && _e !== void 0 ? _e : ((0, transport_1.object)(privateData) ? privateData.params : undefined);
45
+ const params = (_f = (_e = body.params) !== null && _e !== void 0 ? _e : details.params) !== null && _f !== void 0 ? _f : ((0, transport_1.object)(privateData) ? privateData.params : undefined);
42
46
  if (params !== undefined)
43
47
  result.params = parse(params);
48
+ const supplied = (key) => {
49
+ if (Object.hasOwn(body, key))
50
+ return body[key];
51
+ if (Object.hasOwn(details, key))
52
+ return details[key];
53
+ return undefined;
54
+ };
55
+ const selectedPrivate = privateData;
56
+ const normalizedInteraction = {};
57
+ const interactionType = (_g = body.type) !== null && _g !== void 0 ? _g : details.type;
58
+ if (typeof interactionType === 'string')
59
+ normalizedInteraction.type = interactionType;
60
+ if ((0, transport_1.object)(selectedPrivate) && Array.isArray(selectedPrivate.actionIds) && selectedPrivate.actionIds.every((id) => typeof id === 'string'))
61
+ normalizedInteraction.actionIds = selectedPrivate.actionIds;
62
+ if (params !== undefined)
63
+ normalizedInteraction.params = parse(params);
64
+ const value = (_h = body.value) !== null && _h !== void 0 ? _h : details.value;
65
+ if (value !== undefined)
66
+ normalizedInteraction.value = parse(value);
67
+ const actor = {};
68
+ for (const key of ['userId', 'userIdType', 'openId', 'unionId', 'operatorId', 'operatorUserId']) {
69
+ const value = supplied(key);
70
+ if (value !== undefined)
71
+ actor[key] = value;
72
+ }
73
+ const card = {};
74
+ const outTrackId = supplied('outTrackId');
75
+ if (outTrackId !== undefined)
76
+ card.outTrackId = outTrackId;
77
+ const conversation = {};
78
+ for (const key of ['spaceId', 'spaceType']) {
79
+ const value = supplied(key);
80
+ if (value !== undefined)
81
+ conversation[key] = value;
82
+ }
83
+ const correlation = {};
84
+ if (typeof headers.messageId === 'string' && headers.messageId)
85
+ correlation.messageId = headers.messageId;
86
+ if (headers.topic === exports.CARD_TOPIC)
87
+ correlation.topic = headers.topic;
88
+ const normalized = { schemaVersion: '1', interaction: normalizedInteraction, actor, card, conversation, correlation };
89
+ const eventTime = headers.time;
90
+ if ((typeof eventTime === 'number' || (typeof eventTime === 'string' && eventTime.trim() !== '')) && Number.isFinite(Number(eventTime))) {
91
+ const date = new Date(Number(eventTime));
92
+ if (Number.isFinite(date.getTime()))
93
+ normalized.eventTime = date.toISOString();
94
+ }
95
+ result.normalized = normalized;
44
96
  for (const key of [
45
97
  'outTrackId',
46
98
  'userId',
@@ -50,7 +102,7 @@ function normalizeCallback(frame, receivedAt = new Date().toISOString()) {
50
102
  'operatorId',
51
103
  'operatorUserId',
52
104
  ]) {
53
- const value = (_f = body[key]) !== null && _f !== void 0 ? _f : details[key];
105
+ const value = (_j = body[key]) !== null && _j !== void 0 ? _j : details[key];
54
106
  if (value !== undefined)
55
107
  result[key] = value;
56
108
  }
@@ -184,7 +236,7 @@ function createCardStream(clientId, clientSecret, deps) {
184
236
  else if (frame.type === 'CALLBACK' && topic === exports.CARD_TOPIC) {
185
237
  acknowledge(current, messageId, {});
186
238
  attempts = 0;
187
- deps.emit(normalizeCallback(frame));
239
+ deps.emit(normalizeCallback(frame, new Date().toISOString(), deps.includeRawData !== false));
188
240
  }
189
241
  }
190
242
  catch {
package/docs/API.md CHANGED
@@ -38,7 +38,7 @@ Outbound node errors use a normalized safe detail object: `code`, `category`, `r
38
38
 
39
39
  Auth cache is bounded and process-local. Workers/restarts can fetch additional tokens. Explicit recognized invalid-token codes permit one auth refresh/replay; other errors never automatically replay writes. There is no distributed retry/idempotency database. The v0.2.0-beta.1 prerelease adds the separate Card Trigger transport below.
40
40
 
41
- # Tooling decision
41
+ ## Tooling decision
42
42
 
43
43
  The [official n8n starter](https://github.com/n8n-io/n8n-nodes-starter) and [CLI guide](https://docs.n8n.io/connect/create-nodes/build-your-node/using-the-n8n-node-tool.md) were checked. The package adopts the official CLI, scripts, strict node registration, peer dependency and ESLint conventions in place. Programmatic execution serves the required centralized auth/partial-failure/error behavior; payload construction is pure and tested. There are no starter product nodes.
44
44
 
@@ -63,3 +63,6 @@ For exact-type/topic CALLBACK envelopes with a message ID, first send `{code:200
63
63
  Form Create & Deliver adds `callbackType:"STREAM"` only when Enable Stream Callbacks is true; default/false omits callbackType. Whole-body JSON remains passthrough. The listener must use the same Client ID as creation; DingTalk’s card examples require one Stream service per Client ID. The process-local lock cannot coordinate other processes/services. No HTTP callback mode, synchronous local-update ACK, persistent deduplication or downstream-dependent response exists in this prerelease. Follow ACK with normal asynchronous Update calls as needed.
64
64
 
65
65
  Security decision: avoid the upstream SDK due the previously verified ticket-log risk; do not import/copy its implementation or patch global console. Fixed generic diagnostics intentionally discard connection/gateway errors even if they contain apparently useful codes. Native construction, handshake errors and pending/active shutdown are covered with sentinel secrets and real local TLS subprocess tests. The tracked-timer lint exception exists because pinned n8n-workflow 2.44.2 has no exported `sleepWithAbort`; plain `sleep` cannot cancel these lifecycle timers.
66
+ ## Trigger callback normalization
67
+
68
+ The Trigger preserves its existing top-level callback fields and adds the versioned `normalized` envelope. Existing workflows require no migration to keep using those fields. See the [v1 interaction contract](INTERACTIONS.md). The **Include Raw Callback Data** option defaults to true; disabling it removes only top-level `rawData` and reduces duplicate serialization, not sensitive content.
@@ -0,0 +1,11 @@
1
+ # Interaction contract v1
2
+
3
+ Every valid DingTalk card `CALLBACK` item retains its existing top-level fields (`type`, `specVersion`, `headers`, `topic`, `messageId`, `receivedAt`, `data`, `rawData` by default, parsed `content`, `cardPrivateData`, `params`, and extracted identifiers) and adds `normalized`. Existing top-level fields remain supported; no migration is required for them.
4
+
5
+ `normalized.schemaVersion` is the string `"1"`. `interaction` may contain the inner card callback business `type` when it is a string (root `data.type`, then `content.type`; this is not the outer Stream envelope type), validated string-array `actionIds`, parsed `params`, and parsed `value` (root `data.value`, then `content.value`). `actor` contains supplied `userId`, `userIdType`, `openId`, `unionId`, `operatorId`, and `operatorUserId`; `card` contains supplied `outTrackId`; `conversation` contains supplied `spaceId` and `spaceType`. Values are preserved as supplied. No identity equivalence or input type is inferred. `correlation` contains the validated Stream `messageId` and exact callback topic. `eventTime` is present only for a valid finite Unix timestamp in milliseconds in `headers.time`, represented as ISO-8601. `receivedAt` remains local receipt time.
6
+
7
+ Callback extraction preserves precedence: direct `cardPrivateData` at root then content takes precedence over SDK `cardActionData.cardPrivateData` at root then content. `params` precedence remains root, content, then selected private data. String JSON parsing and malformed JSON preservation remain unchanged. Unknown params are retained. Form and selection inputs are unverified and deferred; generic `params` do not classify submitted values.
8
+
9
+ The Trigger option **Include Raw Callback Data** defaults to true. When false, only top-level `rawData` is omitted; `data` and other fields remain. This reduces duplicate raw serialization but does not remove sensitive callback content. The live-verified interaction claim for this milestone is limited to the existing request-button/action callback path.
10
+
11
+ The Stream receipt ACK is sent before item normalization/emission. Downstream workflow execution remains asynchronous. This provides no exactly-once or durable deduplication guarantee.
package/docs/ROADMAP.md CHANGED
@@ -4,7 +4,7 @@ This roadmap is subordinate to the project's [design baseline](DESIGN.md), which
4
4
 
5
5
  This roadmap starts from the published **v0.4.0** stable state. It describes intended milestones, not released capabilities. The current release and its tested limits remain documented in the [README](../README.md), [API contracts](API.md), and [verification record](VERIFICATION.md). Dates are omitted; milestones are semantic versions, not calendar commitments.
6
6
 
7
- The repository package version is **0.4.0**. npm `latest` resolves to `0.4.0`; `beta` remains `0.4.0-beta.2`. The v0.4.0 Presentation Contract & Template Kit is implemented and production acceptance is complete. The package ships no DingTalk templates. See [beta.2 production acceptance](VERIFICATION.md#v040-beta2-production-regression-acceptance-2026-10-25) and [stable release verification](VERIFICATION.md#v040-stable-release).
7
+ The repository package version is **0.5.0**. npm `latest` tracks `0.5.0`; beta remains `0.5.0-beta.1`. The v0.4.0 Presentation Contract & Template Kit is implemented and production acceptance is complete. v0.5.0 promotes the beta.1 baseline without runtime changes. Its production acceptance covers only the request-button/action-callback path; Form and Selection remain unverified and deferred. See [verification](VERIFICATION.md).
8
8
 
9
9
  ## Vision and product principle
10
10
 
@@ -66,7 +66,7 @@ The implementation is a deterministic stateless adapter to the existing Form-mod
66
66
 
67
67
  **Compatibility and migration:** The contract is additive and versioned. Existing Form and whole-body JSON modes continue to work; no existing request body is silently reinterpreted. Beta.2 was published and production-installed through the supported UI. Transport, lifecycle, and Presentation acceptance are complete for the documented paths.
68
68
 
69
- ### v0.5.0 — Interaction Contract & Normalized Trigger
69
+ ### v0.5.0 — Interaction Contract & Normalized Trigger (beta.1 production acceptance complete)
70
70
 
71
71
  **Objective:** Give workflows a stable, safe representation of card actions.
72
72
 
@@ -84,6 +84,8 @@ The implementation is a deterministic stateless adapter to the existing Form-mod
84
84
 
85
85
  **Compatibility and migration:** Add normalized fields without removing or renaming current fields such as `params`, `outTrackId`, or `rawData`. Publish a migration note before any breaking envelope change.
86
86
 
87
+ The beta.1 implementation is specified in [INTERACTIONS.md](INTERACTIONS.md), with phases and acceptance criteria in [V0.5_PLAN.md](V0.5_PLAN.md). Production acceptance passed for the existing request-button/action callback path, including compatibility with legacy downstream expressions. Form and selection remain unverified and deferred. Beta.1 is eligible for stable promotion; see [verification](VERIFICATION.md#v050-beta1-production-acceptance--2026-10-25).
88
+
87
89
  ### v0.6.0 — Controlled A2UI Runtime
88
90
 
89
91
  **Objective:** Render validated presentation/action descriptors through an approved set of DingTalk card primitives and templates.
@@ -0,0 +1,20 @@
1
+ # v0.5.0-beta.1 plan
2
+
3
+ ## Phase 1: additive normalized envelope
4
+ - Add schema version 1 alongside existing top-level callback fields.
5
+ - Verify extraction precedence, optional fields, timestamps, and raw-data control.
6
+ - Success: regression tests pass and existing consumers need no migration.
7
+
8
+ ## Phase 2: contract and examples
9
+ - Publish the normative interaction contract and placeholder-safe callback example.
10
+ - Record that request-button/action is the only live-verified path; form/selection remain deferred.
11
+ - Success: docs make no unsupported identity or typed-input claims.
12
+
13
+ ## Phase 3: beta release candidate
14
+ - Set package metadata to 0.5.0-beta.1 and permit only v0.5.0-beta.* on the beta channel.
15
+ - Success: local quality gates, package verification, release-ref simulation, and artifact inspection pass. Beta publication must leave npm latest at 0.4.0.
16
+
17
+ ## Before stable
18
+ - Complete live acceptance of the documented callback path and any additional interaction types before claiming them.
19
+ - Review privacy handling, asynchronous ACK behavior, compatibility, and migration notes.
20
+ - Stable v0.5.0 remains out of scope for this candidate.
@@ -1,5 +1,25 @@
1
1
  # Release verification record — 2026-10-24
2
2
 
3
+ ## v0.5.0-beta.1 local verification scope (historical, before production acceptance)
4
+
5
+ This candidate adds normalized callback fields beside the existing output contract. Local verification exercises the existing request-button/action callback path, normalization precedence, optional fields, timestamps, raw-data control, privacy-safe diagnostics, and ACK-before-emit ordering. Form and selection interactions have not been live-verified and remain deferred. No production n8n was touched for this candidate. Stable release still requires scoped live acceptance before expanding interaction claims.
6
+
7
+ ## v0.5.0-beta.1 public prerelease — 2026-10-25 (historical, before production acceptance)
8
+
9
+ - Annotated tag [`v0.5.0-beta.1`](https://github.com/NTLx/n8n-nodes-dingtalk-card/releases/tag/v0.5.0-beta.1) points to release commit `f95b20b25a2e51956034a6b739cd51f130c841ba`. Tag CI run [40162534352](https://github.com/NTLx/n8n-nodes-dingtalk-card/actions/runs/40162534352) passed; Trusted Publisher/OIDC publish run [40162610880](https://github.com/NTLx/n8n-nodes-dingtalk-card/actions/runs/40162610880) passed all release gates and public registry checks.
10
+ - npm public dist-tags are `beta -> 0.5.0-beta.1` and `latest -> 0.4.0`. Published package metadata reports `gitHead` `f95b20b25a2e51956034a6b739cd51f130c841ba`, 30 files, and unpacked size 204,191 bytes. `npm audit signatures` verified registry signatures for all 94 packages in an isolated install and attestations for 6 packages.
11
+ - The public SLSA provenance subject is `n8n-nodes-dingtalk-card@0.5.0-beta.1` with SHA-512 `2009bcb75cd0ec3e97885d82b3853fe711d16cf015d1fdbc3da1c5ad1cf6be232cddce6a0e16b4a9605961a54ad4df3220c0c38d7f109aa40c9c46e3b44f419f`. Provenance identifies `refs/tags/v0.5.0-beta.1`, the same release commit, `.github/workflows/publish.yml`, and publish run 40162610880 attempt 1.
12
+ - The [GitHub prerelease](https://github.com/NTLx/n8n-nodes-dingtalk-card/releases/tag/v0.5.0-beta.1) is published with one canonical npm tarball asset. `n8n-nodes-dingtalk-card-0.5.0-beta.1.tgz` is 61,780 bytes and byte-identical to the public npm tarball; both have SHA-256 `0cd7b3f39f8ab071dbc88b1b4597797dfa07170e5d926f64ea9433719ec922a6`. SHA-1 is `7a199aabed820cae64e57863bbb80e5f2b97aefa`; npm integrity is `sha512-IAm8t1zQ7D6XiF2Cs4U/5xHRbPAV0f28PaHFrRz2viMs3c5qDha0qWBZYaVK1N8yIMDDjX8QmqQMnEbjtE9Bnw==`.
13
+ - This is an additive normalized callback v1: existing top-level output fields remain; `rawData` defaults to true and can be omitted with the optional control; immediate ACK and asynchronous downstream handling are unchanged. At publication, only the request-button/action callback path had been live-verified; Form and Selection remained unverified and deferred, and production beta acceptance was pending. No production n8n was changed during release. The pending status is superseded by the production acceptance below.
14
+
15
+ ## v0.5.0-beta.1 production acceptance — 2026-10-25
16
+
17
+ Production n8n loaded the v0.5 Trigger schema, including optional `includeRawData` with default `true`. For the scoped live check, the existing legacy Interaction E2E workflow had Trigger parameters `{}` and was published temporarily. A new request-button card was delivered successfully. One real button click in Mac DingTalk produced a successful Trigger execution and downstream card update.
18
+
19
+ The callback output had `normalized.schemaVersion="1"` and `interaction.type="actionCallback"`; `actionIds`, `params`, and `value` were present and correct. Actor `userId` and `userIdType` were populated only from source facts. Card `outTrackId`, conversation `spaceId` and `spaceType`, and correlation `messageId` and `topic` were present. `eventTime` was correctly converted from the Stream header `time` millisecond epoch. Legacy top-level `params`, `outTrackId`, and `rawData` remained present. Existing downstream expressions using `messageId`, `params`, and `outTrackId` continued to work and updated the card. The temporary listener was unpublished immediately after verification.
20
+
21
+ This completes beta.1 production acceptance for the request-button/action-callback path and makes beta.1 eligible for stable promotion. Form and Selection interactions remain unverified and deferred; no live claim is made for them. This acceptance does not expand other template, reconnect, or failure-mode claims. No private IDs or secrets are recorded.
22
+
3
23
  ## v0.4.0-beta.2 production regression acceptance — 2026-10-25
4
24
 
5
25
  Production n8n was upgraded to `n8n-nodes-dingtalk-card@0.4.0-beta.2` through the supported Community Nodes lifecycle. A true Presentation-mode status card rendered correctly in Mac DingTalk with no workflow-supplied `flowStatus` and no JSON request body. This demonstrates that beta.2 automatically supplies the AI-card completed-state host metadata. The earlier visual probe using the final AI-card template showed all 13 Presentation fields, including `summary`, through one BaseText path.
@@ -10,7 +30,21 @@ Beta.2 production acceptance is complete and forms the exact functional baseline
10
30
 
11
31
  ## v0.4.0 stable release
12
32
 
13
- Stable promotion changes package and release metadata only. The Presentation implementation is unchanged from the production-accepted v0.4.0-beta.2 baseline. Release gates and public artifact evidence will be recorded here after publication. Beta remains on `0.4.0-beta.2`; stable publication uses the existing Trusted Publisher/OIDC workflow and `latest` dist-tag.
33
+ Stable promotion changes package and release metadata only. The Presentation implementation is unchanged from the production-accepted v0.4.0-beta.2 baseline.
34
+
35
+ - Release commit `019b52ddb89611b32bb0c73b6390b20eeede5c37`; annotated tag `v0.4.0` points to that commit. Main CI run [40161106076](https://github.com/NTLx/n8n-nodes-dingtalk-card/actions/runs/40161106076) and tag CI run [40161166710](https://github.com/NTLx/n8n-nodes-dingtalk-card/actions/runs/40161166710) passed the complete Node 24 gate set. The Trusted Publisher/OIDC publish run [40161166763](https://github.com/NTLx/n8n-nodes-dingtalk-card/actions/runs/40161166763) also passed install, lint, typecheck, build, 60 tests, package verification, production audit, release-ref policy, npm dist-tag and public package verification.
36
+ - Public npm dist-tags are `latest -> 0.4.0` and `beta -> 0.4.0-beta.2`. Public metadata reports version `0.4.0`, `gitHead` `019b52ddb89611b32bb0c73b6390b20eeede5c37`, tarball `https://registry.npmjs.org/n8n-nodes-dingtalk-card/-/n8n-nodes-dingtalk-card-0.4.0.tgz`, and 27 files. `npm audit signatures` verified the published package signature and provenance; the package had no invalid or missing signature results.
37
+ - The public SLSA provenance identifies `refs/tags/v0.4.0`, release commit `019b52ddb89611b32bb0c73b6390b20eeede5c37`, `.github/workflows/publish.yml`, and publish run `40161166763` attempt 1.
38
+ - The non-prerelease [GitHub Release v0.4.0](https://github.com/NTLx/n8n-nodes-dingtalk-card/releases/tag/v0.4.0) is published and contains exactly one asset, `n8n-nodes-dingtalk-card-0.4.0.tgz`. Its 58,405 bytes match the public npm tarball; GitHub's asset digest matches the locally computed SHA-256.
39
+ - Canonical tarball SHA-256: `11dfb9f75af58766196c7f2dbaea043267e2cc346cd46f15e961124e0cb6eb87`; SHA-1: `bdb23cf0e05fe77cc02099fa1e9b8800e7aaf888`; npm integrity: `sha512-3L4Pg2HabTP+FeSPJWjfMiv6SZ6yPdUZxitJMopIHomweS0/Lchx+JoOoGqgXEwrdTGYz+oQl28iLqmIff9vhQ==`.
40
+
41
+ The local clean install, lint, typecheck, build, 60 tests, package verification, production audit (0 findings), release-ref self-test and `git diff --check` all passed. No production n8n installation was changed during this release task.
42
+
43
+ ## v0.4.0 stable production post-install acceptance — 2026-10-25
44
+
45
+ After the stable release, production n8n reported the installed `n8n-nodes-dingtalk-card` package metadata as exactly **0.4.0**. Production n8n and its external runners were healthy on **2.44.6**; `/healthz` and `/healthz/readiness` both returned HTTP 200. The live node schema continued to expose `cardDataMode=presentation` and `presentationDescriptor`.
46
+
47
+ A temporary true Presentation-mode status Create & Deliver smoke workflow succeeded without workflow-supplied `flowStatus`. The n8n execution succeeded, and the DingTalk response had top-level `success=true` and `deliverResults[].success=true`. The temporary workflow was archived. This closes the stable production install and status Create & Deliver smoke acceptance; it does not extend the documented template or client-rendering claims. No private template, group, card, workflow, execution, credential, or other private identifiers are recorded.
14
48
 
15
49
  ## v0.4.0-beta.2 real Mac DingTalk visual acceptance — 2026-10-25
16
50
 
@@ -0,0 +1,19 @@
1
+ {
2
+ "normalized": {
3
+ "schemaVersion": "1",
4
+ "interaction": {
5
+ "type": "actionCallback",
6
+ "actionIds": ["<action-id>"],
7
+ "params": { "<parameter-name>": "<submitted-value>" }
8
+ },
9
+ "actor": { "userId": "<user-id>" },
10
+ "card": { "outTrackId": "<caller-generated-correlation-id>" },
11
+ "conversation": { "spaceId": "<conversation-id>" },
12
+ "correlation": {
13
+ "messageId": "<stream-message-id>",
14
+ "topic": "/v1.0/card/instances/callback"
15
+ },
16
+ "eventTime": "<ISO-8601-event-time>"
17
+ },
18
+ "receivedAt": "<ISO-8601-local-receipt-time>"
19
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "n8n-nodes-dingtalk-card",
3
- "version": "0.4.0",
3
+ "version": "0.5.0",
4
4
  "description": "DingTalk Card Platform lifecycle nodes for n8n",
5
5
  "license": "MIT",
6
6
  "homepage": "https://github.com/NTLx/n8n-nodes-dingtalk-card#readme",