@openclaw/nextcloud-talk 2026.7.2-beta.7 → 2026.8.1-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.
- package/dist/api.js +1 -1
- package/dist/{channel-B9yquEb1.js → channel-CojgyJSq.js} +71 -69
- package/dist/channel-plugin-api.js +1 -1
- package/dist/{doctor-contract-fNhK1wag.js → doctor-contract-Bda_xc6V.js} +1 -2
- package/dist/doctor-contract-api.js +1 -1
- package/dist/secret-contract-Bvm0PmP3.js +15 -0
- package/dist/secret-contract-api.js +1 -1
- package/openclaw.plugin.json +101 -0
- package/package.json +8 -5
- package/dist/secret-contract-DGgvfVqm.js +0 -45
package/dist/api.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { t as nextcloudTalkPlugin } from "./channel-
|
|
1
|
+
import { t as nextcloudTalkPlugin } from "./channel-CojgyJSq.js";
|
|
2
2
|
export { nextcloudTalkPlugin };
|
|
@@ -1,6 +1,6 @@
|
|
|
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-Bda_xc6V.js";
|
|
3
|
+
import { n as collectRuntimeConfigAssignments, r as secretTargetRegistryEntries } from "./secret-contract-Bvm0PmP3.js";
|
|
4
4
|
import { createAccountListHelpers, 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";
|
|
@@ -8,7 +8,7 @@ import { createAllowlistProviderRouteAllowlistWarningCollector, resolveScopeRequ
|
|
|
8
8
|
import { buildWebhookChannelStatusSummary, createComputedAccountStatusAdapter, createDefaultChannelRuntimeState } from "openclaw/plugin-sdk/status-helpers";
|
|
9
9
|
import { FormatCapabilityProfile, convertMarkdownTables, renderMarkdownWithMarkers, sanitizeAssistantVisibleText } from "openclaw/plugin-sdk/text-chunking";
|
|
10
10
|
import { createChannelApprovalAuth } from "openclaw/plugin-sdk/approval-auth-runtime";
|
|
11
|
-
import { normalizeLowercaseStringOrEmpty, normalizeOptionalLowercaseString, normalizeOptionalString, normalizeStringEntries } from "openclaw/plugin-sdk/string-coerce-runtime";
|
|
11
|
+
import { normalizeLowercaseStringOrEmpty, normalizeOptionalLowercaseString, normalizeOptionalString, normalizeStringEntries, readNonEmptyStringPreservingWhitespace } from "openclaw/plugin-sdk/string-coerce-runtime";
|
|
12
12
|
import { DEFAULT_ACCOUNT_ID, hasConfiguredAccountValue, normalizeAccountId, resolveAccountWithDefaultFallback } from "openclaw/plugin-sdk/account-core";
|
|
13
13
|
import { isTruthyEnvValue } from "openclaw/plugin-sdk/runtime-env";
|
|
14
14
|
import { tryReadSecretFileSync } from "openclaw/plugin-sdk/secret-file-runtime";
|
|
@@ -16,7 +16,7 @@ import { buildSecretInputSchema, hasConfiguredSecretInput, normalizeResolvedSecr
|
|
|
16
16
|
import { formatErrorMessage } from "openclaw/plugin-sdk/error-runtime";
|
|
17
17
|
import { parseStrictNonNegativeInteger, parseStrictPositiveInteger } from "openclaw/plugin-sdk/number-runtime";
|
|
18
18
|
import { readProviderJsonResponse, readResponseTextLimited } from "openclaw/plugin-sdk/provider-http";
|
|
19
|
-
import {
|
|
19
|
+
import { resolveChannelInboundRouteEnvelope } from "openclaw/plugin-sdk/channel-inbound";
|
|
20
20
|
import { bindIngressLifecycleToReplyOptions, createAccountStatusSink, createChannelIngressMonitor, createMessageReceiptFromOutboundResults, defineChannelMessageAdapter, resolveChannelStreamingBlockEnabled, runPassiveAccountLifecycle } from "openclaw/plugin-sdk/channel-outbound";
|
|
21
21
|
import { ssrfPolicyFromPrivateNetworkOptIn, ssrfPolicyFromPrivateNetworkOptIn as ssrfPolicyFromPrivateNetworkOptIn$1 } from "openclaw/plugin-sdk/ssrf-runtime";
|
|
22
22
|
import { requireRuntimeConfig } from "openclaw/plugin-sdk/plugin-config-runtime";
|
|
@@ -34,6 +34,7 @@ import os from "node:os";
|
|
|
34
34
|
import path from "node:path";
|
|
35
35
|
import { migratePersistentDedupeLegacyJsonFile, resolvePersistentDedupePluginStateNamespace } from "openclaw/plugin-sdk/persistent-dedupe";
|
|
36
36
|
import { resolveStateDir } from "openclaw/plugin-sdk/state-paths";
|
|
37
|
+
import { channelReadyPatch } from "openclaw/plugin-sdk/gateway-runtime";
|
|
37
38
|
import { channelIngressRoutes, resolveStableChannelMessageIngress } from "openclaw/plugin-sdk/channel-ingress-runtime";
|
|
38
39
|
import { buildChannelKeyCandidates, normalizeChannelSlug, resolveChannelEntryMatchWithFallback } from "openclaw/plugin-sdk/channel-targets";
|
|
39
40
|
import { pruneMapToMaxSize } from "openclaw/plugin-sdk/collection-runtime";
|
|
@@ -395,6 +396,7 @@ dangerouslyAllowPrivateNetwork: z.boolean().optional() }).strict().optional();
|
|
|
395
396
|
const NextcloudTalkConfigSchema = buildMultiAccountChannelSchema(z.object({
|
|
396
397
|
name: z.string().optional(),
|
|
397
398
|
enabled: z.boolean().optional(),
|
|
399
|
+
configWrites: z.boolean().optional(),
|
|
398
400
|
markdown: MarkdownConfigSchema,
|
|
399
401
|
baseUrl: z.string().optional(),
|
|
400
402
|
botSecret: buildSecretInputSchema().optional(),
|
|
@@ -593,10 +595,6 @@ function cacheRoomInfo(key, value) {
|
|
|
593
595
|
roomCache.set(key, value);
|
|
594
596
|
pruneMapToMaxSize(roomCache, ROOM_CACHE_MAX_ENTRIES);
|
|
595
597
|
}
|
|
596
|
-
function coerceRoomType(value) {
|
|
597
|
-
if (typeof value === "number" && Number.isSafeInteger(value) && value > 0) return value;
|
|
598
|
-
return parseStrictPositiveInteger(value);
|
|
599
|
-
}
|
|
600
598
|
function resolveRoomKindFromType(type) {
|
|
601
599
|
if (!type) return;
|
|
602
600
|
if (type === 1 || type === 5 || type === 6) return "direct";
|
|
@@ -648,7 +646,7 @@ async function resolveNextcloudTalkRoomKind(params) {
|
|
|
648
646
|
runtime?.log?.(`nextcloud-talk: room lookup failed (${response.status}) token=${roomToken}`);
|
|
649
647
|
return;
|
|
650
648
|
}
|
|
651
|
-
const kind = resolveRoomKindFromType(
|
|
649
|
+
const kind = resolveRoomKindFromType(parseStrictPositiveInteger((await readProviderJsonResponse(response, "Nextcloud Talk room info failed")).ocs?.data?.type));
|
|
652
650
|
cacheRoomInfo(key, {
|
|
653
651
|
fetchedAt: Date.now(),
|
|
654
652
|
kind
|
|
@@ -987,7 +985,7 @@ async function handleNextcloudTalkInbound(params) {
|
|
|
987
985
|
const allowFrom = normalizeStringEntries(account.config.allowFrom);
|
|
988
986
|
const outerGroupAllowFrom = account.config.groupAllowFrom?.length ? normalizeStringEntries(account.config.groupAllowFrom) : allowFrom;
|
|
989
987
|
const roomAllowFrom = normalizeStringEntries(roomConfig?.allowFrom);
|
|
990
|
-
const resolveAccess = async (wasMentioned) => await resolveStableChannelMessageIngress({
|
|
988
|
+
const resolveAccess = async (wasMentioned, contextBinding) => await resolveStableChannelMessageIngress({
|
|
991
989
|
channelId: CHANNEL_ID,
|
|
992
990
|
accountId: account.accountId,
|
|
993
991
|
identity: {
|
|
@@ -1003,6 +1001,7 @@ async function handleNextcloudTalkInbound(params) {
|
|
|
1003
1001
|
kind: isGroup ? "group" : "direct",
|
|
1004
1002
|
id: isGroup ? roomToken : senderId
|
|
1005
1003
|
},
|
|
1004
|
+
contextBinding,
|
|
1006
1005
|
route: roomRoutes({
|
|
1007
1006
|
isGroup,
|
|
1008
1007
|
groupPolicy,
|
|
@@ -1090,11 +1089,6 @@ async function handleNextcloudTalkInbound(params) {
|
|
|
1090
1089
|
}
|
|
1091
1090
|
const mentionRegexes = core.channel.mentions.buildMentionRegexes(config);
|
|
1092
1091
|
const wasMentioned = mentionRegexes.length ? core.channel.mentions.matchesMentionPatterns(rawBody, mentionRegexes) : false;
|
|
1093
|
-
if (isGroup) access = await resolveAccess(wasMentioned);
|
|
1094
|
-
if (isGroup && access.activationAccess.shouldSkip) {
|
|
1095
|
-
runtime.log?.(`nextcloud-talk: drop room ${roomToken} (no mention)`);
|
|
1096
|
-
return;
|
|
1097
|
-
}
|
|
1098
1092
|
const { route, buildEnvelope } = resolveChannelInboundRouteEnvelope({
|
|
1099
1093
|
cfg: config,
|
|
1100
1094
|
channel: CHANNEL_ID,
|
|
@@ -1104,6 +1098,16 @@ async function handleNextcloudTalkInbound(params) {
|
|
|
1104
1098
|
id: isGroup ? roomToken : senderId
|
|
1105
1099
|
}
|
|
1106
1100
|
});
|
|
1101
|
+
access = await resolveAccess(isGroup ? wasMentioned : void 0, {
|
|
1102
|
+
agentId: route.agentId,
|
|
1103
|
+
sessionKey: route.sessionKey,
|
|
1104
|
+
messageId: message.messageId,
|
|
1105
|
+
inboundEventKind: "user_request"
|
|
1106
|
+
});
|
|
1107
|
+
if (access.ingress.admission !== "dispatch") {
|
|
1108
|
+
runtime.log?.(isGroup && access.activationAccess.shouldSkip ? `nextcloud-talk: drop room ${roomToken} (no mention)` : `nextcloud-talk: drop ${isGroup ? "room" : "DM"} ${roomToken} (authorization changed)`);
|
|
1109
|
+
return;
|
|
1110
|
+
}
|
|
1107
1111
|
const fromLabel = isGroup ? `room:${roomName || roomToken}` : senderName || `user:${senderId}`;
|
|
1108
1112
|
const body = buildEnvelope({
|
|
1109
1113
|
channel: "Nextcloud Talk",
|
|
@@ -1113,7 +1117,8 @@ async function handleNextcloudTalkInbound(params) {
|
|
|
1113
1117
|
});
|
|
1114
1118
|
const groupSystemPrompt = normalizeOptionalString(roomConfig?.systemPrompt);
|
|
1115
1119
|
const blockStreamingEnabled = resolveChannelStreamingBlockEnabled(account.config);
|
|
1116
|
-
const ctxPayload =
|
|
1120
|
+
const ctxPayload = core.channel.inbound.buildContext({
|
|
1121
|
+
channelIngress: access,
|
|
1117
1122
|
channel: CHANNEL_ID,
|
|
1118
1123
|
accountId: route.accountId,
|
|
1119
1124
|
messageId: message.messageId,
|
|
@@ -1125,7 +1130,7 @@ async function handleNextcloudTalkInbound(params) {
|
|
|
1125
1130
|
},
|
|
1126
1131
|
conversation: {
|
|
1127
1132
|
kind: isGroup ? "group" : "direct",
|
|
1128
|
-
id: roomToken,
|
|
1133
|
+
id: isGroup ? roomToken : senderId,
|
|
1129
1134
|
label: fromLabel
|
|
1130
1135
|
},
|
|
1131
1136
|
route: {
|
|
@@ -1276,10 +1281,6 @@ const WEBHOOK_ERRORS = {
|
|
|
1276
1281
|
payloadTooLarge: "Payload too large",
|
|
1277
1282
|
internalServerError: "Internal server error"
|
|
1278
1283
|
};
|
|
1279
|
-
function formatError(err) {
|
|
1280
|
-
if (err instanceof Error) return err.message;
|
|
1281
|
-
return typeof err === "string" ? err : JSON.stringify(err);
|
|
1282
|
-
}
|
|
1283
1284
|
function writeJsonResponse(res, status, body) {
|
|
1284
1285
|
if (body) {
|
|
1285
1286
|
res.writeHead(status, { "Content-Type": "application/json" });
|
|
@@ -1388,7 +1389,7 @@ function createNextcloudTalkWebhookServer(opts) {
|
|
|
1388
1389
|
writeWebhookError(res, 400, WEBHOOK_ERRORS.invalidPayloadFormat);
|
|
1389
1390
|
return;
|
|
1390
1391
|
}
|
|
1391
|
-
const error = err instanceof Error ? err : new Error(
|
|
1392
|
+
const error = err instanceof Error ? err : new Error(formatErrorMessage(err));
|
|
1392
1393
|
onError?.(error);
|
|
1393
1394
|
writeWebhookError(res, 500, WEBHOOK_ERRORS.internalServerError);
|
|
1394
1395
|
}
|
|
@@ -1536,12 +1537,12 @@ function createNextcloudTalkWebhookSpool(options) {
|
|
|
1536
1537
|
await options.deliver(message, lifecycle);
|
|
1537
1538
|
},
|
|
1538
1539
|
pollIntervalMs: options.pollIntervalMs ?? NEXTCLOUD_TALK_INGRESS_POLL_INTERVAL_MS,
|
|
1539
|
-
waitForDeliveryIdleBeforeRepump: true,
|
|
1540
1540
|
retention: {
|
|
1541
1541
|
completedMaxEntries: 1e4,
|
|
1542
1542
|
failedMaxEntries: 1e4
|
|
1543
1543
|
},
|
|
1544
1544
|
drain: {
|
|
1545
|
+
startLimit: 32,
|
|
1545
1546
|
resolveNonRetryableFailure,
|
|
1546
1547
|
...options.adoptionStallTimeoutMs === void 0 ? {} : { adoptionStallTimeoutMs: options.adoptionStallTimeoutMs },
|
|
1547
1548
|
onLog: (message) => options.runtime.log?.(`nextcloud-talk ${message}`)
|
|
@@ -1672,6 +1673,7 @@ async function monitorNextcloudTalkProvider(opts) {
|
|
|
1672
1673
|
await stop();
|
|
1673
1674
|
return { stop };
|
|
1674
1675
|
}
|
|
1676
|
+
opts.statusSink?.(channelReadyPatch());
|
|
1675
1677
|
const publicUrl = account.config.webhookPublicUrl ?? `http://${host === "0.0.0.0" ? "localhost" : host}:${port}${path}`;
|
|
1676
1678
|
logger.info(`[nextcloud-talk:${account.accountId}] webhook listening on ${publicUrl}`);
|
|
1677
1679
|
return { stop };
|
|
@@ -1857,9 +1859,6 @@ function resolveNextcloudTalkOutboundSessionRoute(params) {
|
|
|
1857
1859
|
//#region extensions/nextcloud-talk/src/setup-core.ts
|
|
1858
1860
|
const t$1 = createSetupTranslator$1();
|
|
1859
1861
|
const channel$1 = "nextcloud-talk";
|
|
1860
|
-
function readOptionalString(value) {
|
|
1861
|
-
return typeof value === "string" && value.length > 0 ? value : void 0;
|
|
1862
|
-
}
|
|
1863
1862
|
function normalizeNextcloudTalkBaseUrl(value) {
|
|
1864
1863
|
return value?.trim().replace(/\/+$/, "") ?? "";
|
|
1865
1864
|
}
|
|
@@ -1924,46 +1923,6 @@ const nextcloudTalkDmPolicy = createChannelDmPolicy({
|
|
|
1924
1923
|
applyPatch: ({ cfg, account, patch }) => setNextcloudTalkAccountConfig(cfg, account.accountId, patch),
|
|
1925
1924
|
promptAllowFrom: promptNextcloudTalkAllowFromForAccount
|
|
1926
1925
|
});
|
|
1927
|
-
const nextcloudTalkSetupAdapter = {
|
|
1928
|
-
singleAccountKeysToMove: ["rooms"],
|
|
1929
|
-
resolveAccountId: ({ accountId }) => normalizeAccountId$1(accountId),
|
|
1930
|
-
prepareAccountConfigInput: ({ input }) => {
|
|
1931
|
-
const setupInput = input;
|
|
1932
|
-
return {
|
|
1933
|
-
...setupInput,
|
|
1934
|
-
baseUrl: setupInput.baseUrl ?? readOptionalString(setupInput.url),
|
|
1935
|
-
secret: setupInput.secret ?? readOptionalString(setupInput.token) ?? readOptionalString(setupInput.password),
|
|
1936
|
-
secretFile: setupInput.secretFile ?? readOptionalString(setupInput.tokenFile)
|
|
1937
|
-
};
|
|
1938
|
-
},
|
|
1939
|
-
applyAccountName: ({ cfg, accountId, name }) => applyAccountNameToChannelSection({
|
|
1940
|
-
cfg,
|
|
1941
|
-
channelKey: channel$1,
|
|
1942
|
-
accountId,
|
|
1943
|
-
name
|
|
1944
|
-
}),
|
|
1945
|
-
validateInput: createSetupInputPresenceValidator({
|
|
1946
|
-
defaultAccountOnlyEnvError: "NEXTCLOUD_TALK_BOT_SECRET can only be used for the default account.",
|
|
1947
|
-
validate: ({ input }) => {
|
|
1948
|
-
const setupInput = input;
|
|
1949
|
-
if (!setupInput.useEnv && !setupInput.secret && !setupInput.secretFile) return "Nextcloud Talk requires bot secret or --secret-file (or --use-env).";
|
|
1950
|
-
if (!setupInput.baseUrl) return "Nextcloud Talk requires --base-url.";
|
|
1951
|
-
return null;
|
|
1952
|
-
}
|
|
1953
|
-
}),
|
|
1954
|
-
applyAccountConfig: ({ cfg, accountId, input }) => {
|
|
1955
|
-
const setupInput = input;
|
|
1956
|
-
return setNextcloudTalkAccountConfig(applyAccountNameToChannelSection({
|
|
1957
|
-
cfg,
|
|
1958
|
-
channelKey: channel$1,
|
|
1959
|
-
accountId,
|
|
1960
|
-
name: setupInput.name
|
|
1961
|
-
}), accountId, {
|
|
1962
|
-
baseUrl: normalizeNextcloudTalkBaseUrl(setupInput.baseUrl),
|
|
1963
|
-
...setupInput.useEnv ? {} : setupInput.secretFile ? { botSecretFile: setupInput.secretFile } : setupInput.secret ? { botSecret: setupInput.secret } : {}
|
|
1964
|
-
}, setupInput.useEnv ? ["botSecret", "botSecretFile"] : void 0);
|
|
1965
|
-
}
|
|
1966
|
-
};
|
|
1967
1926
|
const nextcloudTalkSetupContract = defineChannelSetupContract({
|
|
1968
1927
|
fields: {
|
|
1969
1928
|
baseUrl: {
|
|
@@ -2025,10 +1984,53 @@ const nextcloudTalkSetupContract = defineChannelSetupContract({
|
|
|
2025
1984
|
cli: {
|
|
2026
1985
|
flags: "--use-env",
|
|
2027
1986
|
description: "Use Nextcloud Talk environment credentials"
|
|
2028
|
-
}
|
|
1987
|
+
},
|
|
1988
|
+
envVars: ["NEXTCLOUD_TALK_BOT_SECRET"]
|
|
2029
1989
|
}
|
|
2030
1990
|
},
|
|
2031
|
-
legacyAdapter:
|
|
1991
|
+
legacyAdapter: {
|
|
1992
|
+
singleAccountKeysToMove: ["rooms"],
|
|
1993
|
+
resolveAccountId: ({ accountId }) => normalizeAccountId$1(accountId),
|
|
1994
|
+
prepareAccountConfigInput: ({ input }) => {
|
|
1995
|
+
const setupInput = input;
|
|
1996
|
+
return {
|
|
1997
|
+
...setupInput,
|
|
1998
|
+
baseUrl: setupInput.baseUrl ?? readNonEmptyStringPreservingWhitespace(setupInput.url),
|
|
1999
|
+
secret: setupInput.secret ?? readNonEmptyStringPreservingWhitespace(setupInput.token) ?? readNonEmptyStringPreservingWhitespace(setupInput.password),
|
|
2000
|
+
secretFile: setupInput.secretFile ?? readNonEmptyStringPreservingWhitespace(setupInput.tokenFile)
|
|
2001
|
+
};
|
|
2002
|
+
},
|
|
2003
|
+
applyAccountName: ({ cfg, accountId, name }) => applyAccountNameToChannelSection({
|
|
2004
|
+
cfg,
|
|
2005
|
+
channelKey: channel$1,
|
|
2006
|
+
accountId,
|
|
2007
|
+
name
|
|
2008
|
+
}),
|
|
2009
|
+
validateInput: createSetupInputPresenceValidator({
|
|
2010
|
+
defaultAccountOnlyEnvError: "NEXTCLOUD_TALK_BOT_SECRET can only be used for the default account.",
|
|
2011
|
+
validate: ({ input }) => {
|
|
2012
|
+
const setupInput = input;
|
|
2013
|
+
if (!setupInput.useEnv && !setupInput.secret && !setupInput.secretFile) return "Nextcloud Talk requires bot secret or --secret-file (or --use-env).";
|
|
2014
|
+
const normalizedBaseUrl = normalizeNextcloudTalkBaseUrl(setupInput.baseUrl);
|
|
2015
|
+
if (!normalizedBaseUrl) return "Nextcloud Talk requires --base-url.";
|
|
2016
|
+
const baseUrlError = validateNextcloudTalkBaseUrl(normalizedBaseUrl);
|
|
2017
|
+
if (baseUrlError) return baseUrlError;
|
|
2018
|
+
return null;
|
|
2019
|
+
}
|
|
2020
|
+
}),
|
|
2021
|
+
applyAccountConfig: ({ cfg, accountId, input }) => {
|
|
2022
|
+
const setupInput = input;
|
|
2023
|
+
return setNextcloudTalkAccountConfig(applyAccountNameToChannelSection({
|
|
2024
|
+
cfg,
|
|
2025
|
+
channelKey: channel$1,
|
|
2026
|
+
accountId,
|
|
2027
|
+
name: setupInput.name
|
|
2028
|
+
}), accountId, {
|
|
2029
|
+
baseUrl: normalizeNextcloudTalkBaseUrl(setupInput.baseUrl),
|
|
2030
|
+
...setupInput.useEnv ? {} : setupInput.secretFile ? { botSecretFile: setupInput.secretFile } : setupInput.secret ? { botSecret: setupInput.secret } : {}
|
|
2031
|
+
}, setupInput.useEnv ? ["botSecret", "botSecretFile"] : void 0);
|
|
2032
|
+
}
|
|
2033
|
+
}
|
|
2032
2034
|
});
|
|
2033
2035
|
//#endregion
|
|
2034
2036
|
//#region extensions/nextcloud-talk/src/setup-surface.ts
|
|
@@ -2232,6 +2234,7 @@ const nextcloudTalkPlugin = createChatChannelPlugin({
|
|
|
2232
2234
|
"nc"
|
|
2233
2235
|
],
|
|
2234
2236
|
normalizeTarget: normalizeNextcloudTalkMessagingTarget,
|
|
2237
|
+
inferTargetChatType: ({ to }) => normalizeNextcloudTalkMessagingTarget(to) ? "group" : void 0,
|
|
2235
2238
|
resolveOutboundSessionRoute: (params) => resolveNextcloudTalkOutboundSessionRoute(params),
|
|
2236
2239
|
targetResolver: {
|
|
2237
2240
|
looksLikeId: looksLikeNextcloudTalkTargetId,
|
|
@@ -2242,7 +2245,6 @@ const nextcloudTalkPlugin = createChatChannelPlugin({
|
|
|
2242
2245
|
secretTargetRegistryEntries,
|
|
2243
2246
|
collectRuntimeConfigAssignments
|
|
2244
2247
|
},
|
|
2245
|
-
setup: nextcloudTalkSetupAdapter,
|
|
2246
2248
|
setupContract: nextcloudTalkSetupContract,
|
|
2247
2249
|
status: createComputedAccountStatusAdapter({
|
|
2248
2250
|
defaultRuntime: createDefaultChannelRuntimeState(DEFAULT_ACCOUNT_ID$2),
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { t as nextcloudTalkPlugin } from "./channel-
|
|
1
|
+
import { t as nextcloudTalkPlugin } from "./channel-CojgyJSq.js";
|
|
2
2
|
export { nextcloudTalkPlugin };
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import { createLegacyPrivateNetworkDoctorContract } from "openclaw/plugin-sdk/
|
|
2
|
-
import { defineChannelAliasMigration } from "openclaw/plugin-sdk/runtime-doctor";
|
|
1
|
+
import { createLegacyPrivateNetworkDoctorContract, defineChannelAliasMigration } from "openclaw/plugin-sdk/runtime-doctor-migrations";
|
|
3
2
|
//#region extensions/nextcloud-talk/src/doctor-contract.ts
|
|
4
3
|
const networkContract = createLegacyPrivateNetworkDoctorContract({ channelKey: "nextcloud-talk" });
|
|
5
4
|
const streamingAliasMigration = defineChannelAliasMigration({
|
|
@@ -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-Bda_xc6V.js";
|
|
2
2
|
export { legacyConfigRules, normalizeCompatibilityConfig };
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { createSimpleChannelSecretContract } from "openclaw/plugin-sdk/channel-secret-basic-runtime";
|
|
2
|
+
//#region extensions/nextcloud-talk/src/secret-contract.ts
|
|
3
|
+
const channelSecrets = createSimpleChannelSecretContract({
|
|
4
|
+
channelKey: "nextcloud-talk",
|
|
5
|
+
label: "Nextcloud Talk",
|
|
6
|
+
accountFields: ["apiPassword", "botSecret"],
|
|
7
|
+
channelFields: ["apiPassword", "botSecret"],
|
|
8
|
+
mode: {
|
|
9
|
+
kind: "surface-inheritance",
|
|
10
|
+
collectionFields: ["botSecret", "apiPassword"]
|
|
11
|
+
}
|
|
12
|
+
});
|
|
13
|
+
const { secretTargetRegistryEntries, collectRuntimeConfigAssignments } = channelSecrets;
|
|
14
|
+
//#endregion
|
|
15
|
+
export { collectRuntimeConfigAssignments as n, secretTargetRegistryEntries as r, channelSecrets as t };
|
|
@@ -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-Bvm0PmP3.js";
|
|
2
2
|
export { channelSecrets, collectRuntimeConfigAssignments, secretTargetRegistryEntries };
|
package/openclaw.plugin.json
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"id": "nextcloud-talk",
|
|
3
|
+
"doctorContract": {
|
|
4
|
+
"configRepair": true
|
|
5
|
+
},
|
|
3
6
|
"name": "Nextcloud Talk",
|
|
4
7
|
"description": "OpenClaw Nextcloud Talk channel plugin for conversations.",
|
|
5
8
|
"icon": "https://cdn.simpleicons.org/nextcloud",
|
|
@@ -26,6 +29,9 @@
|
|
|
26
29
|
"enabled": {
|
|
27
30
|
"type": "boolean"
|
|
28
31
|
},
|
|
32
|
+
"configWrites": {
|
|
33
|
+
"type": "boolean"
|
|
34
|
+
},
|
|
29
35
|
"markdown": {
|
|
30
36
|
"type": "object",
|
|
31
37
|
"properties": {
|
|
@@ -74,6 +80,29 @@
|
|
|
74
80
|
],
|
|
75
81
|
"additionalProperties": false
|
|
76
82
|
},
|
|
83
|
+
{
|
|
84
|
+
"type": "object",
|
|
85
|
+
"properties": {
|
|
86
|
+
"source": {
|
|
87
|
+
"type": "string",
|
|
88
|
+
"const": "store"
|
|
89
|
+
},
|
|
90
|
+
"provider": {
|
|
91
|
+
"type": "string",
|
|
92
|
+
"pattern": "^[a-z][a-z0-9_-]{0,63}$"
|
|
93
|
+
},
|
|
94
|
+
"id": {
|
|
95
|
+
"type": "string",
|
|
96
|
+
"pattern": "^[A-Z][A-Z0-9_]{0,127}$"
|
|
97
|
+
}
|
|
98
|
+
},
|
|
99
|
+
"required": [
|
|
100
|
+
"source",
|
|
101
|
+
"provider",
|
|
102
|
+
"id"
|
|
103
|
+
],
|
|
104
|
+
"additionalProperties": false
|
|
105
|
+
},
|
|
77
106
|
{
|
|
78
107
|
"type": "object",
|
|
79
108
|
"properties": {
|
|
@@ -158,6 +187,29 @@
|
|
|
158
187
|
],
|
|
159
188
|
"additionalProperties": false
|
|
160
189
|
},
|
|
190
|
+
{
|
|
191
|
+
"type": "object",
|
|
192
|
+
"properties": {
|
|
193
|
+
"source": {
|
|
194
|
+
"type": "string",
|
|
195
|
+
"const": "store"
|
|
196
|
+
},
|
|
197
|
+
"provider": {
|
|
198
|
+
"type": "string",
|
|
199
|
+
"pattern": "^[a-z][a-z0-9_-]{0,63}$"
|
|
200
|
+
},
|
|
201
|
+
"id": {
|
|
202
|
+
"type": "string",
|
|
203
|
+
"pattern": "^[A-Z][A-Z0-9_]{0,127}$"
|
|
204
|
+
}
|
|
205
|
+
},
|
|
206
|
+
"required": [
|
|
207
|
+
"source",
|
|
208
|
+
"provider",
|
|
209
|
+
"id"
|
|
210
|
+
],
|
|
211
|
+
"additionalProperties": false
|
|
212
|
+
},
|
|
161
213
|
{
|
|
162
214
|
"type": "object",
|
|
163
215
|
"properties": {
|
|
@@ -424,6 +476,9 @@
|
|
|
424
476
|
"enabled": {
|
|
425
477
|
"type": "boolean"
|
|
426
478
|
},
|
|
479
|
+
"configWrites": {
|
|
480
|
+
"type": "boolean"
|
|
481
|
+
},
|
|
427
482
|
"markdown": {
|
|
428
483
|
"type": "object",
|
|
429
484
|
"properties": {
|
|
@@ -472,6 +527,29 @@
|
|
|
472
527
|
],
|
|
473
528
|
"additionalProperties": false
|
|
474
529
|
},
|
|
530
|
+
{
|
|
531
|
+
"type": "object",
|
|
532
|
+
"properties": {
|
|
533
|
+
"source": {
|
|
534
|
+
"type": "string",
|
|
535
|
+
"const": "store"
|
|
536
|
+
},
|
|
537
|
+
"provider": {
|
|
538
|
+
"type": "string",
|
|
539
|
+
"pattern": "^[a-z][a-z0-9_-]{0,63}$"
|
|
540
|
+
},
|
|
541
|
+
"id": {
|
|
542
|
+
"type": "string",
|
|
543
|
+
"pattern": "^[A-Z][A-Z0-9_]{0,127}$"
|
|
544
|
+
}
|
|
545
|
+
},
|
|
546
|
+
"required": [
|
|
547
|
+
"source",
|
|
548
|
+
"provider",
|
|
549
|
+
"id"
|
|
550
|
+
],
|
|
551
|
+
"additionalProperties": false
|
|
552
|
+
},
|
|
475
553
|
{
|
|
476
554
|
"type": "object",
|
|
477
555
|
"properties": {
|
|
@@ -556,6 +634,29 @@
|
|
|
556
634
|
],
|
|
557
635
|
"additionalProperties": false
|
|
558
636
|
},
|
|
637
|
+
{
|
|
638
|
+
"type": "object",
|
|
639
|
+
"properties": {
|
|
640
|
+
"source": {
|
|
641
|
+
"type": "string",
|
|
642
|
+
"const": "store"
|
|
643
|
+
},
|
|
644
|
+
"provider": {
|
|
645
|
+
"type": "string",
|
|
646
|
+
"pattern": "^[a-z][a-z0-9_-]{0,63}$"
|
|
647
|
+
},
|
|
648
|
+
"id": {
|
|
649
|
+
"type": "string",
|
|
650
|
+
"pattern": "^[A-Z][A-Z0-9_]{0,127}$"
|
|
651
|
+
}
|
|
652
|
+
},
|
|
653
|
+
"required": [
|
|
654
|
+
"source",
|
|
655
|
+
"provider",
|
|
656
|
+
"id"
|
|
657
|
+
],
|
|
658
|
+
"additionalProperties": false
|
|
659
|
+
},
|
|
559
660
|
{
|
|
560
661
|
"type": "object",
|
|
561
662
|
"properties": {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@openclaw/nextcloud-talk",
|
|
3
|
-
"version": "2026.
|
|
3
|
+
"version": "2026.8.1-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.
|
|
11
|
+
"openclaw": ">=2026.8.1-beta.2"
|
|
12
12
|
},
|
|
13
13
|
"peerDependenciesMeta": {
|
|
14
14
|
"openclaw": {
|
|
@@ -113,7 +113,10 @@
|
|
|
113
113
|
"cli": {
|
|
114
114
|
"flags": "--use-env",
|
|
115
115
|
"description": "Use Nextcloud Talk environment credentials"
|
|
116
|
-
}
|
|
116
|
+
},
|
|
117
|
+
"envVars": [
|
|
118
|
+
"NEXTCLOUD_TALK_BOT_SECRET"
|
|
119
|
+
]
|
|
117
120
|
}
|
|
118
121
|
]
|
|
119
122
|
}
|
|
@@ -124,10 +127,10 @@
|
|
|
124
127
|
"minHostVersion": ">=2026.4.10"
|
|
125
128
|
},
|
|
126
129
|
"compat": {
|
|
127
|
-
"pluginApi": ">=2026.
|
|
130
|
+
"pluginApi": ">=2026.8.1-beta.2"
|
|
128
131
|
},
|
|
129
132
|
"build": {
|
|
130
|
-
"openclawVersion": "2026.
|
|
133
|
+
"openclawVersion": "2026.8.1-beta.2"
|
|
131
134
|
},
|
|
132
135
|
"release": {
|
|
133
136
|
"publishToClawHub": true,
|
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
import { collectConditionalChannelFieldAssignments, createChannelSecretTargetRegistryEntries, getChannelSurface, hasOwnProperty } from "openclaw/plugin-sdk/channel-secret-basic-runtime";
|
|
2
|
-
//#region extensions/nextcloud-talk/src/secret-contract.ts
|
|
3
|
-
const secretTargetRegistryEntries = createChannelSecretTargetRegistryEntries({
|
|
4
|
-
channelKey: "nextcloud-talk",
|
|
5
|
-
account: ["apiPassword", "botSecret"],
|
|
6
|
-
channel: ["apiPassword", "botSecret"]
|
|
7
|
-
});
|
|
8
|
-
function collectRuntimeConfigAssignments(params) {
|
|
9
|
-
const resolved = getChannelSurface(params.config, "nextcloud-talk");
|
|
10
|
-
if (!resolved) return;
|
|
11
|
-
const { channel: nextcloudTalk, surface } = resolved;
|
|
12
|
-
const inheritsField = (field) => ({ account, enabled }) => enabled && !hasOwnProperty(account, field);
|
|
13
|
-
collectConditionalChannelFieldAssignments({
|
|
14
|
-
channelKey: "nextcloud-talk",
|
|
15
|
-
field: "botSecret",
|
|
16
|
-
channel: nextcloudTalk,
|
|
17
|
-
surface,
|
|
18
|
-
defaults: params.defaults,
|
|
19
|
-
context: params.context,
|
|
20
|
-
topLevelActiveWithoutAccounts: true,
|
|
21
|
-
topLevelInheritedAccountActive: inheritsField("botSecret"),
|
|
22
|
-
accountActive: ({ enabled }) => enabled,
|
|
23
|
-
topInactiveReason: "no enabled Nextcloud Talk surface inherits this top-level botSecret.",
|
|
24
|
-
accountInactiveReason: "Nextcloud Talk account is disabled."
|
|
25
|
-
});
|
|
26
|
-
collectConditionalChannelFieldAssignments({
|
|
27
|
-
channelKey: "nextcloud-talk",
|
|
28
|
-
field: "apiPassword",
|
|
29
|
-
channel: nextcloudTalk,
|
|
30
|
-
surface,
|
|
31
|
-
defaults: params.defaults,
|
|
32
|
-
context: params.context,
|
|
33
|
-
topLevelActiveWithoutAccounts: true,
|
|
34
|
-
topLevelInheritedAccountActive: inheritsField("apiPassword"),
|
|
35
|
-
accountActive: ({ enabled }) => enabled,
|
|
36
|
-
topInactiveReason: "no enabled Nextcloud Talk surface inherits this top-level apiPassword.",
|
|
37
|
-
accountInactiveReason: "Nextcloud Talk account is disabled."
|
|
38
|
-
});
|
|
39
|
-
}
|
|
40
|
-
const channelSecrets = {
|
|
41
|
-
secretTargetRegistryEntries,
|
|
42
|
-
collectRuntimeConfigAssignments
|
|
43
|
-
};
|
|
44
|
-
//#endregion
|
|
45
|
-
export { collectRuntimeConfigAssignments as n, secretTargetRegistryEntries as r, channelSecrets as t };
|