@openclaw/nextcloud-talk 2026.10.2 → 2026.10.5-beta.2

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.
@@ -0,0 +1,3 @@
1
+ import { t as nextcloudTalkPlugin } from "./channel-DTKYMnlK.mjs";
2
+ import "../api.js";
3
+ export { nextcloudTalkPlugin };
@@ -1,5 +1,5 @@
1
1
  import { a as __exportAll, n as legacyConfigRules, o as __reExport, r as normalizeCompatibilityConfig } from "./doctor-contract-DwH950tH.mjs";
2
- import { listNextcloudTalkAccountIds as listNextcloudTalkAccountIds$1, mergeNextcloudTalkAccountConfig, resolveDefaultNextcloudTalkAccountId } from "../configured-state.js";
2
+ import { listNextcloudTalkAccountIds, mergeNextcloudTalkAccountConfig, resolveDefaultNextcloudTalkAccountId } from "../configured-state.js";
3
3
  import { a as logInboundDrop, c as warnMissingProviderGroupPolicyFallbackOnce, i as fetchWithSsrFGuard, l as getNextcloudTalkRuntime, n as createChannelPairingController, o as resolveAllowlistProviderRuntimeGroupPolicy, r as deliverFormattedTextWithAttachments, s as resolveDefaultGroupPolicy, t as GROUP_POLICY_BLOCKED_LABEL, u as getOptionalNextcloudTalkRuntime } from "./runtime-api-DVkVOUSo.mjs";
4
4
  import { n as collectRuntimeConfigAssignments, r as secretTargetRegistryEntries } from "./secret-contract-Bvm0PmP3.mjs";
5
5
  import { describeWebhookAccountSnapshot } from "openclaw/plugin-sdk/account-helpers";
