@openclaw/nextcloud-talk 2026.7.2-beta.2 → 2026.7.2-beta.3

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/dist/api.js CHANGED
@@ -1,2 +1,2 @@
1
- import { t as nextcloudTalkPlugin } from "./channel-BSnehBf6.js";
1
+ import { t as nextcloudTalkPlugin } from "./channel-De2OKnzd.js";
2
2
  export { nextcloudTalkPlugin };
@@ -15,6 +15,7 @@ import { buildSecretInputSchema, hasConfiguredSecretInput, normalizeResolvedSecr
15
15
  import { formatErrorMessage } from "openclaw/plugin-sdk/error-runtime";
16
16
  import { parseStrictNonNegativeInteger, parseStrictPositiveInteger } from "openclaw/plugin-sdk/number-runtime";
17
17
  import { readProviderJsonResponse, readResponseTextLimited } from "openclaw/plugin-sdk/provider-http";
18
+ import { buildChannelInboundEventContext, resolveChannelInboundRouteEnvelope } from "openclaw/plugin-sdk/channel-inbound";
18
19
  import { createAccountStatusSink, createMessageReceiptFromOutboundResults, defineChannelMessageAdapter, resolveChannelStreamingBlockEnabled } from "openclaw/plugin-sdk/channel-outbound";
19
20
  import { ssrfPolicyFromPrivateNetworkOptIn, ssrfPolicyFromPrivateNetworkOptIn as ssrfPolicyFromPrivateNetworkOptIn$1 } from "openclaw/plugin-sdk/ssrf-runtime";
20
21
  import { requireRuntimeConfig } from "openclaw/plugin-sdk/plugin-config-runtime";
@@ -24,7 +25,7 @@ import { fileExists, safeEqualSecret } from "openclaw/plugin-sdk/security-runtim
24
25
  import { clearAccountEntryFields } from "openclaw/plugin-sdk/channel-plugin-common";
25
26
  import { DEFAULT_ACCOUNT_ID as DEFAULT_ACCOUNT_ID$2 } from "openclaw/plugin-sdk/account-id";
26
27
  import { DmPolicySchema, GroupPolicySchema, MarkdownConfigSchema, ReplyRuntimeConfigSchemaShape, buildChannelConfigSchema, buildGroupEntrySchema, buildMultiAccountChannelSchema, requireOpenAllowFrom } from "openclaw/plugin-sdk/channel-config-schema";
27
- import { formatAllowFromLowercase } from "openclaw/plugin-sdk/allow-from";
28
+ import { formatAllowFromLowercase, resolveAllowlistMatchByCandidates } from "openclaw/plugin-sdk/allow-from";
28
29
  import { adaptScopedAccountAccessor, createScopedChannelConfigAdapter, createScopedDmSecurityResolver } from "openclaw/plugin-sdk/channel-config-helpers";
29
30
  import { requireChannelOpenAllowFrom, resolveLoggerBackedRuntime, runStoppablePassiveMonitor, safeParseJsonWithSchema } from "openclaw/plugin-sdk/extension-shared";
30
31
  import { z } from "zod";
@@ -33,7 +34,6 @@ import path from "node:path";
33
34
  import { createChannelReplayGuard, migratePersistentDedupeLegacyJsonFile } from "openclaw/plugin-sdk/persistent-dedupe";
34
35
  import { resolveStateDir } from "openclaw/plugin-sdk/state-paths";
35
36
  import { channelIngressRoutes, resolveStableChannelMessageIngress } from "openclaw/plugin-sdk/channel-ingress-runtime";
36
- import { resolveInboundRouteEnvelopeBuilderWithRuntime } from "openclaw/plugin-sdk/inbound-envelope";
37
37
  import { buildChannelKeyCandidates, normalizeChannelSlug, resolveChannelEntryMatchWithFallback } from "openclaw/plugin-sdk/channel-targets";
38
38
  import { pruneMapToMaxSize } from "openclaw/plugin-sdk/collection-runtime";
39
39
  import { truncateUtf16Safe } from "openclaw/plugin-sdk/text-utility-runtime";
@@ -44,6 +44,37 @@ import { DEFAULT_ACCOUNT_ID as DEFAULT_ACCOUNT_ID$1, buildOutboundBaseSessionKey
44
44
  import { applyAccountNameToChannelSection, baseUrlTextInput, createSetupTranslator, createStandardChannelSetupStatus, defineTokenCredential, formatDocsLink, patchScopedAccountConfig, setSetupChannelEnabled } from "openclaw/plugin-sdk/setup";
45
45
  import { createSetupInputPresenceValidator, createSetupTranslator as createSetupTranslator$1, mergeAllowFromEntries, promptParsedAllowFromForAccount, resolveSetupAccountId } from "openclaw/plugin-sdk/setup-runtime";
46
46
  import { formatDocsLink as formatDocsLink$1 } from "openclaw/plugin-sdk/setup-tools";
47
+ //#region extensions/nextcloud-talk/src/api-credentials.ts
48
+ function resolveNextcloudTalkApiCredentialsResult(params) {
49
+ const apiUser = params.apiUser?.trim();
50
+ if (!apiUser) return { status: "missing" };
51
+ const inlinePassword = normalizeResolvedSecretInputString({
52
+ value: params.apiPassword,
53
+ path: "channels.nextcloud-talk.apiPassword"
54
+ });
55
+ if (inlinePassword) return {
56
+ status: "available",
57
+ value: {
58
+ apiUser,
59
+ apiPassword: inlinePassword
60
+ }
61
+ };
62
+ if (!params.apiPasswordFile?.trim()) return { status: "missing" };
63
+ const result = tryReadSecretFileSync(params.apiPasswordFile, "Nextcloud Talk API password", { rejectHardlinks: false }, { configPath: params.configPath ?? "channels.nextcloud-talk.apiPasswordFile" });
64
+ if (result.status === "available") return result.value ? {
65
+ status: "available",
66
+ value: {
67
+ apiUser,
68
+ apiPassword: result.value
69
+ }
70
+ } : { status: "missing" };
71
+ return result;
72
+ }
73
+ function resolveNextcloudTalkApiCredentials(params) {
74
+ const result = resolveNextcloudTalkApiCredentialsResult(params);
75
+ return result.status === "available" ? result.value : void 0;
76
+ }
77
+ //#endregion
47
78
  //#region extensions/nextcloud-talk/src/accounts.ts
48
79
  function isTruthyEnvValue(value) {
49
80
  const normalized = normalizeLowercaseStringOrEmpty(value);
@@ -79,13 +110,21 @@ function resolveNextcloudTalkSecret(cfg, opts) {
79
110
  const envSecret = normalizeOptionalString(process.env.NEXTCLOUD_TALK_BOT_SECRET);
80
111
  if (envSecret && resolvedAccountId === DEFAULT_ACCOUNT_ID) return {
81
112
  secret: envSecret,
82
- source: "env"
113
+ source: "env",
114
+ status: "available"
83
115
  };
84
- if (merged.botSecretFile) {
85
- const fileSecret = tryReadSecretFileSync(merged.botSecretFile, "Nextcloud Talk bot secret file", { rejectSymlink: true });
86
- if (fileSecret) return {
87
- secret: fileSecret,
88
- source: "secretFile"
116
+ const botSecretFile = normalizeOptionalString(merged.botSecretFile);
117
+ if (botSecretFile) {
118
+ const result = tryReadSecretFileSync(botSecretFile, "Nextcloud Talk bot secret file", { rejectSymlink: true }, { configPath: `channels.nextcloud-talk.accounts.${resolvedAccountId}.botSecretFile` });
119
+ return result.status === "available" ? {
120
+ secret: result.value,
121
+ source: "secretFile",
122
+ status: "available"
123
+ } : {
124
+ secret: "",
125
+ source: "secretFile",
126
+ status: "configured_unavailable",
127
+ diagnostic: result.diagnostic
89
128
  };
90
129
  }
91
130
  const inlineSecret = normalizeResolvedSecretInputString({
@@ -94,11 +133,13 @@ function resolveNextcloudTalkSecret(cfg, opts) {
94
133
  });
95
134
  if (inlineSecret) return {
96
135
  secret: inlineSecret,
97
- source: "config"
136
+ source: "config",
137
+ status: "available"
98
138
  };
99
139
  return {
100
140
  secret: "",
101
- source: "none"
141
+ source: "none",
142
+ status: "missing"
102
143
  };
103
144
  }
104
145
  function resolveNextcloudTalkAccount(params) {
@@ -109,6 +150,13 @@ function resolveNextcloudTalkAccount(params) {
109
150
  const accountEnabled = merged.enabled !== false;
110
151
  const enabled = baseEnabled && accountEnabled;
111
152
  const secretResolution = resolveNextcloudTalkSecret(params.cfg, { accountId });
153
+ const apiCredentialResolution = resolveNextcloudTalkApiCredentialsResult({
154
+ apiUser: merged.apiUser,
155
+ apiPassword: merged.apiPassword,
156
+ apiPasswordFile: merged.apiPasswordFile,
157
+ configPath: `channels.nextcloud-talk.accounts.${accountId}.apiPasswordFile`
158
+ });
159
+ const diagnostics = [secretResolution.diagnostic, apiCredentialResolution.status === "configured_unavailable" ? apiCredentialResolution.diagnostic : void 0].filter((diagnostic) => Boolean(diagnostic));
112
160
  const baseUrl = merged.baseUrl?.trim()?.replace(/\/$/, "") ?? "";
113
161
  debugAccounts("resolve", {
114
162
  accountId,
@@ -123,6 +171,9 @@ function resolveNextcloudTalkAccount(params) {
123
171
  baseUrl,
124
172
  secret: secretResolution.secret,
125
173
  secretSource: secretResolution.source,
174
+ tokenStatus: secretResolution.status,
175
+ apiCredentialStatus: apiCredentialResolution.status,
176
+ ...diagnostics.length > 0 ? { credentialDiagnostics: diagnostics } : {},
126
177
  config: merged
127
178
  };
128
179
  };
@@ -130,7 +181,7 @@ function resolveNextcloudTalkAccount(params) {
130
181
  accountId: resolvedAccountId,
131
182
  normalizeAccountId,
132
183
  resolvePrimary: resolve,
133
- hasCredential: (account) => account.secretSource !== "none",
184
+ hasCredential: (account) => account.tokenStatus !== "missing",
134
185
  resolveDefaultAccountId: () => resolveDefaultNextcloudTalkAccountId(params.cfg)
135
186
  });
136
187
  }
@@ -150,30 +201,6 @@ const nextcloudTalkApprovalAuth = createChannelApprovalAuth({
150
201
  normalizeApprover: normalizeNextcloudTalkApproverId
151
202
  }).approvalAuth;
152
203
  //#endregion
153
- //#region extensions/nextcloud-talk/src/api-credentials.ts
154
- function resolveNextcloudTalkApiCredentials(params) {
155
- const apiUser = params.apiUser?.trim();
156
- if (!apiUser) return;
157
- const inlinePassword = normalizeResolvedSecretInputString({
158
- value: params.apiPassword,
159
- path: "channels.nextcloud-talk.apiPassword"
160
- });
161
- if (inlinePassword) return {
162
- apiUser,
163
- apiPassword: inlinePassword
164
- };
165
- if (!params.apiPasswordFile) return;
166
- try {
167
- const fileValue = tryReadSecretFileSync(params.apiPasswordFile, "Nextcloud Talk API password", { rejectHardlinks: false });
168
- return fileValue ? {
169
- apiUser,
170
- apiPassword: fileValue
171
- } : void 0;
172
- } catch {
173
- return;
174
- }
175
- }
176
- //#endregion
177
204
  //#region extensions/nextcloud-talk/src/signature.ts
178
205
  const SIGNATURE_HEADER = "x-nextcloud-talk-signature";
179
206
  const RANDOM_HEADER = "x-nextcloud-talk-random";
@@ -513,19 +540,13 @@ function normalizeNextcloudTalkAllowlist(values) {
513
540
  return (values ?? []).map((value) => normalizeNextcloudTalkAllowEntry(String(value))).filter(Boolean);
514
541
  }
515
542
  function resolveNextcloudTalkAllowlistMatch(params) {
516
- const allowFrom = normalizeNextcloudTalkAllowlist(params.allowFrom);
517
- if (allowFrom.length === 0) return { allowed: false };
518
- if (allowFrom.includes("*")) return {
519
- allowed: true,
520
- matchKey: "*",
521
- matchSource: "wildcard"
522
- };
523
- const senderId = normalizeNextcloudTalkAllowEntry(params.senderId);
524
- return allowFrom.includes(senderId) ? {
525
- allowed: true,
526
- matchKey: senderId,
527
- matchSource: "id"
528
- } : { allowed: false };
543
+ return resolveAllowlistMatchByCandidates({
544
+ allowList: normalizeNextcloudTalkAllowlist(params.allowFrom),
545
+ candidates: [{
546
+ value: normalizeNextcloudTalkAllowEntry(params.senderId),
547
+ source: "id"
548
+ }]
549
+ });
529
550
  }
530
551
  function resolveNextcloudTalkRoomMatch(params) {
531
552
  const rooms = params.rooms ?? {};
@@ -1077,19 +1098,17 @@ async function handleNextcloudTalkInbound(params) {
1077
1098
  runtime.log?.(`nextcloud-talk: drop room ${roomToken} (no mention)`);
1078
1099
  return;
1079
1100
  }
1080
- const { route, buildEnvelope } = resolveInboundRouteEnvelopeBuilderWithRuntime({
1101
+ const { route, buildEnvelope } = resolveChannelInboundRouteEnvelope({
1081
1102
  cfg: config,
1082
1103
  channel: CHANNEL_ID,
1083
1104
  accountId: account.accountId,
1084
1105
  peer: {
1085
1106
  kind: isGroup ? "group" : "direct",
1086
1107
  id: isGroup ? roomToken : senderId
1087
- },
1088
- runtime: core.channel,
1089
- sessionStore: config.session?.store
1108
+ }
1090
1109
  });
1091
1110
  const fromLabel = isGroup ? `room:${roomName || roomToken}` : senderName || `user:${senderId}`;
1092
- const { storePath, body } = buildEnvelope({
1111
+ const body = buildEnvelope({
1093
1112
  channel: "Nextcloud Talk",
1094
1113
  from: fromLabel,
1095
1114
  timestamp: message.timestamp,
@@ -1097,40 +1116,58 @@ async function handleNextcloudTalkInbound(params) {
1097
1116
  });
1098
1117
  const groupSystemPrompt = normalizeOptionalString(roomConfig?.systemPrompt);
1099
1118
  const blockStreamingEnabled = resolveChannelStreamingBlockEnabled(account.config);
1100
- const ctxPayload = core.channel.reply.finalizeInboundContext({
1101
- Body: body,
1102
- BodyForAgent: rawBody,
1103
- RawBody: rawBody,
1104
- CommandBody: rawBody,
1105
- From: isGroup ? `nextcloud-talk:room:${roomToken}` : `nextcloud-talk:${senderId}`,
1106
- To: `nextcloud-talk:${roomToken}`,
1107
- SessionKey: route.sessionKey,
1108
- AccountId: route.accountId,
1109
- ChatType: isGroup ? "group" : "direct",
1110
- ConversationLabel: fromLabel,
1111
- SenderName: senderName || void 0,
1112
- SenderId: senderId,
1113
- GroupSubject: isGroup ? roomName || roomToken : void 0,
1114
- GroupSystemPrompt: isGroup ? groupSystemPrompt : void 0,
1115
- Provider: CHANNEL_ID,
1116
- Surface: CHANNEL_ID,
1117
- WasMentioned: isGroup ? wasMentioned : void 0,
1118
- MessageSid: message.messageId,
1119
- Timestamp: message.timestamp,
1120
- OriginatingChannel: CHANNEL_ID,
1121
- OriginatingTo: `nextcloud-talk:${roomToken}`,
1122
- CommandAuthorized: commandAuthorized
1119
+ const ctxPayload = buildChannelInboundEventContext({
1120
+ channel: CHANNEL_ID,
1121
+ accountId: route.accountId,
1122
+ messageId: message.messageId,
1123
+ timestamp: message.timestamp,
1124
+ from: isGroup ? `nextcloud-talk:room:${roomToken}` : `nextcloud-talk:${senderId}`,
1125
+ sender: {
1126
+ id: senderId,
1127
+ name: senderName || void 0
1128
+ },
1129
+ conversation: {
1130
+ kind: isGroup ? "group" : "direct",
1131
+ id: roomToken,
1132
+ label: fromLabel
1133
+ },
1134
+ route: {
1135
+ agentId: route.agentId,
1136
+ dmScope: route.dmScope,
1137
+ accountId: route.accountId,
1138
+ routeSessionKey: route.sessionKey
1139
+ },
1140
+ reply: {
1141
+ to: `nextcloud-talk:${roomToken}`,
1142
+ originatingTo: `nextcloud-talk:${roomToken}`
1143
+ },
1144
+ message: {
1145
+ body,
1146
+ bodyForAgent: rawBody,
1147
+ rawBody,
1148
+ commandBody: rawBody
1149
+ },
1150
+ access: {
1151
+ commands: { authorized: commandAuthorized },
1152
+ mentions: {
1153
+ canDetectMention: isGroup,
1154
+ wasMentioned: isGroup && wasMentioned
1155
+ }
1156
+ },
1157
+ extra: {
1158
+ GroupSubject: isGroup ? roomName || roomToken : void 0,
1159
+ GroupSystemPrompt: isGroup ? groupSystemPrompt : void 0
1160
+ }
1123
1161
  });
1124
- await core.channel.inbound.dispatchReply({
1162
+ await core.channel.inbound.dispatch({
1125
1163
  cfg: config,
1126
1164
  channel: CHANNEL_ID,
1127
1165
  accountId: account.accountId,
1128
- agentId: route.agentId,
1129
- routeSessionKey: route.sessionKey,
1130
- storePath,
1166
+ route: {
1167
+ agentId: route.agentId,
1168
+ sessionKey: route.sessionKey
1169
+ },
1131
1170
  ctxPayload,
1132
- recordInboundSession: core.channel.session.recordInboundSession,
1133
- dispatchReplyWithBufferedBlockDispatcher: core.channel.reply.dispatchReplyWithBufferedBlockDispatcher,
1134
1171
  delivery: {
1135
1172
  preparePayload: (payload) => payload.text === void 0 ? payload : {
1136
1173
  ...payload,
@@ -1992,12 +2029,14 @@ const nextcloudTalkPlugin = createChatChannelPlugin({
1992
2029
  configSchema: buildChannelConfigSchema(NextcloudTalkConfigSchema),
1993
2030
  config: {
1994
2031
  ...nextcloudTalkConfigAdapter,
1995
- isConfigured: (account) => Boolean(account.secret?.trim() && account.baseUrl?.trim()),
2032
+ isConfigured: (account) => Boolean(account.tokenStatus !== "missing" && account.baseUrl?.trim()),
1996
2033
  describeAccount: (account) => describeWebhookAccountSnapshot({
1997
2034
  account,
1998
- configured: Boolean(account.secret?.trim() && account.baseUrl?.trim()),
2035
+ configured: Boolean(account.tokenStatus !== "missing" && account.baseUrl?.trim()),
1999
2036
  extra: {
2000
2037
  secretSource: account.secretSource,
2038
+ tokenStatus: account.tokenStatus,
2039
+ apiCredentialStatus: account.apiCredentialStatus,
2001
2040
  baseUrl: account.baseUrl ? "[set]" : "[missing]"
2002
2041
  }
2003
2042
  })
@@ -2048,9 +2087,11 @@ const nextcloudTalkPlugin = createChatChannelPlugin({
2048
2087
  accountId: account.accountId,
2049
2088
  name: account.name,
2050
2089
  enabled: account.enabled,
2051
- configured: Boolean(account.secret?.trim() && account.baseUrl?.trim()),
2090
+ configured: Boolean(account.tokenStatus !== "missing" && account.baseUrl?.trim()),
2052
2091
  extra: {
2053
2092
  secretSource: account.secretSource,
2093
+ tokenStatus: account.tokenStatus,
2094
+ apiCredentialStatus: account.apiCredentialStatus,
2054
2095
  baseUrl: account.baseUrl ? "[set]" : "[missing]",
2055
2096
  mode: "webhook"
2056
2097
  }
@@ -1,2 +1,2 @@
1
- import { t as nextcloudTalkPlugin } from "./channel-BSnehBf6.js";
1
+ import { t as nextcloudTalkPlugin } from "./channel-De2OKnzd.js";
2
2
  export { nextcloudTalkPlugin };
@@ -1,17 +1,17 @@
1
1
  {
2
2
  "name": "@openclaw/nextcloud-talk",
3
- "version": "2026.7.2-beta.2",
3
+ "version": "2026.7.2-beta.3",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "@openclaw/nextcloud-talk",
9
- "version": "2026.7.2-beta.2",
9
+ "version": "2026.7.2-beta.3",
10
10
  "dependencies": {
11
11
  "zod": "4.4.3"
12
12
  },
13
13
  "peerDependencies": {
14
- "openclaw": ">=2026.7.2-beta.2"
14
+ "openclaw": ">=2026.7.2-beta.3"
15
15
  },
16
16
  "peerDependenciesMeta": {
17
17
  "openclaw": {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openclaw/nextcloud-talk",
3
- "version": "2026.7.2-beta.2",
3
+ "version": "2026.7.2-beta.3",
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.7.2-beta.2"
11
+ "openclaw": ">=2026.7.2-beta.3"
12
12
  },
13
13
  "peerDependenciesMeta": {
14
14
  "openclaw": {
@@ -40,10 +40,10 @@
40
40
  "minHostVersion": ">=2026.4.10"
41
41
  },
42
42
  "compat": {
43
- "pluginApi": ">=2026.7.2-beta.2"
43
+ "pluginApi": ">=2026.7.2-beta.3"
44
44
  },
45
45
  "build": {
46
- "openclawVersion": "2026.7.2-beta.2"
46
+ "openclawVersion": "2026.7.2-beta.3"
47
47
  },
48
48
  "release": {
49
49
  "publishToClawHub": true,