@openclaw/nextcloud-talk 2026.10.10-beta.5 → 2026.11.5-beta.1

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.
Files changed (64) hide show
  1. package/dist/.setup/api-BvrRSilb.mjs +2 -0
  2. package/dist/.setup/{channel-B8-CvvK1.mjs → channel-BA1-OoqO.mjs} +1724 -994
  3. package/dist/.setup/{doctor-contract-DwH950tH.mjs → doctor-contract-CkWQa5uZ.mjs} +6 -12
  4. package/dist/.setup/outbound-media-CpFe1Xgz.mjs +303 -0
  5. package/dist/.setup/reply-BEkv387l.mjs +64 -0
  6. package/dist/.setup/{runtime-api-DVkVOUSo.mjs → runtime-api-CGy_KpdV.mjs} +2 -4
  7. package/dist/.setup/{secret-contract-api-DoyAH9bS.mjs → secret-contract-api-QMihLdr1.mjs} +1 -1
  8. package/dist/.setup/secret-contract-yjCLewtg.mjs +19 -0
  9. package/dist/.source-module-urls/3332e832383d54fca83a3cfe8961ecdecf361c1eec0972c99f00a876d9481d98.json +1 -1
  10. package/dist/api.js +1 -1
  11. package/dist/channel-plugin-api.js +1 -1
  12. package/dist/configured-state.js +3 -7
  13. package/dist/doctor-contract-api.js +1 -1
  14. package/dist/index.js +1 -2
  15. package/dist/runtime-api.js +1 -1
  16. package/dist/secret-contract-api.js +1 -1
  17. package/dist/setup-entry.js +3 -4
  18. package/node_modules/saxes/README.md +323 -0
  19. package/node_modules/saxes/node_modules/xmlchars/LICENSE +18 -0
  20. package/node_modules/saxes/node_modules/xmlchars/README.md +33 -0
  21. package/node_modules/saxes/node_modules/xmlchars/package.json +51 -0
  22. package/node_modules/saxes/node_modules/xmlchars/xml/1.0/ed4.d.ts +31 -0
  23. package/node_modules/saxes/node_modules/xmlchars/xml/1.0/ed4.js +44 -0
  24. package/node_modules/saxes/node_modules/xmlchars/xml/1.0/ed4.js.map +1 -0
  25. package/node_modules/saxes/node_modules/xmlchars/xml/1.0/ed5.d.ts +51 -0
  26. package/node_modules/saxes/node_modules/xmlchars/xml/1.0/ed5.js +105 -0
  27. package/node_modules/saxes/node_modules/xmlchars/xml/1.0/ed5.js.map +1 -0
  28. package/node_modules/saxes/node_modules/xmlchars/xml/1.1/ed2.d.ts +73 -0
  29. package/node_modules/saxes/node_modules/xmlchars/xml/1.1/ed2.js +145 -0
  30. package/node_modules/saxes/node_modules/xmlchars/xml/1.1/ed2.js.map +1 -0
  31. package/node_modules/saxes/node_modules/xmlchars/xmlchars.d.ts +170 -0
  32. package/node_modules/saxes/node_modules/xmlchars/xmlchars.js +191 -0
  33. package/node_modules/saxes/node_modules/xmlchars/xmlchars.js.map +1 -0
  34. package/node_modules/saxes/node_modules/xmlchars/xmlns/1.0/ed3.d.ts +28 -0
  35. package/node_modules/saxes/node_modules/xmlchars/xmlns/1.0/ed3.js +65 -0
  36. package/node_modules/saxes/node_modules/xmlchars/xmlns/1.0/ed3.js.map +1 -0
  37. package/node_modules/saxes/package.json +71 -0
  38. package/node_modules/saxes/saxes.d.ts +635 -0
  39. package/node_modules/saxes/saxes.js +2053 -0
  40. package/node_modules/saxes/saxes.js.map +1 -0
  41. package/node_modules/zod/package.json +1 -1
  42. package/node_modules/zod/src/v4/classic/tests/array.test.ts +27 -0
  43. package/node_modules/zod/src/v4/classic/tests/map.test.ts +7 -0
  44. package/node_modules/zod/src/v4/classic/tests/set.test.ts +6 -0
  45. package/node_modules/zod/src/v4/core/compile.ts +9 -0
  46. package/node_modules/zod/src/v4/core/schemas.ts +35 -1
  47. package/node_modules/zod/src/v4/core/util.ts +13 -0
  48. package/node_modules/zod/src/v4/core/versions.ts +1 -1
  49. package/node_modules/zod/v4/core/compile.cjs +8 -0
  50. package/node_modules/zod/v4/core/compile.js +8 -0
  51. package/node_modules/zod/v4/core/schemas.cjs +30 -0
  52. package/node_modules/zod/v4/core/schemas.d.cts +3 -1
  53. package/node_modules/zod/v4/core/schemas.d.ts +3 -1
  54. package/node_modules/zod/v4/core/schemas.js +30 -0
  55. package/node_modules/zod/v4/core/util.cjs +15 -0
  56. package/node_modules/zod/v4/core/util.d.cts +2 -0
  57. package/node_modules/zod/v4/core/util.d.ts +2 -0
  58. package/node_modules/zod/v4/core/util.js +14 -0
  59. package/node_modules/zod/v4/core/versions.cjs +1 -1
  60. package/node_modules/zod/v4/core/versions.js +1 -1
  61. package/openclaw.plugin.json +23 -1
  62. package/package.json +8 -6
  63. package/dist/.setup/api-BmNQoi-o.mjs +0 -2
  64. package/dist/.setup/secret-contract-Bvm0PmP3.mjs +0 -15
@@ -1,5 +1,5 @@
1
1
  import { hasConfiguredNextcloudTalkChannelState, listNextcloudTalkAccountIds, mergeNextcloudTalkAccountConfig } from "../configured-state.js";
2
- //#region \0rolldown/runtime.js
2
+ // \0rolldown/runtime.js
3
3
  var __defProp = Object.defineProperty;
4
4
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
5
  var __getOwnPropNames = Object.getOwnPropertyNames;
@@ -24,8 +24,7 @@ var __copyProps = (to, from, except, desc) => {
24
24
  return to;
25
25
  };
26
26
  var __reExport = (target, mod, secondTarget) => (__copyProps(target, mod, "default"), secondTarget && __copyProps(secondTarget, mod, "default"));
27
- //#endregion
28
- //#region packages/normalization-core/src/record-coerce.ts
27
+ // packages/normalization-core/src/record-coerce.ts
29
28
  /** Type guard for non-array object records at browser-safe boundaries. */