@@ -9,7 +9,6 @@ import { createAllowlistProviderRouteAllowlistWarningCollector, createConditiona
9
9
  import { buildWebhookChannelStatusSummary, createComputedAccountStatusAdapter, createDefaultChannelRuntimeState } from "openclaw/plugin-sdk/status-helpers";
10
10
  import { convertMarkdownTables, sanitizeAssistantVisibleText } from "openclaw/plugin-sdk/text-chunking";
11
11
  import { DEFAULT_ACCOUNT_ID, normalizeAccountId, resolveAccountWithDefaultFallback } from "openclaw/plugin-sdk/account-core";
12
- import { isTruthyEnvValue } from "openclaw/plugin-sdk/runtime-env";
13
12
  import { tryReadSecretFileSync } from "openclaw/plugin-sdk/secret-file-runtime";
14
13
  import { buildSecretInputSchema, hasConfiguredSecretInput, resolveSecretInputString } from "openclaw/plugin-sdk/secret-input";
15
14
  import { isRecord, normalizeLowercaseStringOrEmpty, normalizeOptionalLowercaseString, normalizeOptionalString, normalizeStringEntries, readNonEmptyStringPreservingWhitespace } from "openclaw/plugin-sdk/string-coerce-runtime";
@@ -17,7 +16,7 @@ import { createChannelApprovalAuth } from "openclaw/plugin-sdk/approval-auth-run
17
16
  import { formatErrorMessage } from "openclaw/plugin-sdk/error-runtime";
18
17
  import { parseStrictNonNegativeInteger, parseStrictPositiveInteger } from "openclaw/plugin-sdk/number-runtime";
19
18
  import { readProviderJsonResponse, readProviderTextResponse } from "openclaw/plugin-sdk/provider-http";
20
- import { resolveChannelInboundRouteEnvelope } from "openclaw/plugin-sdk/channel-inbound";
19
+ import { createChannelInboundEnvelopeBuilderAsync } from "openclaw/plugin-sdk/channel-inbound";
21
20
  import { SsrFBlockedError, ssrfPolicyFromPrivateNetworkOptIn, ssrfPolicyFromPrivateNetworkOptIn as ssrfPolicyFromPrivateNetworkOptIn$1 } from "openclaw/plugin-sdk/ssrf-runtime";
22
21
  import { createPluginRuntimeStore } from "openclaw/plugin-sdk/runtime-store";
23
22
  import { redactToolPayloadText } from "openclaw/plugin-sdk/logging-core";
@@ -38,6 +37,7 @@ import { resolveStateDir } from "openclaw/plugin-sdk/state-paths";
38
37
  import { bindIngressLifecycleToReplyOptions, createAccountStatusSink, createChannelIngressMonitor, createMessageReceiptFromOutboundResults, defineChannelMessageAdapter, resolveChannelStreamingBlockEnabled, runPassiveAccountLifecycle } from "openclaw/plugin-sdk/channel-outbound";
39
38
  import { channelReadyPatch } from "openclaw/plugin-sdk/gateway-runtime";
40
39
  import { channelIngressRoutes } from "openclaw/plugin-sdk/channel-ingress-runtime";
40
+ import { DEFAULT_ACCOUNT_ID as DEFAULT_ACCOUNT_ID$1, normalizeAccountId as normalizeAccountId$1, resolveAgentRoute } from "openclaw/plugin-sdk/routing";
41
41
  import { safeParseJson, truncateUtf16Safe } from "openclaw/plugin-sdk/text-utility-runtime";
42
42
  import { buildChannelKeyCandidates, normalizeChannelSlug, resolveChannelEntryMatchWithFallback } from "openclaw/plugin-sdk/channel-targets";
43
43
  import { pruneMapToMaxSize } from "openclaw/plugin-sdk/collection-runtime";
@@ -49,7 +49,6 @@ import { resolvePersistentDedupePluginStateNamespace } from "openclaw/plugin-sdk
49
49
  import { jsonResult, readStringParam, resolveReactionMessageId } from "openclaw/plugin-sdk/channel-actions";
50
50
  import { createChannelDmPolicy } from "openclaw/plugin-sdk/channel-dm-policy";
51
51
  import { defineChannelSetupContract } from "openclaw/plugin-sdk/channel-setup";
52
- import { DEFAULT_ACCOUNT_ID as DEFAULT_ACCOUNT_ID$1, normalizeAccountId as normalizeAccountId$1 } from "openclaw/plugin-sdk/routing";
53
52
  import { applyAccountNameToChannelSection, baseUrlTextInput, createPromptParsedAllowFromForAccount, createSetupTranslator, createStandardChannelSetupStatus, defineTokenCredential, formatDocsLink, patchScopedAccountConfig, setSetupChannelEnabled } from "openclaw/plugin-sdk/setup";
54
53
  import { createSetupInputPresenceValidator, createSetupTranslator as createSetupTranslator$1, mergeAllowFromEntries } from "openclaw/plugin-sdk/setup-runtime";
55
54
  import { formatDocsLink as formatDocsLink$1 } from "openclaw/plugin-sdk/setup-tools";
@@ -87,14 +86,6 @@ function resolveNextcloudTalkApiCredentials(params) {
87
86
  }
88
87
  //#endregion
89
88
  //#region extensions/nextcloud-talk/src/accounts.ts
90
- const debugAccounts = (...args) => {
91
- if (isTruthyEnvValue(process.env.OPENCLAW_DEBUG_NEXTCLOUD_TALK_ACCOUNTS)) console.warn("[nextcloud-talk:accounts]", ...args);
92
- };
93
- function listNextcloudTalkAccountIds(cfg) {
94
- const ids = listNextcloudTalkAccountIds$1(cfg);
95
- debugAccounts("listNextcloudTalkAccountIds", ids);
96
- return ids;
97
- }
98
89
  function resolveNextcloudTalkSecret(accountId, merged) {
99
90
  const configuredSecret = resolveSecretInputString({
100
91
  value: merged.botSecret,
@@ -146,12 +137,6 @@ function resolveNextcloudTalkAccount(params) {
146
137
  const enabled = baseEnabled && accountEnabled;
147
138
  const secretResolution = resolveNextcloudTalkSecret(accountId, merged);
148
139
  const baseUrl = merged.baseUrl?.trim()?.replace(/\/$/, "") ?? "";
149
- debugAccounts("resolve", {
150
- accountId,
151
- enabled,
152
- secretSource: secretResolution.source,
153
- baseUrl: baseUrl ? "[set]" : "[missing]"
154
- });
155
140
  return {
156
141
  accountId,
157
142
  enabled,
@@ -252,9 +237,6 @@ function extractNextcloudTalkHeaders(headers) {
252
237
  backend
253
238
  };
254
239
  }
255
- /**
256
- * Generate signature headers for an outbound request to Nextcloud Talk.
257
- */
258
240
  function generateNextcloudTalkSignature(params) {
259
241
  const { body, secret } = params;
260
242
  const random = randomBytes(32).toString("hex");
@@ -267,14 +249,10 @@ function generateNextcloudTalkSignature(params) {
267
249
  //#region extensions/nextcloud-talk/src/bot-preflight.ts
268
250
  const BOT_FEATURE_RESPONSE = 2;
269
251
  function normalizeUrlForMatch(value) {
270
- if (!value?.trim()) return "";
271
- try {
272
- const url = new URL(value.trim());
273
- url.hash = "";
274
- return url.toString().replace(/\/$/, "");
275
- } catch {
276
- return value.trim().replace(/\/$/, "");
277
- }
252
+ const trimmed = value?.trim() ?? "";
253
+ const url = URL.parse(trimmed);
254
+ if (url) url.hash = "";
255
+ return (url?.toString() ?? trimmed).replace(/\/$/, "");
278
256
  }
279
257
  function formatMissingResponseFeatureMessage(bot, features) {
280
258
  const id = bot.id == null ? "unknown" : String(bot.id);
@@ -287,14 +265,14 @@ async function probeNextcloudTalkBotResponseFeature(params) {
287
265
  ok: true,
288
266
  skipped: true,
289
267
  code: "missing_base_url",
290
- message: "Nextcloud Talk bot response feature probe skipped: baseUrl is not configured."
268
+ message: "Nextcloud Talk bot response feature check skipped: baseUrl is not configured."
291
269
  };
292
270
  const webhookUrl = normalizeUrlForMatch(account.config.webhookPublicUrl);
293
271
  if (!webhookUrl) return {
294
272
  ok: true,
295
273
  skipped: true,
296
274
  code: "missing_webhook_url",
297
- message: "Nextcloud Talk bot response feature probe skipped: webhookPublicUrl is not configured."
275
+ message: "Nextcloud Talk bot response feature check skipped: webhookPublicUrl is not configured."
298
276
  };
299
277
  const credentials = resolveNextcloudTalkApiCredentials({
300
278
  apiUser: account.config.apiUser,
@@ -305,7 +283,7 @@ async function probeNextcloudTalkBotResponseFeature(params) {
305
283
  ok: true,
306
284
  skipped: true,
307
285
  code: "missing_api_credentials",
308
- message: "Nextcloud Talk bot response feature probe skipped: apiUser/apiPassword are not configured."
286
+ message: "Nextcloud Talk bot response feature check skipped: apiUser/apiPassword are not configured."
309
287
  };
310
288
  const url = `${baseUrl}/ocs/v2.php/apps/spreed/api/v1/bot/admin`;
311
289
  const auth = Buffer.from(`${credentials.apiUser}:${credentials.apiPassword}`, "utf-8").toString("base64");
@@ -321,7 +299,7 @@ async function probeNextcloudTalkBotResponseFeature(params) {
321
299
  }
322
300
  },
323
301
  auditContext: "nextcloud-talk.bot-response-preflight",
324
- policy: ssrfPolicyFromPrivateNetworkOptIn$1(account.config),
302
+ policy: ssrfPolicyFromPrivateNetworkOptIn$1(account.config.network?.dangerouslyAllowPrivateNetwork),
325
303
  timeoutMs
326
304
  });
327
305
  try {
@@ -331,15 +309,15 @@ async function probeNextcloudTalkBotResponseFeature(params) {
331
309
  ok: false,
332
310
  code: "api_error",
333
311
  status: response.status,
334
- message: `Nextcloud Talk bot response feature probe failed (${response.status})${body ? `: ${body}` : ""}`
312
+ message: `Nextcloud Talk bot response feature check failed (${response.status})${body ? `: ${body}` : ""}`
335
313
  };
336
314
  }
337
- const payload = await readProviderJsonResponse(response, "Nextcloud Talk bot response feature probe failed");
315
+ const payload = await readProviderJsonResponse(response, "Nextcloud Talk bot response feature check failed");
338
316
  const bot = (Array.isArray(payload.ocs?.data) ? payload.ocs.data : []).find((entry) => normalizeUrlForMatch(entry.url) === webhookUrl);
339
317
  if (!bot) return {
340
318
  ok: false,
341
319
  code: "bot_not_found",
342
- message: `Nextcloud Talk bot response feature probe could not find a bot with webhook URL ${webhookUrl}.`
320
+ message: `Nextcloud Talk bot response feature check could not find a bot with webhook URL ${webhookUrl}.`
343
321
  };
344
322
  const features = parseStrictNonNegativeInteger(bot.features);
345
323
  if (features == null || (features & BOT_FEATURE_RESPONSE) !== BOT_FEATURE_RESPONSE) return {
@@ -365,7 +343,7 @@ async function probeNextcloudTalkBotResponseFeature(params) {
365
343
  return {
366
344
  ok: false,
367
345
  code: "request_failed",
368
- message: `Nextcloud Talk bot response feature probe failed: ${error instanceof Error ? error.message : formatErrorMessage(error)}`
346
+ message: `Nextcloud Talk bot response feature check failed: ${error instanceof Error ? error.message : formatErrorMessage(error)}`
369
347
  };
370
348
  }
371
349
  }
@@ -505,22 +483,15 @@ function normalizePathSeparators(pathname) {
505
483
  if (collapsed.length <= 1) return collapsed;
506
484
  return collapsed.replace(/\/+$/, "");
507
485
  }
508
- function resolveDotSegments(pathname) {
509
- try {
510
- return new URL(pathname, "http://localhost").pathname;
511
- } catch {
512
- return pathname;
513
- }
514
- }
515
486
  function normalizePathForSecurity(pathname) {
516
- return normalizePathSeparators(normalizeLowercaseStringOrEmpty$1(resolveDotSegments(pathname))) || "/";
487
+ return normalizePathSeparators(normalizeLowercaseStringOrEmpty$1(URL.parse(pathname, "http://localhost")?.pathname ?? pathname)) || "/";
517
488
  }
518
- function buildCanonicalPathCandidates(pathname, maxDecodePasses = MAX_PATH_DECODE_PASSES) {
489
+ function buildCanonicalPathCandidates(pathname) {
519
490
  const candidates = /* @__PURE__ */ new Set([normalizePathForSecurity(pathname)]);
520
491
  let decoded = pathname;
521
492
  let malformedEncoding = false;
522
493
  let decodePasses = 0;
523
- for (let pass = 0; pass < maxDecodePasses; pass++) {
494
+ for (let pass = 0; pass < MAX_PATH_DECODE_PASSES; pass++) {
524
495
  let nextDecoded;
525
496
  try {
526
497
  nextDecoded = decodeURIComponent(decoded);
@@ -607,7 +578,7 @@ function resolveNextcloudTalkLegacyWebhook(config) {
607
578
  function describeNextcloudTalkWebhookRouteConflict(path, gatewayPort) {
608
579
  const pathname = URL.parse(path, "http://localhost")?.pathname ?? path;
609
580
  const probe = classifyGatewayProbePath(pathname);
610
- const reason = probe !== "outside" && probe !== "namespace" ? "is reserved for Gateway probes" : isProtectedPluginRoutePathFromContext(resolvePluginRoutePathContext(pathname)) ? "requires Gateway authentication" : void 0;
581
+ const reason = probe !== "outside" && probe !== "namespace" ? "is reserved for Gateway checks" : isProtectedPluginRoutePathFromContext(resolvePluginRoutePathContext(pathname)) ? "requires Gateway authentication" : void 0;
611
582
  if (!reason) return;
612
583
  return `Webhook path "${path}" ${reason} and cannot receive Nextcloud callbacks on the Gateway port. Set webhookPath to "${DEFAULT_NEXTCLOUD_TALK_WEBHOOK_PATH}" and update the Nextcloud bot callback and reverse-proxy upstream to Gateway port ${gatewayPort}${DEFAULT_NEXTCLOUD_TALK_WEBHOOK_PATH}.`;
613
584
  }
@@ -808,7 +779,7 @@ async function resolveNextcloudTalkRoomKind(params) {
808
779
  }
809
780
  },
810
781
  auditContext: "nextcloud-talk.room-info",
811
- policy: ssrfPolicyFromPrivateNetworkOptIn(account.config),
782
+ policy: ssrfPolicyFromPrivateNetworkOptIn(account.config.network?.dangerouslyAllowPrivateNetwork),
812
783
  timeoutMs: params.timeoutMs ?? NEXTCLOUD_TALK_ROOM_INFO_TIMEOUT_MS
813
784
  });
814
785
  } catch (error) {
@@ -865,7 +836,7 @@ function resolveNextcloudTalkSendContext(opts) {
865
836
  cfg,
866
837
  accountId: opts.accountId
867
838
  });
868
- const baseUrl = opts.baseUrl?.trim() ?? account.baseUrl;
839
+ const baseUrl = account.baseUrl;
869
840
  const secret = opts.secret?.trim() ?? account.secret;
870
841
  if (!baseUrl) throw new Error(`Nextcloud Talk baseUrl missing for account "${account.accountId}" (set channels.nextcloud-talk.baseUrl).`);
871
842
  if (!secret) throw new Error(account.tokenStatus === "configured_unavailable" ? `Nextcloud Talk bot secret is configured but unavailable for account "${account.accountId}" (check the configured channels.nextcloud-talk.botSecret/botSecretFile).` : `Nextcloud Talk bot secret missing for account "${account.accountId}" (set channels.nextcloud-talk.botSecret/botSecretFile or NEXTCLOUD_TALK_BOT_SECRET for default).`);
@@ -891,9 +862,10 @@ async function sendMessageNextcloudTalk(to, text, opts) {
891
862
  accountId: account.accountId
892
863
  });
893
864
  const message = convertMarkdownTables(text.trim(), tableMode);
894
- const body = { message };
895
- if (opts.replyTo) body.replyTo = opts.replyTo;
896
- const bodyStr = JSON.stringify(body);
865
+ const body = JSON.stringify({
866
+ message,
867
+ replyTo: opts.replyTo || void 0
868
+ });
897
869
  const { random, signature } = generateNextcloudTalkSignature({
898
870
  body: message,
899
871
  secret
@@ -911,10 +883,10 @@ async function sendMessageNextcloudTalk(to, text, opts) {
911
883
  "X-Nextcloud-Talk-Bot-Random": random,
912
884
  "X-Nextcloud-Talk-Bot-Signature": signature
913
885
  },
914
- body: bodyStr
886
+ body
915
887
  },
916
888
  auditContext: "nextcloud-talk-send",
917
- policy: ssrfPolicyFromPrivateNetworkOptIn$1(account.config),
889
+ policy: ssrfPolicyFromPrivateNetworkOptIn$1(account.config.network?.dangerouslyAllowPrivateNetwork),
918
890
  timeoutMs: opts.timeoutMs ?? NEXTCLOUD_TALK_SEND_TIMEOUT_MS
919
891
  });
920
892
  try {
@@ -936,7 +908,6 @@ async function sendMessageNextcloudTalk(to, text, opts) {
936
908
  if (data.ocs?.data?.id != null) messageId = String(data.ocs.data.id);
937
909
  if (typeof data.ocs?.data?.timestamp === "number") timestamp = data.ocs.data.timestamp;
938
910
  } catch {}
939
- if (opts.verbose) console.log(`[nextcloud-talk] Sent message ${messageId} to room ${roomToken}`);
940
911
  getOptionalNextcloudTalkRuntime()?.channel.activity.record({
941
912
  channel: "nextcloud-talk",
942
913
  accountId: account.accountId,
@@ -983,7 +954,7 @@ async function sendReactionNextcloudTalk(roomToken, messageId, reaction, opts) {
983
954
  body
984
955
  },
985
956
  auditContext: "nextcloud-talk-reaction",
986
- policy: ssrfPolicyFromPrivateNetworkOptIn$1(account.config),
957
+ policy: ssrfPolicyFromPrivateNetworkOptIn$1(account.config.network?.dangerouslyAllowPrivateNetwork),
987
958
  timeoutMs: opts.timeoutMs ?? NEXTCLOUD_TALK_SEND_TIMEOUT_MS
988
959
  });
989
960
  try {
@@ -1002,37 +973,6 @@ const CHANNEL_ID = "nextcloud-talk";
1002
973
  function hasAllowEntries(entries) {
1003
974
  return normalizeNextcloudTalkAllowlist(entries).length > 0;
1004
975
  }
1005
- function roomRoutes(params) {
1006
- if (!params.isGroup) return [];
1007
- const roomSenderConfigured = params.groupPolicy === "allowlist" && hasAllowEntries(params.roomAllowFrom);
1008
- return channelIngressRoutes(params.roomMatch.allowlistConfigured && {
1009
- id: "nextcloud-talk:room",
1010
- allowed: params.roomMatch.allowed,
1011
- precedence: 0,
1012
- matchId: "nextcloud-talk-room",
1013
- blockReason: "room_not_allowlisted"
1014
- }, params.roomConfig?.enabled === false && {
1015
- id: "nextcloud-talk:room-enabled",
1016
- enabled: false,
1017
- precedence: 10,
1018
- blockReason: "room_disabled"
1019
- }, roomSenderConfigured && {
1020
- id: "nextcloud-talk:room-sender",
1021
- kind: "nestedAllowlist",
1022
- precedence: 20,
1023
- blockReason: "room_sender_not_allowlisted",
1024
- ...!hasAllowEntries(params.outerGroupAllowFrom) ? {
1025
- senderPolicy: "replace",
1026
- senderAllowFrom: params.roomAllowFrom
1027
- } : {
1028
- allowed: resolveNextcloudTalkAllowlistMatch({
1029
- allowFrom: params.roomAllowFrom,
1030
- senderId: params.senderId
1031
- }).allowed,
1032
- matchId: "nextcloud-talk-room-sender"
1033
- }
1034
- });
1035
- }
1036
976
  async function handleNextcloudTalkInbound(params) {
1037
977
  const { message, account, config, runtime, statusSink } = params;
1038
978
  const core = getNextcloudTalkRuntime();
@@ -1105,15 +1045,33 @@ async function handleNextcloudTalkInbound(params) {
1105
1045
  id: isGroup ? roomToken : senderId
1106
1046
  },
1107
1047
  contextBinding,
1108
- route: roomRoutes({
1109
- isGroup,
1110
- groupPolicy,
1111
- roomMatch,
1112
- roomConfig,
1113
- senderId,
1114
- outerGroupAllowFrom,
1115
- roomAllowFrom
1116
- }),
1048
+ route: isGroup ? channelIngressRoutes(roomMatch.allowlistConfigured && {
1049
+ id: "nextcloud-talk:room",
1050
+ allowed: roomMatch.allowed,
1051
+ precedence: 0,
1052
+ matchId: "nextcloud-talk-room",
1053
+ blockReason: "room_not_allowlisted"
1054
+ }, roomConfig?.enabled === false && {
1055
+ id: "nextcloud-talk:room-enabled",
1056
+ enabled: false,
1057
+ precedence: 10,
1058
+ blockReason: "room_disabled"
1059
+ }, groupPolicy === "allowlist" && hasAllowEntries(roomAllowFrom) && {
1060
+ id: "nextcloud-talk:room-sender",
1061
+ kind: "nestedAllowlist",
1062
+ precedence: 20,
1063
+ blockReason: "room_sender_not_allowlisted",
1064
+ ...!hasAllowEntries(outerGroupAllowFrom) ? {
1065
+ senderPolicy: "replace",
1066
+ senderAllowFrom: roomAllowFrom
1067
+ } : {
1068
+ allowed: resolveNextcloudTalkAllowlistMatch({
1069
+ allowFrom: roomAllowFrom,
1070
+ senderId
1071
+ }).allowed,
1072
+ matchId: "nextcloud-talk-room-sender"
1073
+ }
1074
+ }) : [],
1117
1075
  dmPolicy: account.config.dmPolicy ?? "pairing",
1118
1076
  groupPolicy,
1119
1077
  policy: {
@@ -1192,7 +1150,7 @@ async function handleNextcloudTalkInbound(params) {
1192
1150
  }
1193
1151
  const mentionRegexes = core.channel.mentions.buildMentionRegexes(config);
1194
1152
  const wasMentioned = mentionRegexes.length ? core.channel.mentions.matchesMentionPatterns(rawBody, mentionRegexes) : false;
1195
- const { route, buildEnvelope } = resolveChannelInboundRouteEnvelope({
1153
+ const route = resolveAgentRoute({
1196
1154
  cfg: config,
1197
1155
  channel: CHANNEL_ID,
1198
1156
  accountId: account.accountId,
@@ -1212,7 +1170,10 @@ async function handleNextcloudTalkInbound(params) {
1212
1170
  return;
1213
1171
  }
1214
1172
  const fromLabel = isGroup ? `room:${roomName || roomToken}` : senderName || `user:${senderId}`;
1215
- const body = buildEnvelope({
1173
+ const body = (await createChannelInboundEnvelopeBuilderAsync({
1174
+ cfg: config,
1175
+ route
1176
+ }))({
1216
1177
  channel: "Nextcloud Talk",
1217
1178
  from: fromLabel,
1218
1179
  timestamp: message.timestamp,
@@ -1757,15 +1718,11 @@ function createNextcloudTalkWebhookSpool(options) {
1757
1718
  //#endregion
1758
1719
  //#region extensions/nextcloud-talk/src/monitor-runtime.ts
1759
1720
  function normalizeOrigin(value) {
1760
- try {
1761
- return normalizeLowercaseStringOrEmpty(new URL(value).origin);
1762
- } catch {
1763
- return null;
1764
- }
1721
+ return URL.parse(value)?.origin.toLowerCase() ?? null;
1765
1722
  }
1766
1723
  async function monitorNextcloudTalkProvider(opts) {
1767
1724
  const core = getNextcloudTalkRuntime();
1768
- const cfg = opts.config ?? core.config.current();
1725
+ const cfg = opts.config;
1769
1726
  const account = resolveNextcloudTalkAccount({
1770
1727
  cfg,
1771
1728
  accountId: opts.accountId
@@ -1782,7 +1739,7 @@ async function monitorNextcloudTalkProvider(opts) {
1782
1739
  accountId: account.accountId
1783
1740
  });
1784
1741
  const expectedBackendOrigin = normalizeOrigin(account.baseUrl);
1785
- const spool = (opts.createSpool ?? createNextcloudTalkWebhookSpool)({
1742
+ const spool = createNextcloudTalkWebhookSpool({
1786
1743
  accountId: account.accountId,
1787
1744
  runtime,
1788
1745
  abortSignal: opts.abortSignal,
@@ -1793,8 +1750,7 @@ async function monitorNextcloudTalkProvider(opts) {
1793
1750
  direction: "inbound",
1794
1751
  at: message.timestamp
1795
1752
  });
1796
- if (opts.onMessage) await opts.onMessage(message, lifecycle);
1797
- else await handleNextcloudTalkInbound({
1753
+ await handleNextcloudTalkInbound({
1798
1754
  message,
1799
1755
  account,
1800
1756
  config: cfg,
package/dist/api.js CHANGED
@@ -1,2 +1,2 @@
1
- import { t as nextcloudTalkPlugin } from "./.setup/channel-BrNxpO5S.mjs";
1
+ import { t as nextcloudTalkPlugin } from "./.setup/channel-DTKYMnlK.mjs";
2
2
  export { nextcloudTalkPlugin };
@@ -1,2 +1,2 @@
1
- import { t as nextcloudTalkPlugin } from "./.setup/channel-BrNxpO5S.mjs";
1
+ import { t as nextcloudTalkPlugin } from "./.setup/channel-DTKYMnlK.mjs";
2
2
  export { nextcloudTalkPlugin };
@@ -4,7 +4,7 @@ import { fileURLToPath } from "node:url";
4
4
  var setup_entry_default = defineBundledChannelSetupEntry({
5
5
  importMetaUrl: import.meta.url,
6
6
  plugin: {
7
- specifier: fileURLToPath(new URL(".setup/api-D0k6lqjU.mjs", import.meta.url).href),
7
+ specifier: fileURLToPath(new URL(".setup/api-DbUH-yZ4.mjs", import.meta.url).href),
8
8
  exportName: "nextcloudTalkPlugin"
9
9
  },
10
10
  secrets: {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openclaw/nextcloud-talk",
3
- "version": "2026.10.2",
3
+ "version": "2026.10.5-beta.2",
4
4
  "description": "OpenClaw Nextcloud Talk channel plugin for conversations.",
5
5
  "repository": {
6
6
  "type": "git",
@@ -8,7 +8,7 @@
8
8
  },
9
9
  "type": "module",
10
10
  "peerDependencies": {
11
- "openclaw": ">=2026.10.2"
11
+ "openclaw": ">=2026.10.5-beta.2"
12
12
  },
13
13
  "peerDependenciesMeta": {
14
14
  "openclaw": {
@@ -130,10 +130,10 @@
130
130
  "minHostVersion": ">=2026.4.10"
131
131
  },
132
132
  "compat": {
133
- "pluginApi": ">=2026.10.2"
133
+ "pluginApi": ">=2026.10.5-beta.2"
134
134
  },
135
135
  "build": {
136
- "openclawVersion": "2026.10.2"
136
+ "openclawVersion": "2026.10.5-beta.2"
137
137
  },
138
138
  "release": {
139
139
  "publishToClawHub": true,
@@ -1,3 +0,0 @@
1
- import { t as nextcloudTalkPlugin } from "./channel-BrNxpO5S.mjs";
2
- import "../api.js";
3
- export { nextcloudTalkPlugin };