@openclaw/nextcloud-talk 2026.7.1 → 2026.7.2-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.
- package/dist/api.js +1 -1
- package/dist/{channel-BMKRTDSP.js → channel-CYse6FwT.js} +89 -78
- package/dist/channel-plugin-api.js +1 -1
- package/dist/doctor-contract-api.js +1 -1
- package/dist/doctor-contract-fNhK1wag.js +22 -0
- package/dist/{secret-contract-CsCJ-vOP.js → secret-contract-DGgvfVqm.js} +6 -47
- package/dist/secret-contract-api.js +1 -1
- package/npm-shrinkwrap.json +3 -3
- package/openclaw.plugin.json +72 -48
- package/package.json +4 -4
- package/dist/doctor-contract-BY7I5-v9.js +0 -7
package/dist/api.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { t as nextcloudTalkPlugin } from "./channel-
|
|
1
|
+
import { t as nextcloudTalkPlugin } from "./channel-CYse6FwT.js";
|
|
2
2
|
export { nextcloudTalkPlugin };
|
|
@@ -1,26 +1,27 @@
|
|
|
1
1
|
import { a as fetchWithSsrFGuard, c as resolveDefaultGroupPolicy, i as deliverFormattedTextWithAttachments, l as warnMissingProviderGroupPolicyFallbackOnce, o as logInboundDrop, r as createChannelPairingController, s as resolveAllowlistProviderRuntimeGroupPolicy, t as GROUP_POLICY_BLOCKED_LABEL, u as getNextcloudTalkRuntime } from "./runtime-api-BKsxTw4J.js";
|
|
2
|
-
import { n as normalizeCompatibilityConfig, t as legacyConfigRules } from "./doctor-contract-
|
|
3
|
-
import { n as collectRuntimeConfigAssignments, r as secretTargetRegistryEntries } from "./secret-contract-
|
|
2
|
+
import { n as normalizeCompatibilityConfig, t as legacyConfigRules } from "./doctor-contract-fNhK1wag.js";
|
|
3
|
+
import { n as collectRuntimeConfigAssignments, r as secretTargetRegistryEntries } from "./secret-contract-DGgvfVqm.js";
|
|
4
4
|
import { describeWebhookAccountSnapshot } from "openclaw/plugin-sdk/account-helpers";
|
|
5
5
|
import { createChatChannelPlugin } from "openclaw/plugin-sdk/channel-core";
|
|
6
6
|
import { createLoggedPairingApprovalNotifier, createPairingPrefixStripper } from "openclaw/plugin-sdk/channel-pairing";
|
|
7
|
-
import { createAllowlistProviderRouteAllowlistWarningCollector } from "openclaw/plugin-sdk/channel-policy";
|
|
7
|
+
import { createAllowlistProviderRouteAllowlistWarningCollector, resolveScopeRequireMention, resolveScopeToolsPolicy } from "openclaw/plugin-sdk/channel-policy";
|
|
8
8
|
import { buildWebhookChannelStatusSummary, createComputedAccountStatusAdapter, createDefaultChannelRuntimeState } from "openclaw/plugin-sdk/status-helpers";
|
|
9
|
+
import { convertMarkdownTables, sanitizeAssistantVisibleText } from "openclaw/plugin-sdk/text-chunking";
|
|
10
|
+
import { createChannelApprovalAuth } from "openclaw/plugin-sdk/approval-auth-runtime";
|
|
11
|
+
import { normalizeLowercaseStringOrEmpty, normalizeOptionalLowercaseString, normalizeOptionalString, normalizeStringEntries } from "openclaw/plugin-sdk/string-coerce-runtime";
|
|
9
12
|
import { DEFAULT_ACCOUNT_ID, createAccountListHelpers, hasConfiguredAccountValue, normalizeAccountId, resolveAccountWithDefaultFallback, resolveMergedAccountConfig } from "openclaw/plugin-sdk/account-core";
|
|
10
13
|
import { tryReadSecretFileSync } from "openclaw/plugin-sdk/secret-file-runtime";
|
|
11
|
-
import { normalizeLowercaseStringOrEmpty, normalizeOptionalLowercaseString, normalizeOptionalString, normalizeStringEntries } from "openclaw/plugin-sdk/string-coerce-runtime";
|
|
12
14
|
import { buildSecretInputSchema, hasConfiguredSecretInput, normalizeResolvedSecretInputString } from "openclaw/plugin-sdk/secret-input";
|
|
13
|
-
import { createResolvedApproverActionAuthAdapter, resolveApprovalApprovers } from "openclaw/plugin-sdk/approval-auth-runtime";
|
|
14
15
|
import { formatErrorMessage } from "openclaw/plugin-sdk/error-runtime";
|
|
15
16
|
import { parseStrictNonNegativeInteger, parseStrictPositiveInteger } from "openclaw/plugin-sdk/number-runtime";
|
|
16
17
|
import { readProviderJsonResponse, readResponseTextLimited } from "openclaw/plugin-sdk/provider-http";
|
|
17
|
-
import { createAccountStatusSink, createMessageReceiptFromOutboundResults, defineChannelMessageAdapter } from "openclaw/plugin-sdk/channel-outbound";
|
|
18
|
+
import { createAccountStatusSink, createMessageReceiptFromOutboundResults, defineChannelMessageAdapter, resolveChannelStreamingBlockEnabled } from "openclaw/plugin-sdk/channel-outbound";
|
|
18
19
|
import { ssrfPolicyFromPrivateNetworkOptIn, ssrfPolicyFromPrivateNetworkOptIn as ssrfPolicyFromPrivateNetworkOptIn$1 } from "openclaw/plugin-sdk/ssrf-runtime";
|
|
19
20
|
import { readFileSync } from "node:fs";
|
|
20
21
|
import { requireRuntimeConfig } from "openclaw/plugin-sdk/plugin-config-runtime";
|
|
21
22
|
import { resolveMarkdownTableMode } from "openclaw/plugin-sdk/markdown-table-runtime";
|
|
22
|
-
import {
|
|
23
|
-
import {
|
|
23
|
+
import { createHmac, randomBytes } from "node:crypto";
|
|
24
|
+
import { safeEqualSecret } from "openclaw/plugin-sdk/security-runtime";
|
|
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, ToolPolicySchema, buildChannelConfigSchema, requireOpenAllowFrom } from "openclaw/plugin-sdk/channel-config-schema";
|
|
@@ -35,8 +36,9 @@ import { createClaimableDedupe, migratePersistentDedupeLegacyJsonFile } from "op
|
|
|
35
36
|
import { resolveStateDir } from "openclaw/plugin-sdk/state-paths";
|
|
36
37
|
import { channelIngressRoutes, resolveStableChannelMessageIngress } from "openclaw/plugin-sdk/channel-ingress-runtime";
|
|
37
38
|
import { resolveInboundRouteEnvelopeBuilderWithRuntime } from "openclaw/plugin-sdk/inbound-envelope";
|
|
38
|
-
import { buildChannelKeyCandidates, normalizeChannelSlug, resolveChannelEntryMatchWithFallback
|
|
39
|
+
import { buildChannelKeyCandidates, normalizeChannelSlug, resolveChannelEntryMatchWithFallback } from "openclaw/plugin-sdk/channel-targets";
|
|
39
40
|
import { pruneMapToMaxSize } from "openclaw/plugin-sdk/collection-runtime";
|
|
41
|
+
import { truncateUtf16Safe } from "openclaw/plugin-sdk/text-utility-runtime";
|
|
40
42
|
import { createServer } from "node:http";
|
|
41
43
|
import { WEBHOOK_RATE_LIMIT_DEFAULTS, createAuthRateLimiter, isRequestBodyLimitError, readRequestBodyWithLimit, requestBodyErrorToText } from "openclaw/plugin-sdk/webhook-ingress";
|
|
42
44
|
import { jsonResult, readStringParam, resolveReactionMessageId } from "openclaw/plugin-sdk/channel-actions";
|
|
@@ -139,19 +141,16 @@ function resolveNextcloudTalkAccount(params) {
|
|
|
139
141
|
function normalizeNextcloudTalkApproverId(value) {
|
|
140
142
|
return normalizeOptionalLowercaseString(String(value).trim().replace(/^(nextcloud-talk|nc-talk|nc):/i, ""));
|
|
141
143
|
}
|
|
142
|
-
const nextcloudTalkApprovalAuth =
|
|
144
|
+
const nextcloudTalkApprovalAuth = createChannelApprovalAuth({
|
|
143
145
|
channelLabel: "Nextcloud Talk",
|
|
144
|
-
|
|
145
|
-
return
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
}).config.allowFrom,
|
|
150
|
-
normalizeApprover: normalizeNextcloudTalkApproverId
|
|
151
|
-
});
|
|
146
|
+
resolveInputs: ({ cfg, accountId }) => {
|
|
147
|
+
return { allowFrom: resolveNextcloudTalkAccount({
|
|
148
|
+
cfg,
|
|
149
|
+
accountId
|
|
150
|
+
}).config.allowFrom };
|
|
152
151
|
},
|
|
153
|
-
|
|
154
|
-
});
|
|
152
|
+
normalizeApprover: normalizeNextcloudTalkApproverId
|
|
153
|
+
}).approvalAuth;
|
|
155
154
|
//#endregion
|
|
156
155
|
//#region extensions/nextcloud-talk/src/api-credentials.ts
|
|
157
156
|
function resolveNextcloudTalkApiCredentials(params) {
|
|
@@ -188,16 +187,7 @@ const BACKEND_HEADER = "x-nextcloud-talk-backend";
|
|
|
188
187
|
function verifyNextcloudTalkSignature(params) {
|
|
189
188
|
const { signature, random, body, secret } = params;
|
|
190
189
|
if (!signature || !random || !secret) return false;
|
|
191
|
-
|
|
192
|
-
const expectedBuf = Buffer.from(expected, "utf8");
|
|
193
|
-
const signatureBuf = Buffer.from(signature, "utf8");
|
|
194
|
-
const maxLen = Math.max(expectedBuf.length, signatureBuf.length);
|
|
195
|
-
const paddedExpected = Buffer.alloc(maxLen);
|
|
196
|
-
const paddedSignature = Buffer.alloc(maxLen);
|
|
197
|
-
expectedBuf.copy(paddedExpected);
|
|
198
|
-
signatureBuf.copy(paddedSignature);
|
|
199
|
-
const timingResult = timingSafeEqual(paddedExpected, paddedSignature);
|
|
200
|
-
return expectedBuf.length === signatureBuf.length && timingResult;
|
|
190
|
+
return safeEqualSecret(signature, createHmac("sha256", secret).update(random + body).digest("hex"));
|
|
201
191
|
}
|
|
202
192
|
/**
|
|
203
193
|
* Extract webhook headers from an incoming request.
|
|
@@ -592,12 +582,11 @@ function resolveNextcloudTalkAllowlistMatch(params) {
|
|
|
592
582
|
matchSource: "wildcard"
|
|
593
583
|
};
|
|
594
584
|
const senderId = normalizeNextcloudTalkAllowEntry(params.senderId);
|
|
595
|
-
|
|
585
|
+
return allowFrom.includes(senderId) ? {
|
|
596
586
|
allowed: true,
|
|
597
587
|
matchKey: senderId,
|
|
598
588
|
matchSource: "id"
|
|
599
|
-
};
|
|
600
|
-
return { allowed: false };
|
|
589
|
+
} : { allowed: false };
|
|
601
590
|
}
|
|
602
591
|
function resolveNextcloudTalkRoomMatch(params) {
|
|
603
592
|
const rooms = params.rooms ?? {};
|
|
@@ -609,12 +598,7 @@ function resolveNextcloudTalkRoomMatch(params) {
|
|
|
609
598
|
normalizeKey: normalizeChannelSlug
|
|
610
599
|
});
|
|
611
600
|
const roomConfig = match.entry;
|
|
612
|
-
const allowed =
|
|
613
|
-
outerConfigured: allowlistConfigured,
|
|
614
|
-
outerMatched: Boolean(roomConfig),
|
|
615
|
-
innerConfigured: false,
|
|
616
|
-
innerMatched: false
|
|
617
|
-
});
|
|
601
|
+
const allowed = !allowlistConfigured || Boolean(roomConfig);
|
|
618
602
|
return {
|
|
619
603
|
roomConfig,
|
|
620
604
|
wildcardConfig: match.wildcardEntry,
|
|
@@ -625,25 +609,52 @@ function resolveNextcloudTalkRoomMatch(params) {
|
|
|
625
609
|
};
|
|
626
610
|
}
|
|
627
611
|
function resolveNextcloudTalkGroupToolPolicy(params) {
|
|
628
|
-
const cfg = params.cfg;
|
|
629
612
|
const roomToken = params.groupId?.trim();
|
|
630
613
|
if (!roomToken) return;
|
|
631
|
-
const
|
|
632
|
-
|
|
633
|
-
|
|
614
|
+
const { tree, toolsPath } = buildNextcloudTalkRoomScope(resolveNextcloudTalkAccount({
|
|
615
|
+
cfg: params.cfg,
|
|
616
|
+
accountId: params.accountId
|
|
617
|
+
}).config.rooms, roomToken);
|
|
618
|
+
return resolveScopeToolsPolicy({
|
|
619
|
+
tree,
|
|
620
|
+
path: toolsPath
|
|
634
621
|
});
|
|
635
|
-
return match.roomConfig?.tools ?? match.wildcardConfig?.tools;
|
|
636
622
|
}
|
|
637
|
-
function
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
623
|
+
function buildNextcloudTalkRoomScope(rooms, roomToken) {
|
|
624
|
+
const { "*": defaults, ...scopes } = rooms ?? {};
|
|
625
|
+
const tree = {
|
|
626
|
+
defaults,
|
|
627
|
+
scopes
|
|
628
|
+
};
|
|
629
|
+
const exactPath = Object.hasOwn(scopes, roomToken) ? [roomToken] : [];
|
|
630
|
+
const toolsMatch = resolveChannelEntryMatchWithFallback({
|
|
631
|
+
entries: scopes,
|
|
632
|
+
keys: buildChannelKeyCandidates(roomToken),
|
|
633
|
+
normalizeKey: normalizeChannelSlug
|
|
634
|
+
});
|
|
635
|
+
return {
|
|
636
|
+
tree,
|
|
637
|
+
exactPath,
|
|
638
|
+
toolsPath: toolsMatch.matchKey ? [toolsMatch.matchKey] : []
|
|
639
|
+
};
|
|
640
|
+
}
|
|
641
|
+
function resolveNextcloudTalkGroupRequireMention(params) {
|
|
642
|
+
if (!params.groupId) return true;
|
|
643
|
+
const { tree, exactPath } = buildNextcloudTalkRoomScope(resolveNextcloudTalkAccount({
|
|
644
|
+
cfg: params.cfg,
|
|
645
|
+
accountId: params.accountId
|
|
646
|
+
}).config.rooms, params.groupId);
|
|
647
|
+
return resolveScopeRequireMention({
|
|
648
|
+
tree,
|
|
649
|
+
path: exactPath
|
|
650
|
+
});
|
|
641
651
|
}
|
|
642
652
|
//#endregion
|
|
643
653
|
//#region extensions/nextcloud-talk/src/room-info.ts
|
|
644
654
|
const ROOM_CACHE_TTL_MS = 300 * 1e3;
|
|
645
655
|
const ROOM_CACHE_ERROR_TTL_MS = 30 * 1e3;
|
|
646
656
|
const ROOM_CACHE_MAX_ENTRIES = 1e3;
|
|
657
|
+
const NEXTCLOUD_TALK_ROOM_INFO_TIMEOUT_MS = 3e4;
|
|
647
658
|
const roomCache = /* @__PURE__ */ new Map();
|
|
648
659
|
function resolveRoomCacheKey(params) {
|
|
649
660
|
return `${params.accountId}:${params.roomToken}`;
|
|
@@ -695,7 +706,8 @@ async function resolveNextcloudTalkRoomKind(params) {
|
|
|
695
706
|
}
|
|
696
707
|
},
|
|
697
708
|
auditContext: "nextcloud-talk.room-info",
|
|
698
|
-
policy: ssrfPolicyFromPrivateNetworkOptIn(account.config)
|
|
709
|
+
policy: ssrfPolicyFromPrivateNetworkOptIn(account.config),
|
|
710
|
+
timeoutMs: params.timeoutMs ?? NEXTCLOUD_TALK_ROOM_INFO_TIMEOUT_MS
|
|
699
711
|
});
|
|
700
712
|
try {
|
|
701
713
|
if (!response.ok) {
|
|
@@ -730,10 +742,10 @@ function stripNextcloudTalkTargetPrefix(raw) {
|
|
|
730
742
|
const trimmed = raw.trim();
|
|
731
743
|
if (!trimmed) return;
|
|
732
744
|
let normalized = trimmed;
|
|
733
|
-
if (
|
|
734
|
-
else if (
|
|
735
|
-
else if (
|
|
736
|
-
if (
|
|
745
|
+
if (/^nextcloud-talk:/i.test(normalized)) normalized = normalized.slice(15).trim();
|
|
746
|
+
else if (/^nc-talk:/i.test(normalized)) normalized = normalized.slice(8).trim();
|
|
747
|
+
else if (/^nc:/i.test(normalized)) normalized = normalized.slice(3).trim();
|
|
748
|
+
if (/^room:/i.test(normalized)) normalized = normalized.slice(5).trim();
|
|
737
749
|
if (!normalized) return;
|
|
738
750
|
return normalized;
|
|
739
751
|
}
|
|
@@ -744,17 +756,18 @@ function normalizeNextcloudTalkMessagingTarget(raw) {
|
|
|
744
756
|
function looksLikeNextcloudTalkTargetId(raw) {
|
|
745
757
|
const trimmed = raw.trim();
|
|
746
758
|
if (!trimmed) return false;
|
|
747
|
-
if (/^(nextcloud-talk|nc-talk|nc):/i.test(trimmed)) return true;
|
|
759
|
+
if (/^(nextcloud-talk|nc-talk|nc|room):/i.test(trimmed)) return true;
|
|
748
760
|
return /^[a-z0-9]{8,}$/i.test(trimmed);
|
|
749
761
|
}
|
|
750
762
|
//#endregion
|
|
751
763
|
//#region extensions/nextcloud-talk/src/send.ts
|
|
752
764
|
const NEXTCLOUD_TALK_ERROR_SNIPPET_MAX_BYTES = 8 * 1024;
|
|
753
765
|
const NEXTCLOUD_TALK_ERROR_SNIPPET_MAX_CHARS = 200;
|
|
766
|
+
const NEXTCLOUD_TALK_SEND_TIMEOUT_MS = 3e4;
|
|
754
767
|
/** Collapses whitespace and caps an error-body prefix to a short, log-safe snippet. */
|
|
755
768
|
function collapseErrorSnippet(text) {
|
|
756
769
|
const collapsed = text.replace(/\s+/g, " ").trim();
|
|
757
|
-
if (collapsed.length > NEXTCLOUD_TALK_ERROR_SNIPPET_MAX_CHARS) return `${collapsed
|
|
770
|
+
if (collapsed.length > NEXTCLOUD_TALK_ERROR_SNIPPET_MAX_CHARS) return `${truncateUtf16Safe(collapsed, NEXTCLOUD_TALK_ERROR_SNIPPET_MAX_CHARS)}…`;
|
|
758
771
|
return collapsed;
|
|
759
772
|
}
|
|
760
773
|
/** Reads a bounded, collapsed error-body snippet without buffering hostile responses. */
|
|
@@ -850,7 +863,8 @@ async function sendMessageNextcloudTalk(to, text, opts) {
|
|
|
850
863
|
body: bodyStr
|
|
851
864
|
},
|
|
852
865
|
auditContext: "nextcloud-talk-send",
|
|
853
|
-
policy: ssrfPolicyFromPrivateNetworkOptIn$1(account.config)
|
|
866
|
+
policy: ssrfPolicyFromPrivateNetworkOptIn$1(account.config),
|
|
867
|
+
timeoutMs: opts.timeoutMs ?? NEXTCLOUD_TALK_SEND_TIMEOUT_MS
|
|
854
868
|
});
|
|
855
869
|
try {
|
|
856
870
|
if (!response.ok) {
|
|
@@ -908,7 +922,8 @@ async function sendReactionNextcloudTalk(roomToken, messageId, reaction, opts) {
|
|
|
908
922
|
body
|
|
909
923
|
},
|
|
910
924
|
auditContext: "nextcloud-talk-reaction",
|
|
911
|
-
policy: ssrfPolicyFromPrivateNetworkOptIn$1(account.config)
|
|
925
|
+
policy: ssrfPolicyFromPrivateNetworkOptIn$1(account.config),
|
|
926
|
+
timeoutMs: opts.timeoutMs ?? NEXTCLOUD_TALK_SEND_TIMEOUT_MS
|
|
912
927
|
});
|
|
913
928
|
try {
|
|
914
929
|
if (!response.ok) {
|
|
@@ -959,7 +974,7 @@ function roomRoutes(params) {
|
|
|
959
974
|
}
|
|
960
975
|
async function deliverNextcloudTalkReply(params) {
|
|
961
976
|
const { cfg, payload, roomToken, accountId, statusSink } = params;
|
|
962
|
-
await deliverFormattedTextWithAttachments({
|
|
977
|
+
return { visibleReplySent: await deliverFormattedTextWithAttachments({
|
|
963
978
|
payload,
|
|
964
979
|
send: async ({ text, replyToId }) => {
|
|
965
980
|
await sendMessageNextcloudTalk(roomToken, text, {
|
|
@@ -969,7 +984,7 @@ async function deliverNextcloudTalkReply(params) {
|
|
|
969
984
|
});
|
|
970
985
|
statusSink?.({ lastOutboundAt: Date.now() });
|
|
971
986
|
}
|
|
972
|
-
});
|
|
987
|
+
}) };
|
|
973
988
|
}
|
|
974
989
|
async function handleNextcloudTalkInbound(params) {
|
|
975
990
|
const { message, account, config, runtime, statusSink } = params;
|
|
@@ -1002,9 +1017,10 @@ async function handleNextcloudTalkInbound(params) {
|
|
|
1002
1017
|
surface: CHANNEL_ID
|
|
1003
1018
|
});
|
|
1004
1019
|
const hasControlCommand = core.channel.text.hasControlCommand(rawBody, config);
|
|
1005
|
-
const shouldRequireMention = isGroup ?
|
|
1006
|
-
|
|
1007
|
-
|
|
1020
|
+
const shouldRequireMention = isGroup ? resolveNextcloudTalkGroupRequireMention({
|
|
1021
|
+
cfg: config,
|
|
1022
|
+
accountId: account.accountId,
|
|
1023
|
+
groupId: roomToken
|
|
1008
1024
|
}) : false;
|
|
1009
1025
|
const { groupPolicy, providerMissingFallbackApplied } = resolveAllowlistProviderRuntimeGroupPolicy({
|
|
1010
1026
|
providerConfigPresent: (config.channels?.[CHANNEL_ID] ?? void 0) !== void 0,
|
|
@@ -1141,6 +1157,7 @@ async function handleNextcloudTalkInbound(params) {
|
|
|
1141
1157
|
body: rawBody
|
|
1142
1158
|
});
|
|
1143
1159
|
const groupSystemPrompt = normalizeOptionalString(roomConfig?.systemPrompt);
|
|
1160
|
+
const blockStreamingEnabled = resolveChannelStreamingBlockEnabled(account.config);
|
|
1144
1161
|
const ctxPayload = core.channel.reply.finalizeInboundContext({
|
|
1145
1162
|
Body: body,
|
|
1146
1163
|
BodyForAgent: rawBody,
|
|
@@ -1176,8 +1193,12 @@ async function handleNextcloudTalkInbound(params) {
|
|
|
1176
1193
|
recordInboundSession: core.channel.session.recordInboundSession,
|
|
1177
1194
|
dispatchReplyWithBufferedBlockDispatcher: core.channel.reply.dispatchReplyWithBufferedBlockDispatcher,
|
|
1178
1195
|
delivery: {
|
|
1196
|
+
preparePayload: (payload) => payload.text === void 0 ? payload : {
|
|
1197
|
+
...payload,
|
|
1198
|
+
text: sanitizeAssistantVisibleText(payload.text)
|
|
1199
|
+
},
|
|
1179
1200
|
deliver: async (payload) => {
|
|
1180
|
-
await deliverNextcloudTalkReply({
|
|
1201
|
+
return await deliverNextcloudTalkReply({
|
|
1181
1202
|
cfg: config,
|
|
1182
1203
|
payload,
|
|
1183
1204
|
roomToken,
|
|
@@ -1192,7 +1213,7 @@ async function handleNextcloudTalkInbound(params) {
|
|
|
1192
1213
|
replyPipeline: {},
|
|
1193
1214
|
replyOptions: {
|
|
1194
1215
|
skillFilter: roomConfig?.skills,
|
|
1195
|
-
disableBlockStreaming: typeof
|
|
1216
|
+
disableBlockStreaming: typeof blockStreamingEnabled === "boolean" ? !blockStreamingEnabled : void 0
|
|
1196
1217
|
},
|
|
1197
1218
|
record: { onRecordError: (err) => {
|
|
1198
1219
|
runtime.error?.(`nextcloud-talk: failed updating session meta: ${String(err)}`);
|
|
@@ -1651,7 +1672,7 @@ const nextcloudTalkMessageActions = {
|
|
|
1651
1672
|
if (!hasConfiguredAccount(cfg, accountId)) return null;
|
|
1652
1673
|
return { actions: ["send", "react"] };
|
|
1653
1674
|
},
|
|
1654
|
-
supportsAction: ({ action }) => action
|
|
1675
|
+
supportsAction: ({ action }) => action === "react",
|
|
1655
1676
|
handleAction: async ({ action, params, cfg, accountId, toolContext }) => {
|
|
1656
1677
|
if (action === "send") throw new Error("Send should be handled by outbound, not actions handler.");
|
|
1657
1678
|
if (action === "react") {
|
|
@@ -2076,18 +2097,7 @@ const nextcloudTalkPlugin = createChatChannelPlugin({
|
|
|
2076
2097
|
approvalCapability: nextcloudTalkApprovalAuth,
|
|
2077
2098
|
doctor: nextcloudTalkDoctor,
|
|
2078
2099
|
groups: {
|
|
2079
|
-
resolveRequireMention:
|
|
2080
|
-
const rooms = resolveNextcloudTalkAccount({
|
|
2081
|
-
cfg,
|
|
2082
|
-
accountId
|
|
2083
|
-
}).config.rooms;
|
|
2084
|
-
if (!rooms || !groupId) return true;
|
|
2085
|
-
const roomConfig = rooms[groupId];
|
|
2086
|
-
if (roomConfig?.requireMention !== void 0) return roomConfig.requireMention;
|
|
2087
|
-
const wildcardConfig = rooms["*"];
|
|
2088
|
-
if (wildcardConfig?.requireMention !== void 0) return wildcardConfig.requireMention;
|
|
2089
|
-
return true;
|
|
2090
|
-
},
|
|
2100
|
+
resolveRequireMention: resolveNextcloudTalkGroupRequireMention,
|
|
2091
2101
|
resolveToolPolicy: resolveNextcloudTalkGroupToolPolicy
|
|
2092
2102
|
},
|
|
2093
2103
|
messaging: {
|
|
@@ -2155,7 +2165,8 @@ const nextcloudTalkPlugin = createChatChannelPlugin({
|
|
|
2155
2165
|
deliveryMode: "direct",
|
|
2156
2166
|
chunker: (text, limit) => getNextcloudTalkRuntime().channel.text.chunkMarkdownText(text, limit),
|
|
2157
2167
|
chunkerMode: "markdown",
|
|
2158
|
-
textChunkLimit: 4e3
|
|
2168
|
+
textChunkLimit: 4e3,
|
|
2169
|
+
sanitizeText: ({ text }) => sanitizeAssistantVisibleText(text)
|
|
2159
2170
|
},
|
|
2160
2171
|
attachedResults: {
|
|
2161
2172
|
channel: "nextcloud-talk",
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { t as nextcloudTalkPlugin } from "./channel-
|
|
1
|
+
import { t as nextcloudTalkPlugin } from "./channel-CYse6FwT.js";
|
|
2
2
|
export { nextcloudTalkPlugin };
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { n as normalizeCompatibilityConfig, t as legacyConfigRules } from "./doctor-contract-
|
|
1
|
+
import { n as normalizeCompatibilityConfig, t as legacyConfigRules } from "./doctor-contract-fNhK1wag.js";
|
|
2
2
|
export { legacyConfigRules, normalizeCompatibilityConfig };
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { createLegacyPrivateNetworkDoctorContract } from "openclaw/plugin-sdk/ssrf-runtime";
|
|
2
|
+
import { defineChannelAliasMigration } from "openclaw/plugin-sdk/runtime-doctor";
|
|
3
|
+
//#region extensions/nextcloud-talk/src/doctor-contract.ts
|
|
4
|
+
const networkContract = createLegacyPrivateNetworkDoctorContract({ channelKey: "nextcloud-talk" });
|
|
5
|
+
const streamingAliasMigration = defineChannelAliasMigration({
|
|
6
|
+
channelId: "nextcloud-talk",
|
|
7
|
+
streaming: {
|
|
8
|
+
defaultMode: "partial",
|
|
9
|
+
deliveryOnly: true
|
|
10
|
+
},
|
|
11
|
+
accountStreamingReplacesRoot: true
|
|
12
|
+
});
|
|
13
|
+
const legacyConfigRules = [...networkContract.legacyConfigRules, ...streamingAliasMigration.legacyConfigRules];
|
|
14
|
+
function normalizeCompatibilityConfig({ cfg }) {
|
|
15
|
+
const network = networkContract.normalizeCompatibilityConfig({ cfg });
|
|
16
|
+
return streamingAliasMigration.normalizeChannelConfig({
|
|
17
|
+
cfg: network.config,
|
|
18
|
+
changes: network.changes
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
//#endregion
|
|
22
|
+
export { normalizeCompatibilityConfig as n, legacyConfigRules as t };
|
|
@@ -1,51 +1,10 @@
|
|
|
1
|
-
import { collectConditionalChannelFieldAssignments, getChannelSurface, hasOwnProperty } from "openclaw/plugin-sdk/channel-secret-basic-runtime";
|
|
1
|
+
import { collectConditionalChannelFieldAssignments, createChannelSecretTargetRegistryEntries, getChannelSurface, hasOwnProperty } from "openclaw/plugin-sdk/channel-secret-basic-runtime";
|
|
2
2
|
//#region extensions/nextcloud-talk/src/secret-contract.ts
|
|
3
|
-
const secretTargetRegistryEntries =
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
pathPattern: "channels.nextcloud-talk.accounts.*.apiPassword",
|
|
9
|
-
secretShape: "secret_input",
|
|
10
|
-
expectedResolvedValue: "string",
|
|
11
|
-
includeInPlan: true,
|
|
12
|
-
includeInConfigure: true,
|
|
13
|
-
includeInAudit: true
|
|
14
|
-
},
|
|
15
|
-
{
|
|
16
|
-
id: "channels.nextcloud-talk.accounts.*.botSecret",
|
|
17
|
-
targetType: "channels.nextcloud-talk.accounts.*.botSecret",
|
|
18
|
-
configFile: "openclaw.json",
|
|
19
|
-
pathPattern: "channels.nextcloud-talk.accounts.*.botSecret",
|
|
20
|
-
secretShape: "secret_input",
|
|
21
|
-
expectedResolvedValue: "string",
|
|
22
|
-
includeInPlan: true,
|
|
23
|
-
includeInConfigure: true,
|
|
24
|
-
includeInAudit: true
|
|
25
|
-
},
|
|
26
|
-
{
|
|
27
|
-
id: "channels.nextcloud-talk.apiPassword",
|
|
28
|
-
targetType: "channels.nextcloud-talk.apiPassword",
|
|
29
|
-
configFile: "openclaw.json",
|
|
30
|
-
pathPattern: "channels.nextcloud-talk.apiPassword",
|
|
31
|
-
secretShape: "secret_input",
|
|
32
|
-
expectedResolvedValue: "string",
|
|
33
|
-
includeInPlan: true,
|
|
34
|
-
includeInConfigure: true,
|
|
35
|
-
includeInAudit: true
|
|
36
|
-
},
|
|
37
|
-
{
|
|
38
|
-
id: "channels.nextcloud-talk.botSecret",
|
|
39
|
-
targetType: "channels.nextcloud-talk.botSecret",
|
|
40
|
-
configFile: "openclaw.json",
|
|
41
|
-
pathPattern: "channels.nextcloud-talk.botSecret",
|
|
42
|
-
secretShape: "secret_input",
|
|
43
|
-
expectedResolvedValue: "string",
|
|
44
|
-
includeInPlan: true,
|
|
45
|
-
includeInConfigure: true,
|
|
46
|
-
includeInAudit: true
|
|
47
|
-
}
|
|
48
|
-
];
|
|
3
|
+
const secretTargetRegistryEntries = createChannelSecretTargetRegistryEntries({
|
|
4
|
+
channelKey: "nextcloud-talk",
|
|
5
|
+
account: ["apiPassword", "botSecret"],
|
|
6
|
+
channel: ["apiPassword", "botSecret"]
|
|
7
|
+
});
|
|
49
8
|
function collectRuntimeConfigAssignments(params) {
|
|
50
9
|
const resolved = getChannelSurface(params.config, "nextcloud-talk");
|
|
51
10
|
if (!resolved) return;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { n as collectRuntimeConfigAssignments, r as secretTargetRegistryEntries, t as channelSecrets } from "./secret-contract-
|
|
1
|
+
import { n as collectRuntimeConfigAssignments, r as secretTargetRegistryEntries, t as channelSecrets } from "./secret-contract-DGgvfVqm.js";
|
|
2
2
|
export { channelSecrets, collectRuntimeConfigAssignments, secretTargetRegistryEntries };
|
package/npm-shrinkwrap.json
CHANGED
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@openclaw/nextcloud-talk",
|
|
3
|
-
"version": "2026.7.1",
|
|
3
|
+
"version": "2026.7.2-beta.1",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "@openclaw/nextcloud-talk",
|
|
9
|
-
"version": "2026.7.1",
|
|
9
|
+
"version": "2026.7.2-beta.1",
|
|
10
10
|
"dependencies": {
|
|
11
11
|
"zod": "4.4.3"
|
|
12
12
|
},
|
|
13
13
|
"peerDependencies": {
|
|
14
|
-
"openclaw": ">=2026.7.1"
|
|
14
|
+
"openclaw": ">=2026.7.2-beta.1"
|
|
15
15
|
},
|
|
16
16
|
"peerDependenciesMeta": {
|
|
17
17
|
"openclaw": {
|
package/openclaw.plugin.json
CHANGED
|
@@ -366,33 +366,45 @@
|
|
|
366
366
|
"exclusiveMinimum": 0,
|
|
367
367
|
"maximum": 9007199254740991
|
|
368
368
|
},
|
|
369
|
-
"
|
|
370
|
-
"type": "string",
|
|
371
|
-
"enum": [
|
|
372
|
-
"length",
|
|
373
|
-
"newline"
|
|
374
|
-
]
|
|
375
|
-
},
|
|
376
|
-
"blockStreaming": {
|
|
377
|
-
"type": "boolean"
|
|
378
|
-
},
|
|
379
|
-
"blockStreamingCoalesce": {
|
|
369
|
+
"streaming": {
|
|
380
370
|
"type": "object",
|
|
381
371
|
"properties": {
|
|
382
|
-
"
|
|
383
|
-
"type": "
|
|
384
|
-
"
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
"type": "integer",
|
|
389
|
-
"exclusiveMinimum": 0,
|
|
390
|
-
"maximum": 9007199254740991
|
|
372
|
+
"chunkMode": {
|
|
373
|
+
"type": "string",
|
|
374
|
+
"enum": [
|
|
375
|
+
"length",
|
|
376
|
+
"newline"
|
|
377
|
+
]
|
|
391
378
|
},
|
|
392
|
-
"
|
|
393
|
-
"type": "
|
|
394
|
-
"
|
|
395
|
-
|
|
379
|
+
"block": {
|
|
380
|
+
"type": "object",
|
|
381
|
+
"properties": {
|
|
382
|
+
"enabled": {
|
|
383
|
+
"type": "boolean"
|
|
384
|
+
},
|
|
385
|
+
"coalesce": {
|
|
386
|
+
"type": "object",
|
|
387
|
+
"properties": {
|
|
388
|
+
"minChars": {
|
|
389
|
+
"type": "integer",
|
|
390
|
+
"exclusiveMinimum": 0,
|
|
391
|
+
"maximum": 9007199254740991
|
|
392
|
+
},
|
|
393
|
+
"maxChars": {
|
|
394
|
+
"type": "integer",
|
|
395
|
+
"exclusiveMinimum": 0,
|
|
396
|
+
"maximum": 9007199254740991
|
|
397
|
+
},
|
|
398
|
+
"idleMs": {
|
|
399
|
+
"type": "integer",
|
|
400
|
+
"minimum": 0,
|
|
401
|
+
"maximum": 9007199254740991
|
|
402
|
+
}
|
|
403
|
+
},
|
|
404
|
+
"additionalProperties": false
|
|
405
|
+
}
|
|
406
|
+
},
|
|
407
|
+
"additionalProperties": false
|
|
396
408
|
}
|
|
397
409
|
},
|
|
398
410
|
"additionalProperties": false
|
|
@@ -752,33 +764,45 @@
|
|
|
752
764
|
"exclusiveMinimum": 0,
|
|
753
765
|
"maximum": 9007199254740991
|
|
754
766
|
},
|
|
755
|
-
"
|
|
756
|
-
"type": "string",
|
|
757
|
-
"enum": [
|
|
758
|
-
"length",
|
|
759
|
-
"newline"
|
|
760
|
-
]
|
|
761
|
-
},
|
|
762
|
-
"blockStreaming": {
|
|
763
|
-
"type": "boolean"
|
|
764
|
-
},
|
|
765
|
-
"blockStreamingCoalesce": {
|
|
767
|
+
"streaming": {
|
|
766
768
|
"type": "object",
|
|
767
769
|
"properties": {
|
|
768
|
-
"
|
|
769
|
-
"type": "
|
|
770
|
-
"
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
"type": "integer",
|
|
775
|
-
"exclusiveMinimum": 0,
|
|
776
|
-
"maximum": 9007199254740991
|
|
770
|
+
"chunkMode": {
|
|
771
|
+
"type": "string",
|
|
772
|
+
"enum": [
|
|
773
|
+
"length",
|
|
774
|
+
"newline"
|
|
775
|
+
]
|
|
777
776
|
},
|
|
778
|
-
"
|
|
779
|
-
"type": "
|
|
780
|
-
"
|
|
781
|
-
|
|
777
|
+
"block": {
|
|
778
|
+
"type": "object",
|
|
779
|
+
"properties": {
|
|
780
|
+
"enabled": {
|
|
781
|
+
"type": "boolean"
|
|
782
|
+
},
|
|
783
|
+
"coalesce": {
|
|
784
|
+
"type": "object",
|
|
785
|
+
"properties": {
|
|
786
|
+
"minChars": {
|
|
787
|
+
"type": "integer",
|
|
788
|
+
"exclusiveMinimum": 0,
|
|
789
|
+
"maximum": 9007199254740991
|
|
790
|
+
},
|
|
791
|
+
"maxChars": {
|
|
792
|
+
"type": "integer",
|
|
793
|
+
"exclusiveMinimum": 0,
|
|
794
|
+
"maximum": 9007199254740991
|
|
795
|
+
},
|
|
796
|
+
"idleMs": {
|
|
797
|
+
"type": "integer",
|
|
798
|
+
"minimum": 0,
|
|
799
|
+
"maximum": 9007199254740991
|
|
800
|
+
}
|
|
801
|
+
},
|
|
802
|
+
"additionalProperties": false
|
|
803
|
+
}
|
|
804
|
+
},
|
|
805
|
+
"additionalProperties": false
|
|
782
806
|
}
|
|
783
807
|
},
|
|
784
808
|
"additionalProperties": false
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@openclaw/nextcloud-talk",
|
|
3
|
-
"version": "2026.7.1",
|
|
3
|
+
"version": "2026.7.2-beta.1",
|
|
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.1"
|
|
11
|
+
"openclaw": ">=2026.7.2-beta.1"
|
|
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.1"
|
|
43
|
+
"pluginApi": ">=2026.7.2-beta.1"
|
|
44
44
|
},
|
|
45
45
|
"build": {
|
|
46
|
-
"openclawVersion": "2026.7.1"
|
|
46
|
+
"openclawVersion": "2026.7.2-beta.1"
|
|
47
47
|
},
|
|
48
48
|
"release": {
|
|
49
49
|
"publishToClawHub": true,
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
import { createLegacyPrivateNetworkDoctorContract } from "openclaw/plugin-sdk/ssrf-runtime";
|
|
2
|
-
//#region extensions/nextcloud-talk/src/doctor-contract.ts
|
|
3
|
-
const contract = createLegacyPrivateNetworkDoctorContract({ channelKey: "nextcloud-talk" });
|
|
4
|
-
const legacyConfigRules = contract.legacyConfigRules;
|
|
5
|
-
const normalizeCompatibilityConfig = contract.normalizeCompatibilityConfig;
|
|
6
|
-
//#endregion
|
|
7
|
-
export { normalizeCompatibilityConfig as n, legacyConfigRules as t };
|