30
29
  function isRecord(value) {
31
30
  return value !== null && typeof value === "object" && !Array.isArray(value);
@@ -34,8 +33,7 @@ function isRecord(value) {
34
33
  function asNullableRecord(value) {
35
34
  return isRecord(value) ? value : null;
36
35
  }
37
- //#endregion
38
- //#region src/config/channel-config-normalization.ts
36
+ // src/config/channel-config-normalization.ts
39
37
  /** Applies one channel-specific doctor migration to every object-shaped account. */
40
38
  function normalizeChannelAccounts(params) {
41
39
  const rawAccounts = asNullableRecord(params.entry.accounts);
@@ -111,8 +109,7 @@ function normalizeChannelConfigEntries(params) {
111
109
  changes
112
110
  };
113
111
  }
114
- //#endregion
115
- //#region src/plugin-sdk/legacy-webhook-listener-migration.ts
112
+ // src/plugin-sdk/legacy-webhook-listener-migration.ts
116
113
  /** Preserve explicitly configured webhook listeners while moving ingress onto Gateway routes. */
117
114
  function createLegacyWebhookListenerDoctorContract(params) {
118
115
  const portKey = params.portKey ?? "webhookPort";
@@ -182,13 +179,11 @@ function createLegacyWebhookListenerDoctorContract(params) {
182
179
  }
183
180
  };
184
181
  }
185
- //#endregion
186
- //#region \0openclaw:bundled-sdk:openclaw/plugin-sdk/runtime-doctor-migrations
182
+ // \0openclaw:bundled-sdk:openclaw/plugin-sdk/runtime-doctor-migrations
187
183
  var runtime_doctor_migrations_exports = /* @__PURE__ */ __exportAll({ createLegacyWebhookListenerDoctorContract: () => createLegacyWebhookListenerDoctorContract });
188
184
  import * as import_openclaw_plugin_sdk_runtime_doctor_migrations from "openclaw/plugin-sdk/runtime-doctor-migrations";
189
185
  __reExport(runtime_doctor_migrations_exports, import_openclaw_plugin_sdk_runtime_doctor_migrations);
190
- //#endregion
191
- //#region extensions/nextcloud-talk/src/doctor-contract.ts
186
+ // extensions/nextcloud-talk/src/doctor-contract.ts
192
187
  const webhookContract = createLegacyWebhookListenerDoctorContract({
193
188
  channelKey: "nextcloud-talk",
194
189
  defaultHost: "0.0.0.0",
@@ -220,5 +215,4 @@ function normalizeCompatibilityConfig({ cfg }) {
220
215
  historicalWebhookAccountIds: webhook.historicalWebhookAccountIds
221
216
  };
222
217
  }
223
- //#endregion
224
218
  export { __exportAll as a, normalizeHistoricalWebhookConfig as i, legacyConfigRules as n, __reExport as o, normalizeCompatibilityConfig as r, historicalWebhookListener as t };
@@ -0,0 +1,303 @@
1
+ import { a as resolveNextcloudTalkAccount, i as releaseNextcloudTalkGuardedResponse, n as stripNextcloudTalkTargetPrefix, o as resolveNextcloudTalkApiCredentialsResult, r as parseWebDavFileId } from "./channel-BA1-OoqO.mjs";
2
+ import { l as getOptionalNextcloudTalkRuntime, r as fetchWithSsrFGuard } from "./runtime-api-CGy_KpdV.mjs";
3
+ import { resolveChannelMediaMaxBytes } from "openclaw/plugin-sdk/account-helpers";
4
+ import { createMessageReceiptFromOutboundResults, isRecentOutboundMessageIdentity, recordOutboundMessageIdentity } from "openclaw/plugin-sdk/channel-outbound";
5
+ import { isRecord } from "openclaw/plugin-sdk/string-coerce-runtime";
6
+ import { convertMarkdownTables } from "openclaw/plugin-sdk/text-chunking";
7
+ import { readProviderJsonResponse, readProviderTextResponse } from "openclaw/plugin-sdk/provider-http";
8
+ import { ssrfPolicyFromPrivateNetworkOptIn } from "openclaw/plugin-sdk/ssrf-runtime";
9
+ import path from "node:path";
10
+ import { sanitizeUntrustedFileName } from "openclaw/plugin-sdk/security-runtime";
11
+ import { truncateUtf8Prefix } from "openclaw/plugin-sdk/text-utility-runtime";
12
+ import { resolveMarkdownTableMode } from "openclaw/plugin-sdk/markdown-table-runtime";
13
+ import { createHmac, randomUUID } from "node:crypto";
14
+ import { loadOutboundMediaFromUrl } from "openclaw/plugin-sdk/outbound-media";
15
+ // extensions/nextcloud-talk/src/outbound-media.ts
16
+ const OUTBOUND_FILE_PREFIX = /^openclaw-([0-9a-f]{8}(?:-[0-9a-f]{4}){3}-[0-9a-f]{12})-/u;
17
+ const FILE_ID_REQUEST = "<d:propfind xmlns:d=\"DAV:\" xmlns:oc=\"http://owncloud.org/ns\"><d:prop><oc:fileid/></d:prop></d:propfind>";
18
+ function createFileClient(account) {
19
+ const credentials = resolveNextcloudTalkApiCredentialsResult(account.config);
20
+ if (credentials.status !== "available") throw new Error("Nextcloud Talk attachments require available apiUser and apiPassword/apiPasswordFile credentials.");
21
+ const base = new URL(account.baseUrl);
22
+ if (!/^https?:$/u.test(base.protocol) || base.username || base.password || base.search || base.hash) throw new Error("Nextcloud Talk attachment baseUrl must be an HTTP(S) URL without credentials, query, or fragment.");
23
+ const authorization = `Basic ${Buffer.from(`${credentials.value.apiUser}:${credentials.value.apiPassword}`).toString("base64")}`;
24
+ const url = (pathname) => `${base.origin}${base.pathname.replace(/\/+$/u, "")}${pathname}`;
25
+ async function request(pathname, init, read, options = {}) {
26
+ options.signal?.throwIfAborted();
27
+ const headers = new Headers(init.headers);
28
+ headers.set("Authorization", authorization);
29
+ headers.set("OCS-APIRequest", "true");
30
+ if (!headers.has("Accept")) headers.set("Accept", "application/json");
31
+ const guarded = await fetchWithSsrFGuard({
32
+ url: url(pathname),
33
+ init: {
34
+ ...init,
35
+ headers
36
+ },
37
+ maxRedirects: 0,
38
+ requireHttps: base.protocol === "https:",
39
+ policy: {
40
+ ...ssrfPolicyFromPrivateNetworkOptIn(account.config.network?.dangerouslyAllowPrivateNetwork),
41
+ hostnameAllowlist: [base.hostname]
42
+ },
43
+ timeoutMs: 12e4,
44
+ signal: options.signal,
45
+ beforeRequest: options.beforeRequest,
46
+ auditContext: "nextcloud-talk-outbound-file"
47
+ });
48
+ try {
49
+ return await read(guarded.response);
50
+ } finally {
51
+ await releaseNextcloudTalkGuardedResponse(guarded);
52
+ }
53
+ }
54
+ async function json(pathname, init, options) {
55
+ return await request(pathname, init, async (response) => {
56
+ if (!response.ok) throw new Error(`Nextcloud Talk attachment API failed (${response.status}).`);
57
+ const payload = await readProviderJsonResponse(response, "Nextcloud Talk attachment API");
58
+ if (!isRecord(payload) || !isRecord(payload.ocs)) throw new Error("Nextcloud Talk attachment API returned an invalid response.");
59
+ return payload.ocs.data;
60
+ }, options);
61
+ }
62
+ async function user(options) {
63
+ const data = await json("/ocs/v1.php/cloud/user?format=json", {}, options);
64
+ if (!isRecord(data) || typeof data.id !== "string" || !data.id || data.id === "." || data.id === ".." || data.id.includes("/") || data.id.includes("\\") || Array.from(data.id).some((character) => {
65
+ const code = character.charCodeAt(0);
66
+ return code <= 31 || code === 127;
67
+ })) throw new Error("Nextcloud Talk API account has no valid canonical user ID.");
68
+ return data.id;
69
+ }
70
+ async function history(roomToken, messageId, options) {
71
+ const query = new URLSearchParams({
72
+ lookIntoFuture: "0",
73
+ limit: messageId ? "1" : "200",
74
+ setReadMarker: "0",
75
+ noStatusUpdate: "1",
76
+ markNotificationsAsRead: "0"
77
+ });
78
+ if (messageId) {
79
+ query.set("lastKnownMessageId", messageId);
80
+ query.set("includeLastKnown", "1");
81
+ }
82
+ const data = await json(`/ocs/v2.php/apps/spreed/api/v1/chat/${encodeURIComponent(roomToken)}?${query}`, {}, options);
83
+ return Array.isArray(data) ? data : [];
84
+ }
85
+ return {
86
+ request,
87
+ json,
88
+ user,
89
+ history
90
+ };
91
+ }
92
+ function fileReference(account, roomToken, uid, fileId) {
93
+ return createHmac("sha256", account.secret).update(JSON.stringify([
94
+ "nextcloud-talk-outbound-file",
95
+ account.accountId,
96
+ roomToken,
97
+ uid,
98
+ fileId
99
+ ])).digest("hex");
100
+ }
101
+ function echoIdentity(accountId, roomToken, actor, fileId) {
102
+ return {
103
+ channel: "nextcloud-talk",
104
+ accountId,
105
+ conversationId: roomToken,
106
+ sourceId: `file:${actor.toLowerCase()}:${fileId}`
107
+ };
108
+ }
109
+ /** The bounded cache handles webhook-before-ack; exact history handles restart/backlog. */
110
+ async function isNextcloudTalkOutboundFileEcho(params) {
111
+ params.signal?.throwIfAborted();
112
+ const { account, message } = params;
113
+ const file = message.attachment;
114
+ if (!file?.fileId) return false;
115
+ if (isRecentOutboundMessageIdentity(echoIdentity(account.accountId, message.roomToken, message.senderId, file.fileId))) return true;
116
+ if (!OUTBOUND_FILE_PREFIX.test(file.name)) return false;
117
+ if (!account.secret || resolveNextcloudTalkApiCredentialsResult(account.config).status !== "available") return false;
118
+ try {
119
+ const client = createFileClient(account);
120
+ const uid = await client.user({ signal: params.signal });
121
+ if (message.senderId !== `users/${uid}`) return false;
122
+ const referenceId = fileReference(account, message.roomToken, uid, file.fileId);
123
+ const history = await client.history(message.roomToken, message.messageId, { signal: params.signal });
124
+ params.signal?.throwIfAborted();
125
+ return history.some((entry) => isRecord(entry) && String(entry.id) === message.messageId && entry.token === message.roomToken && entry.actorType === "users" && entry.actorId === uid && entry.referenceId === referenceId && isRecord(entry.messageParameters) && isRecord(entry.messageParameters.file) && String(entry.messageParameters.file.id) === file.fileId);
126
+ } catch {
127
+ params.signal?.throwIfAborted();
128
+ return false;
129
+ }
130
+ }
131
+ async function sendMediaNextcloudTalk(ctx) {
132
+ const account = resolveNextcloudTalkAccount({
133
+ cfg: ctx.cfg,
134
+ accountId: ctx.accountId
135
+ });
136
+ if (!account.enabled || !account.baseUrl || !account.secret) throw new Error("Nextcloud Talk account is disabled or not configured.");
137
+ const roomToken = stripNextcloudTalkTargetPrefix(ctx.to);
138
+ if (!roomToken) throw new Error("Room token is required for Nextcloud Talk attachments.");
139
+ if (ctx.replyToId && !/^[1-9]\d*$/u.test(ctx.replyToId)) throw new Error("Nextcloud Talk attachment replyTo must be a positive message ID.");
140
+ const client = createFileClient(account);
141
+ const assertCurrent = () => {
142
+ ctx.signal?.throwIfAborted();
143
+ ctx.assertDirectAdapterHandoff?.();
144
+ };
145
+ const options = {
146
+ signal: ctx.signal,
147
+ beforeRequest: assertCurrent
148
+ };
149
+ assertCurrent();
150
+ if (ctx.silent) {
151
+ const data = await client.json("/ocs/v2.php/cloud/capabilities?format=json", {}, options);
152
+ assertCurrent();
153
+ const spreed = isRecord(data) && isRecord(data.capabilities) ? data.capabilities.spreed : void 0;
154
+ if (!isRecord(spreed) || !Array.isArray(spreed.features) || !spreed.features.includes("media-caption")) throw new Error("Nextcloud Talk silent attachments require the server's media-caption capability. Upgrade Talk before retrying.");
155
+ }
156
+ const maxBytes = resolveChannelMediaMaxBytes({
157
+ cfg: ctx.cfg,
158
+ accountId: account.accountId,
159
+ resolveChannelLimitMb: () => account.config.mediaMaxMb
160
+ }) ?? 20971520;
161
+ const media = await loadOutboundMediaFromUrl(ctx.mediaUrl, {
162
+ maxBytes,
163
+ mediaAccess: ctx.mediaAccess,
164
+ mediaLocalRoots: ctx.mediaLocalRoots,
165
+ mediaReadFile: ctx.mediaReadFile,
166
+ optimizeImages: false
167
+ });
168
+ assertCurrent();
169
+ const asVoice = ctx.audioAsVoice === true && (media.contentType === "audio/mpeg" || media.contentType === "audio/wav");
170
+ const uid = await client.user(options);
171
+ const uploadId = randomUUID();
172
+ const prefix = `openclaw-${uploadId}-`;
173
+ const filename = sanitizeUntrustedFileName(media.fileName ?? "attachment.bin", "attachment.bin");
174
+ const nameBudget = 250 - Buffer.byteLength(prefix);
175
+ const extension = truncateUtf8Prefix(path.extname(filename), nameBudget - 4);
176
+ const stem = truncateUtf8Prefix(filename.slice(0, filename.length - path.extname(filename).length), nameBudget - Buffer.byteLength(extension));
177
+ const uploadFolderPath = `/OpenClaw/openclaw-${uploadId}`;
178
+ const filePath = `${uploadFolderPath}/${prefix}${stem}${extension}`;
179
+ const davRoot = `/remote.php/dav/files/${encodeURIComponent(uid)}`;
180
+ const uploadFolder = `${davRoot}${uploadFolderPath}`;
181
+ const davPath = `${davRoot}${filePath.split("/").map(encodeURIComponent).join("/")}`;
182
+ let uploadFolderOwned = false;
183
+ let publicationAttempted = false;
184
+ try {
185
+ await client.request(`${davRoot}/OpenClaw`, { method: "MKCOL" }, async (response) => {
186
+ if (response.status !== 201 && response.status !== 405) throw new Error(`Nextcloud Talk attachment folder creation failed (${response.status}).`);
187
+ }, options);
188
+ await client.request(uploadFolder, { method: "MKCOL" }, async (response) => {
189
+ if (response.status !== 201) throw new Error(`Nextcloud Talk private upload folder creation failed (${response.status}).`);
190
+ uploadFolderOwned = true;
191
+ }, options);
192
+ await client.request(davPath, {
193
+ method: "PUT",
194
+ headers: {
195
+ "If-None-Match": "*",
196
+ "Content-Type": media.contentType ?? "application/octet-stream"
197
+ },
198
+ body: new Uint8Array(media.buffer)
199
+ }, async (response) => {
200
+ if (response.status !== 201) {
201
+ if (response.status === 412) uploadFolderOwned = false;
202
+ const recovery = response.status === 401 ? "Check apiUser and update its app password (apiPassword/apiPasswordFile) before retrying." : response.status === 507 ? "Free Files storage or increase the API user's quota before retrying." : "Check Nextcloud server logs and the API user's Files write access.";
203
+ throw new Error(`Nextcloud Talk attachment upload failed (${response.status}). ${recovery}`);
204
+ }
205
+ }, options);
206
+ const fileId = await client.request(davPath, {
207
+ method: "PROPFIND",
208
+ headers: {
209
+ Depth: "0",
210
+ "Content-Type": "application/xml"
211
+ },
212
+ body: FILE_ID_REQUEST
213
+ }, async (response) => {
214
+ if (response.status !== 207) throw new Error("Nextcloud Talk uploaded file identity unavailable.");
215
+ const id = parseWebDavFileId(await readProviderTextResponse(response, "Nextcloud Talk uploaded file identity", { maxBytes: 65536 }));
216
+ if (!id) throw new Error("Nextcloud Talk uploaded file identity invalid.");
217
+ return id;
218
+ }, options);
219
+ const referenceId = fileReference(account, roomToken, uid, fileId);
220
+ const caption = convertMarkdownTables(ctx.text.trim(), resolveMarkdownTableMode({
221
+ cfg: ctx.cfg,
222
+ channel: "nextcloud-talk",
223
+ accountId: account.accountId
224
+ }));
225
+ const body = new URLSearchParams({
226
+ path: filePath,
227
+ shareType: "10",
228
+ shareWith: roomToken,
229
+ permissions: "1",
230
+ referenceId,
231
+ talkMetaData: JSON.stringify({
232
+ caption,
233
+ ...asVoice ? { messageType: "voice-message" } : {},
234
+ ...ctx.silent ? { silent: true } : {},
235
+ ...ctx.replyToId ? { replyTo: Number(ctx.replyToId) } : {}
236
+ })
237
+ });
238
+ await ctx.onPlatformSendDispatch?.();
239
+ assertCurrent();
240
+ recordOutboundMessageIdentity(echoIdentity(account.accountId, roomToken, `users/${uid}`, fileId));
241
+ let publicationError;
242
+ try {
243
+ await client.json("/ocs/v2.php/apps/files_sharing/api/v1/shares?format=json", {
244
+ method: "POST",
245
+ headers: { "Content-Type": "application/x-www-form-urlencoded" },
246
+ body
247
+ }, {
248
+ ...options,
249
+ beforeRequest: () => {
250
+ assertCurrent();
251
+ publicationAttempted = true;
252
+ }
253
+ });
254
+ } catch (error) {
255
+ if (!publicationAttempted) throw error;
256
+ publicationError = error;
257
+ }
258
+ let history;
259
+ try {
260
+ history = await client.history(roomToken);
261
+ } catch (error) {
262
+ throw new Error("Nextcloud Talk attachment delivery not confirmed; uploaded file retained. Do not blindly retry.", { cause: error });
263
+ }
264
+ const message = history.find((entry) => isRecord(entry) && entry.token === roomToken && entry.actorType === "users" && entry.actorId === uid && entry.referenceId === referenceId && /^[1-9]\d*$/u.test(String(entry.id)) && isRecord(entry.messageParameters) && isRecord(entry.messageParameters.file) && String(entry.messageParameters.file.id) === fileId);
265
+ if (!isRecord(message)) throw new Error("Nextcloud Talk attachment delivery not confirmed; uploaded file retained. Do not blindly retry.", { cause: publicationError });
266
+ const messageId = String(message.id);
267
+ const replyToId = isRecord(message.parent) && String(message.parent.id) === ctx.replyToId ? ctx.replyToId : void 0;
268
+ recordOutboundMessageIdentity({
269
+ channel: "nextcloud-talk",
270
+ accountId: account.accountId,
271
+ conversationId: roomToken,
272
+ messageId
273
+ });
274
+ getOptionalNextcloudTalkRuntime()?.channel.activity.record({
275
+ channel: "nextcloud-talk",
276
+ accountId: account.accountId,
277
+ direction: "outbound"
278
+ });
279
+ return {
280
+ messageId,
281
+ roomToken,
282
+ receipt: createMessageReceiptFromOutboundResults({
283
+ results: [{
284
+ channel: "nextcloud-talk",
285
+ conversationId: roomToken,
286
+ messageId
287
+ }],
288
+ kind: asVoice && message.messageType === "voice-message" ? "voice" : "media",
289
+ ...replyToId ? { replyToId } : {}
290
+ })
291
+ };
292
+ } catch (error) {
293
+ if (uploadFolderOwned && !publicationAttempted) try {
294
+ await client.request(uploadFolder, { method: "DELETE" }, async (response) => {
295
+ if (!response.ok && response.status !== 404) throw new Error("cleanup rejected", { cause: error });
296
+ });
297
+ } catch {
298
+ throw new Error("Nextcloud Talk attachment failed before sharing; unshared upload cleanup also failed.", { cause: error });
299
+ }
300
+ throw error;
301
+ }
302
+ }
303
+ export { isNextcloudTalkOutboundFileEcho, sendMediaNextcloudTalk };
@@ -0,0 +1,64 @@
1
+ import { buildOutboundSessionContext, deliverInboundReplyWithMessageSendContext, sendDurableMessageBatch } from "openclaw/plugin-sdk/channel-outbound";
2
+ import { createAcceptedChannelDeliveryResult, createChannelPartialDeliveryError } from "openclaw/plugin-sdk/channel-inbound";
3
+ // extensions/nextcloud-talk/src/reply.ts
4
+ /** Keep final runtime handoff and all payload planning with the shared owners. */
5
+ async function deliverNextcloudTalkReply(params) {
6
+ const { cfg, accountId, agentId, ctxPayload, payload, info, to } = params;
7
+ const final = await deliverInboundReplyWithMessageSendContext({
8
+ cfg,
9
+ channel: "nextcloud-talk",
10
+ accountId,
11
+ agentId,
12
+ ctxPayload,
13
+ payload,
14
+ info,
15
+ to
16
+ });
17
+ if (final.status === "handled_visible" || final.status === "handled_no_send") return final.delivery;
18
+ if (final.status === "failed") throw final.error;
19
+ const send = await sendDurableMessageBatch({
20
+ cfg,
21
+ channel: "nextcloud-talk",
22
+ accountId,
23
+ to,
24
+ payloads: [payload],
25
+ replyToId: payload.replyToId,
26
+ session: buildOutboundSessionContext({
27
+ cfg,
28
+ agentId,
29
+ sessionKey: ctxPayload.SessionKey,
30
+ policySessionKey: ctxPayload.RuntimePolicySessionKey,
31
+ conversationType: ctxPayload.ChatType,
32
+ requesterAccountId: accountId ?? ctxPayload.AccountId,
33
+ requesterSenderId: ctxPayload.SenderId ?? ctxPayload.From,
34
+ requesterSenderName: ctxPayload.SenderName,
35
+ requesterSenderUsername: ctxPayload.SenderUsername,
36
+ requesterSenderE164: ctxPayload.SenderE164
37
+ }),
38
+ gatewayClientScopes: ctxPayload.GatewayClientScopes ?? [],
39
+ signal: params.signal,
40
+ onPlatformSendDispatch: info.onPlatformSendDispatch,
41
+ assertDirectAdapterHandoff: info.assertPlatformSendAuthorized,
42
+ skipQueue: true,
43
+ durability: "best_effort"
44
+ });
45
+ if (send.status === "failed") throw send.error;
46
+ const deliveryIntent = send.deliveryIntent ? {
47
+ id: send.deliveryIntent.id,
48
+ kind: "outbound_queue",
49
+ queuePolicy: send.deliveryIntent.queuePolicy
50
+ } : void 0;
51
+ if (send.status === "suppressed") return {
52
+ visibleReplySent: false,
53
+ receipt: send.receipt,
54
+ suppression: { reason: send.reason },
55
+ ...deliveryIntent ? { deliveryIntent } : {}
56
+ };
57
+ const result = {
58
+ ...createAcceptedChannelDeliveryResult({ results: [{ receipt: send.receipt }] }),
59
+ ...deliveryIntent ? { deliveryIntent } : {}
60
+ };
61
+ if (send.status === "partial_failed") throw createChannelPartialDeliveryError(send.error, result);
62
+ return result;
63
+ }
64
+ export { deliverNextcloudTalkReply };
@@ -1,13 +1,11 @@
1
1
  import { createChannelPairingController } from "openclaw/plugin-sdk/channel-pairing";
2
2
  import { logInboundDrop } from "openclaw/plugin-sdk/channel-inbound";
3
3
  import { GROUP_POLICY_BLOCKED_LABEL, resolveAllowlistProviderRuntimeGroupPolicy, resolveDefaultGroupPolicy, warnMissingProviderGroupPolicyFallbackOnce } from "openclaw/plugin-sdk/runtime-group-policy";
4
- import { deliverFormattedTextWithAttachments } from "openclaw/plugin-sdk/reply-payload";
5
4
  import { fetchWithSsrFGuard } from "openclaw/plugin-sdk/ssrf-runtime";
6
5
  import { createPluginRuntimeStore } from "openclaw/plugin-sdk/runtime-store";
7
- //#region extensions/nextcloud-talk/src/runtime.ts
6
+ // extensions/nextcloud-talk/src/runtime.ts
8
7
  const { setRuntime: setNextcloudTalkRuntime, getRuntime: getNextcloudTalkRuntime, tryGetRuntime: getOptionalNextcloudTalkRuntime } = createPluginRuntimeStore({
9
8
  pluginId: "nextcloud-talk",
10
9
  errorMessage: "Nextcloud Talk runtime not initialized"
11
10
  });
12
- //#endregion
13
- export { logInboundDrop as a, warnMissingProviderGroupPolicyFallbackOnce as c, setNextcloudTalkRuntime as d, fetchWithSsrFGuard as i, getNextcloudTalkRuntime as l, createChannelPairingController as n, resolveAllowlistProviderRuntimeGroupPolicy as o, deliverFormattedTextWithAttachments as r, resolveDefaultGroupPolicy as s, GROUP_POLICY_BLOCKED_LABEL as t, getOptionalNextcloudTalkRuntime as u };
11
+ export { resolveAllowlistProviderRuntimeGroupPolicy as a, getNextcloudTalkRuntime as c, logInboundDrop as i, getOptionalNextcloudTalkRuntime as l, createChannelPairingController as n, resolveDefaultGroupPolicy as o, fetchWithSsrFGuard as r, warnMissingProviderGroupPolicyFallbackOnce as s, GROUP_POLICY_BLOCKED_LABEL as t, setNextcloudTalkRuntime as u };
@@ -1,2 +1,2 @@
1
- export { t as channelSecrets, n as collectRuntimeConfigAssignments, r as secretTargetRegistryEntries } from "./secret-contract-Bvm0PmP3.mjs";
1
+ export { t as channelSecrets, n as collectRuntimeConfigAssignments, r as secretTargetRegistryEntries } from "./secret-contract-yjCLewtg.mjs";
2
2
  import "../secret-contract-api.js";
@@ -0,0 +1,19 @@
1
+ import { hasConfiguredNextcloudAccount } from "../configured-state.js";
2
+ import { collectSimpleChannelFieldAssignments, createChannelSecretContract } from "openclaw/plugin-sdk/channel-secret-basic-runtime";
3
+ // extensions/nextcloud-talk/src/secret-contract.ts
4
+ const channelSecrets = createChannelSecretContract({
5
+ channelKey: "nextcloud-talk",
6
+ account: ["apiPassword", "botSecret"],
7
+ channel: ["apiPassword", "botSecret"],
8
+ hasImplicitDefaultAccount: ({ context }) => hasConfiguredNextcloudAccount(context.sourceConfig.channels?.["nextcloud-talk"], context.env),
9
+ collect(params) {
10
+ for (const field of ["botSecret", "apiPassword"]) collectSimpleChannelFieldAssignments({
11
+ ...params,
12
+ field,
13
+ topInactiveReason: `no enabled Nextcloud Talk surface inherits this top-level ${field}.`,
14
+ accountInactiveReason: "Nextcloud Talk account is disabled."
15
+ });
16
+ }
17
+ });
18
+ const { secretTargetRegistryEntries, collectRuntimeConfigAssignments } = channelSecrets;
19
+ export { collectRuntimeConfigAssignments as n, secretTargetRegistryEntries as r, channelSecrets as t };
@@ -1 +1 @@
1
- {"version":3,"entries":[{"output":"api.js","source":"extensions/nextcloud-talk/api.ts"},{"output":"channel-plugin-api.js","source":"extensions/nextcloud-talk/channel-plugin-api.ts"},{"output":"configured-state.js","source":"extensions/nextcloud-talk/configured-state.ts"},{"output":"doctor-contract-api.js","source":"extensions/nextcloud-talk/doctor-contract-api.ts"},{"output":"index.js","source":"extensions/nextcloud-talk/index.ts"},{"output":"runtime-api.js","source":"extensions/nextcloud-talk/runtime-api.ts"},{"output":"secret-contract-api.js","source":"extensions/nextcloud-talk/secret-contract-api.ts"},{"output":"setup-entry.js","source":"extensions/nextcloud-talk/setup-entry.ts"}],"chunks":[{"output":".setup/api-BmNQoi-o.mjs","sha256":"2bc270280c12867279785c00677d286e883e393cc47d4da2a7201006ea89320a","facadeSource":"extensions/nextcloud-talk/api.ts","sources":[]},{"output":".setup/channel-B8-CvvK1.mjs","sha256":"ea3865dc7fd8c75112f517da40fcd855f95f65e66ec36fd90b035ed0ea1f92c6","facadeSource":null,"sources":["extensions/nextcloud-talk/src/accounts.ts","extensions/nextcloud-talk/src/api-credentials.ts","extensions/nextcloud-talk/src/approval-auth.ts","extensions/nextcloud-talk/src/bot-preflight.ts","extensions/nextcloud-talk/src/channel.adapters.ts","extensions/nextcloud-talk/src/channel.ts","extensions/nextcloud-talk/src/config-schema.ts","extensions/nextcloud-talk/src/doctor.ts","extensions/nextcloud-talk/src/gateway.ts","extensions/nextcloud-talk/src/guarded-response.ts","extensions/nextcloud-talk/src/inbound.ts","extensions/nextcloud-talk/src/message-actions.ts","extensions/nextcloud-talk/src/message-adapter.ts","extensions/nextcloud-talk/src/monitor-runtime.ts","extensions/nextcloud-talk/src/monitor.ts","extensions/nextcloud-talk/src/normalize.ts","extensions/nextcloud-talk/src/policy.ts","extensions/nextcloud-talk/src/replay-migration-contract.ts","extensions/nextcloud-talk/src/room-info.ts","extensions/nextcloud-talk/src/send.ts","extensions/nextcloud-talk/src/session-route.ts","extensions/nextcloud-talk/src/setup-core.ts","extensions/nextcloud-talk/src/setup-surface.ts","extensions/nextcloud-talk/src/signature.ts","extensions/nextcloud-talk/src/webhook-route.ts","extensions/nextcloud-talk/src/webhook-spool-state.ts","extensions/nextcloud-talk/src/webhook-spool.ts","packages/normalization-core/src/string-coerce.ts","src/gateway/gateway-http-route-contracts.ts","src/gateway/security-path.ts","src/gateway/server/plugins-http/path-context.ts","src/plugins/http-path-prefix.ts"]},{"output":".setup/doctor-contract-DwH950tH.mjs","sha256":"fc92feebc8e348bacba027cadbf2fd4e510c557abe00e20ff2ee80bab76c0e8a","facadeSource":null,"sources":["extensions/nextcloud-talk/src/doctor-contract.ts","packages/normalization-core/src/record-coerce.ts","src/config/channel-config-normalization.ts","src/plugin-sdk/legacy-webhook-listener-migration.ts"]},{"output":".setup/runtime-api-DVkVOUSo.mjs","sha256":"7f9187eb96ed6d031f63c3a480653fef48d5b9c581f18008598feeee27345cdc","facadeSource":null,"sources":["extensions/nextcloud-talk/src/runtime.ts"]},{"output":".setup/secret-contract-api-DoyAH9bS.mjs","sha256":"f28083e02a867734bc44bdc6a690bba3e7c9dd61e4ee7efe65bf90c7d820caec","facadeSource":"extensions/nextcloud-talk/secret-contract-api.ts","sources":[]},{"output":".setup/secret-contract-Bvm0PmP3.mjs","sha256":"88393e46f2f5b42d8868d36c1b0c85a275dd01472601f757005052fa6dfcf051","facadeSource":null,"sources":["extensions/nextcloud-talk/src/secret-contract.ts"]},{"output":"api.js","sha256":"59b284727af55cf3a9b549405c5b9811e829dca1f9a08492bdb1f6004770bff6","facadeSource":"extensions/nextcloud-talk/api.ts","sources":[]},{"output":"channel-plugin-api.js","sha256":"59b284727af55cf3a9b549405c5b9811e829dca1f9a08492bdb1f6004770bff6","facadeSource":"extensions/nextcloud-talk/channel-plugin-api.ts","sources":[]},{"output":"configured-state.js","sha256":"ac8ee085fd929e3644c33b516f94891205f915591811d8f541ca443d175a74b5","facadeSource":"extensions/nextcloud-talk/configured-state.ts","sources":["extensions/nextcloud-talk/configured-state.ts"]},{"output":"doctor-contract-api.js","sha256":"8bc6b0c8254cfb5f79b7516d18d4bbf6bf862e3a3deba033e037d481b6ff9114","facadeSource":"extensions/nextcloud-talk/doctor-contract-api.ts","sources":[]},{"output":"index.js","sha256":"eaac1b676ea855c0ce9ea0a8e3157564c7a38f956ace23c22b0c28667dc0b424","facadeSource":"extensions/nextcloud-talk/index.ts","sources":["extensions/nextcloud-talk/index.ts"]},{"output":"runtime-api.js","sha256":"f4b2341101e63c59f0086c5738b3d798f1718e7cf7c0ec1dfb70b9f172821f67","facadeSource":"extensions/nextcloud-talk/runtime-api.ts","sources":[]},{"output":"secret-contract-api.js","sha256":"70acb59d3d1c1e0a74dcd8a1090740d6361943e32c9776bcc4e1fc2630ddd860","facadeSource":"extensions/nextcloud-talk/secret-contract-api.ts","sources":[]},{"output":"setup-entry.js","sha256":"085ddebc5687f8394702f895486ad994cdbf703c204c71e74e02b33782282823","facadeSource":"extensions/nextcloud-talk/setup-entry.ts","sources":["extensions/nextcloud-talk/setup-entry.ts"]}],"unrenderedSources":["extensions/nextcloud-talk/api.ts","extensions/nextcloud-talk/channel-plugin-api.ts","extensions/nextcloud-talk/config-doctor-api.ts","extensions/nextcloud-talk/doctor-contract-api.ts","extensions/nextcloud-talk/runtime-api.ts","extensions/nextcloud-talk/secret-contract-api.ts","extensions/nextcloud-talk/src/channel-api.ts","extensions/nextcloud-talk/src/send.runtime.ts"]}
1
+ {"version":3,"entries":[{"output":"api.js","source":"extensions/nextcloud-talk/api.ts"},{"output":"channel-plugin-api.js","source":"extensions/nextcloud-talk/channel-plugin-api.ts"},{"output":"configured-state.js","source":"extensions/nextcloud-talk/configured-state.ts"},{"output":"doctor-contract-api.js","source":"extensions/nextcloud-talk/doctor-contract-api.ts"},{"output":"index.js","source":"extensions/nextcloud-talk/index.ts"},{"output":"runtime-api.js","source":"extensions/nextcloud-talk/runtime-api.ts"},{"output":"secret-contract-api.js","source":"extensions/nextcloud-talk/secret-contract-api.ts"},{"output":"setup-entry.js","source":"extensions/nextcloud-talk/setup-entry.ts"}],"chunks":[{"output":".setup/api-BvrRSilb.mjs","sha256":"b25f39344c117b809520b3961b58f661adee93617654525cf980397c3567f61c","facadeSource":"extensions/nextcloud-talk/api.ts","sources":[]},{"output":".setup/channel-BA1-OoqO.mjs","sha256":"7332d213f8ca1e37bfa7a913f295bbef288630ddb9739c5f4032aa558c2e4057","facadeSource":null,"sources":["extensions/nextcloud-talk/src/accounts.ts","extensions/nextcloud-talk/src/api-credentials.ts","extensions/nextcloud-talk/src/bot-preflight.ts","extensions/nextcloud-talk/src/channel.ts","extensions/nextcloud-talk/src/config-schema.ts","extensions/nextcloud-talk/src/doctor.ts","extensions/nextcloud-talk/src/guarded-response.ts","extensions/nextcloud-talk/src/inbound-media.ts","extensions/nextcloud-talk/src/inbound.ts","extensions/nextcloud-talk/src/message-actions.ts","extensions/nextcloud-talk/src/monitor.ts","extensions/nextcloud-talk/src/normalize.ts","extensions/nextcloud-talk/src/policy.ts","extensions/nextcloud-talk/src/replay-migration-contract.ts","extensions/nextcloud-talk/src/room-info.ts","extensions/nextcloud-talk/src/send.ts","extensions/nextcloud-talk/src/setup-core.ts","extensions/nextcloud-talk/src/setup-surface.ts","extensions/nextcloud-talk/src/signature.ts","extensions/nextcloud-talk/src/voice-media.ts","extensions/nextcloud-talk/src/webdav.ts","extensions/nextcloud-talk/src/webhook-route.ts","extensions/nextcloud-talk/src/webhook-spool-state.ts","extensions/nextcloud-talk/src/webhook-spool.ts","packages/normalization-core/src/string-coerce.ts","src/gateway/gateway-http-route-contracts.ts","src/gateway/security-path.ts","src/gateway/server/plugins-http/path-context.ts","src/plugins/http-path-prefix.ts"]},{"output":".setup/doctor-contract-CkWQa5uZ.mjs","sha256":"b580887eb445ab10c67ee1a057982cd3be79d68e2c3440b3f2a46f2a8852c55b","facadeSource":null,"sources":["extensions/nextcloud-talk/src/doctor-contract.ts","packages/normalization-core/src/record-coerce.ts","src/config/channel-config-normalization.ts","src/plugin-sdk/legacy-webhook-listener-migration.ts"]},{"output":".setup/outbound-media-CpFe1Xgz.mjs","sha256":"bef81da85203f92dc6478aa3f00d11112e3f8aad10191dbf0a0678c07049ab61","facadeSource":"extensions/nextcloud-talk/src/outbound-media.ts","sources":["extensions/nextcloud-talk/src/outbound-media.ts"]},{"output":".setup/reply-BEkv387l.mjs","sha256":"e2c5093c05fcdbbe57a1693ea81de165c8280573ad3706f244dbd152dcd895ca","facadeSource":"extensions/nextcloud-talk/src/reply.ts","sources":["extensions/nextcloud-talk/src/reply.ts"]},{"output":".setup/runtime-api-CGy_KpdV.mjs","sha256":"344accb3739f831215489e33d0ca4dbaa5062fad8a0c98b7e356ee2bd0bb8228","facadeSource":null,"sources":["extensions/nextcloud-talk/src/runtime.ts"]},{"output":".setup/secret-contract-api-QMihLdr1.mjs","sha256":"0a2531895db3b16212c29ea87314c04021173a1bde49b58fbfd29fed181b4f15","facadeSource":"extensions/nextcloud-talk/secret-contract-api.ts","sources":[]},{"output":".setup/secret-contract-yjCLewtg.mjs","sha256":"183e7de729d242a63a7b607f3d353a5712f19eaea4ca24525cd96cc93bb63ffc","facadeSource":null,"sources":["extensions/nextcloud-talk/src/secret-contract.ts"]},{"output":"api.js","sha256":"e6a136ec30af9d685b3b1724ac335bc48534867c9c553e6a04f47d1ae22444d8","facadeSource":"extensions/nextcloud-talk/api.ts","sources":[]},{"output":"channel-plugin-api.js","sha256":"e6a136ec30af9d685b3b1724ac335bc48534867c9c553e6a04f47d1ae22444d8","facadeSource":"extensions/nextcloud-talk/channel-plugin-api.ts","sources":[]},{"output":"configured-state.js","sha256":"a45a34efe4339d78b7fcc92b8d09f8ad60d19c4a4e3a9754104c7f658be278d0","facadeSource":"extensions/nextcloud-talk/configured-state.ts","sources":["extensions/nextcloud-talk/configured-state.ts"]},{"output":"doctor-contract-api.js","sha256":"71237fb5c510be1302851b9fb7b264dd4e0d0095be206e50ffce4b5890ace54f","facadeSource":"extensions/nextcloud-talk/doctor-contract-api.ts","sources":[]},{"output":"index.js","sha256":"16bcc875626f7dd3bc4c1195210f856deaa9c3757abe5cea2a1d90cb2877cd22","facadeSource":"extensions/nextcloud-talk/index.ts","sources":["extensions/nextcloud-talk/index.ts"]},{"output":"runtime-api.js","sha256":"9306402515a553c1fe195fc8be8d6436a41abca338ae6cd4254434422e6f4cb3","facadeSource":"extensions/nextcloud-talk/runtime-api.ts","sources":[]},{"output":"secret-contract-api.js","sha256":"34c4d2c917c364f14b73bb8f51db22a8f24d047246358f543ab3aa0abfa78202","facadeSource":"extensions/nextcloud-talk/secret-contract-api.ts","sources":[]},{"output":"setup-entry.js","sha256":"7dba8b8fb26185b57bcabe7aab548d7e956deb37c46142110413ff4cab7cf80a","facadeSource":"extensions/nextcloud-talk/setup-entry.ts","sources":["extensions/nextcloud-talk/setup-entry.ts"]}],"unrenderedSources":["extensions/nextcloud-talk/api.ts","extensions/nextcloud-talk/channel-plugin-api.ts","extensions/nextcloud-talk/config-doctor-api.ts","extensions/nextcloud-talk/doctor-contract-api.ts","extensions/nextcloud-talk/runtime-api.ts","extensions/nextcloud-talk/secret-contract-api.ts"]}
package/dist/api.js CHANGED
@@ -1 +1 @@
1
- export { t as nextcloudTalkPlugin } from "./.setup/channel-B8-CvvK1.mjs";
1
+ export { t as nextcloudTalkPlugin } from "./.setup/channel-BA1-OoqO.mjs";
@@ -1 +1 @@
1
- export { t as nextcloudTalkPlugin } from "./.setup/channel-B8-CvvK1.mjs";
1
+ export { t as nextcloudTalkPlugin } from "./.setup/channel-BA1-OoqO.mjs";
@@ -1,12 +1,9 @@
1
1
  import { DEFAULT_ACCOUNT_ID, createAccountListHelpers, hasConfiguredAccountValue, normalizeAccountId } from "openclaw/plugin-sdk/account-core";
2
- //#region extensions/nextcloud-talk/configured-state.ts
2
+ // extensions/nextcloud-talk/configured-state.ts
3
3
  const { listAccountIds: listNextcloudTalkAccountIds, resolveDefaultAccountId: resolveDefaultNextcloudTalkAccountId, resolveAccountConfig: mergeNextcloudTalkAccountConfig } = createAccountListHelpers("nextcloud-talk", {
4
4
  normalizeAccountId,
5
5
  omitKeys: ["defaultAccount"],
6
- hasImplicitDefaultAccount: (cfg) => {
7
- const channel = cfg.channels?.["nextcloud-talk"];
8
- return Boolean(channel?.baseUrl?.trim() && (hasConfiguredAccountValue(channel.botSecret) || channel.botSecretFile?.trim() || process.env.NEXTCLOUD_TALK_BOT_SECRET?.trim()));
9
- }
6
+ hasImplicitDefaultAccount: (cfg) => hasConfiguredNextcloudAccount(cfg.channels?.["nextcloud-talk"], process.env)
10
7
  });
11
8
  function hasConfiguredNextcloudAccount(account, env) {
12
9
  return Boolean(account?.baseUrl?.trim() && (hasConfiguredAccountValue(account.botSecret) || hasConfiguredAccountValue(account.botSecretFile) || hasConfiguredAccountValue(env.NEXTCLOUD_TALK_BOT_SECRET)));
@@ -20,5 +17,4 @@ function hasConfiguredNextcloudTalkChannelState(params) {
20
17
  }
21
18
  return Object.entries(channel?.accounts ?? {}).some(([accountId, account]) => accountId !== DEFAULT_ACCOUNT_ID && account.enabled !== false && hasConfiguredNextcloudAccount(mergeNextcloudTalkAccountConfig(params.cfg, accountId), {}));
22
19
  }
23
- //#endregion
24
- export { hasConfiguredNextcloudTalkChannelState, listNextcloudTalkAccountIds, mergeNextcloudTalkAccountConfig, resolveDefaultNextcloudTalkAccountId };
20
+ export { hasConfiguredNextcloudAccount, hasConfiguredNextcloudTalkChannelState, listNextcloudTalkAccountIds, mergeNextcloudTalkAccountConfig, resolveDefaultNextcloudTalkAccountId };
@@ -1 +1 @@
1
- export { t as historicalWebhookListener, n as legacyConfigRules, r as normalizeCompatibilityConfig, i as normalizeHistoricalWebhookConfig } from "./.setup/doctor-contract-DwH950tH.mjs";
1
+ export { t as historicalWebhookListener, n as legacyConfigRules, r as normalizeCompatibilityConfig, i as normalizeHistoricalWebhookConfig } from "./.setup/doctor-contract-CkWQa5uZ.mjs";
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { defineBundledChannelEntry } from "openclaw/plugin-sdk/channel-entry-contract";
2
- //#region extensions/nextcloud-talk/index.ts
2
+ // extensions/nextcloud-talk/index.ts
3
3
  var nextcloud_talk_default = defineBundledChannelEntry({
4
4
  id: "nextcloud-talk",
5
5
  name: "Nextcloud Talk",
@@ -18,5 +18,4 @@ var nextcloud_talk_default = defineBundledChannelEntry({
18
18
  exportName: "setNextcloudTalkRuntime"
19
19
  }
20
20
  });
21
- //#endregion
22
21
  export { nextcloud_talk_default as default };
@@ -1 +1 @@
1
- export { t as GROUP_POLICY_BLOCKED_LABEL, n as createChannelPairingController, r as deliverFormattedTextWithAttachments, i as fetchWithSsrFGuard, a as logInboundDrop, o as resolveAllowlistProviderRuntimeGroupPolicy, s as resolveDefaultGroupPolicy, d as setNextcloudTalkRuntime, c as warnMissingProviderGroupPolicyFallbackOnce } from "./.setup/runtime-api-DVkVOUSo.mjs";
1
+ export { t as GROUP_POLICY_BLOCKED_LABEL, n as createChannelPairingController, r as fetchWithSsrFGuard, i as logInboundDrop, a as resolveAllowlistProviderRuntimeGroupPolicy, o as resolveDefaultGroupPolicy, u as setNextcloudTalkRuntime, s as warnMissingProviderGroupPolicyFallbackOnce } from "./.setup/runtime-api-CGy_KpdV.mjs";
@@ -1 +1 @@
1
- export { t as channelSecrets, n as collectRuntimeConfigAssignments, r as secretTargetRegistryEntries } from "./.setup/secret-contract-Bvm0PmP3.mjs";
1
+ export { t as channelSecrets, n as collectRuntimeConfigAssignments, r as secretTargetRegistryEntries } from "./.setup/secret-contract-yjCLewtg.mjs";
@@ -1,16 +1,15 @@
1
1
  import { defineBundledChannelSetupEntry } from "openclaw/plugin-sdk/channel-entry-contract";
2
2
  import { fileURLToPath } from "node:url";
3
- //#region extensions/nextcloud-talk/setup-entry.ts
3
+ // extensions/nextcloud-talk/setup-entry.ts
4
4
  var setup_entry_default = defineBundledChannelSetupEntry({
5
5
  importMetaUrl: import.meta.url,
6
6
  plugin: {
7
- specifier: fileURLToPath(new URL(".setup/api-BmNQoi-o.mjs", import.meta.url).href),
7
+ specifier: fileURLToPath(new URL(".setup/api-BvrRSilb.mjs", import.meta.url).href),
8
8
  exportName: "nextcloudTalkPlugin"
9
9
  },
10
10
  secrets: {
11
- specifier: fileURLToPath(new URL(".setup/secret-contract-api-DoyAH9bS.mjs", import.meta.url).href),
11
+ specifier: fileURLToPath(new URL(".setup/secret-contract-api-QMihLdr1.mjs", import.meta.url).href),
12
12
  exportName: "channelSecrets"
13
13
  }
14
14
  });
15
- //#endregion
16
15
  export { setup_entry_default as default };