@openclaw/nextcloud-talk 2026.8.1-beta.3 → 2026.8.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
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { t as nextcloudTalkPlugin } from "./channel-
|
|
1
|
+
import { t as nextcloudTalkPlugin } from "./channel-C7Xe0Nkb.js";
|
|
2
2
|
export { nextcloudTalkPlugin };
|
|
@@ -15,19 +15,19 @@ import { tryReadSecretFileSync } from "openclaw/plugin-sdk/secret-file-runtime";
|
|
|
15
15
|
import { buildSecretInputSchema, hasConfiguredSecretInput, normalizeResolvedSecretInputString, resolveSecretInputString } from "openclaw/plugin-sdk/secret-input";
|
|
16
16
|
import { formatErrorMessage } from "openclaw/plugin-sdk/error-runtime";
|
|
17
17
|
import { parseStrictNonNegativeInteger, parseStrictPositiveInteger } from "openclaw/plugin-sdk/number-runtime";
|
|
18
|
-
import { readProviderJsonResponse,
|
|
18
|
+
import { readProviderJsonResponse, readProviderTextResponse } from "openclaw/plugin-sdk/provider-http";
|
|
19
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
|
+
import { redactToolPayloadText } from "openclaw/plugin-sdk/logging-core";
|
|
22
23
|
import { requireRuntimeConfig } from "openclaw/plugin-sdk/plugin-config-runtime";
|
|
23
24
|
import { resolveMarkdownTableMode } from "openclaw/plugin-sdk/markdown-table-runtime";
|
|
24
25
|
import { createHmac, randomBytes } from "node:crypto";
|
|
25
26
|
import { fileExists, safeEqualSecret } from "openclaw/plugin-sdk/security-runtime";
|
|
26
|
-
import { clearAccountEntryFields } from "openclaw/plugin-sdk/channel-plugin-common";
|
|
27
27
|
import { DEFAULT_ACCOUNT_ID as DEFAULT_ACCOUNT_ID$2 } from "openclaw/plugin-sdk/account-id";
|
|
28
|
-
import { DmPolicySchema, GroupPolicySchema, MarkdownConfigSchema, ReplyRuntimeConfigSchemaShape, buildChannelConfigSchema, buildGroupEntrySchema, buildMultiAccountChannelSchema, requireOpenAllowFrom } from "openclaw/plugin-sdk/channel-config-schema";
|
|
28
|
+
import { DmPolicySchema, GroupPolicySchema, MarkdownConfigSchema, ReplyRuntimeConfigSchemaShape, ReplyToModeSchema, buildChannelConfigSchema, buildGroupEntrySchema, buildMultiAccountChannelSchema, requireOpenAllowFrom } from "openclaw/plugin-sdk/channel-config-schema";
|
|
29
29
|
import { formatAllowFromLowercase, resolveAllowlistMatchByCandidates } from "openclaw/plugin-sdk/allow-from";
|
|
30
|
-
import { adaptScopedAccountAccessor, createScopedChannelConfigAdapter, createScopedDmSecurityResolver } from "openclaw/plugin-sdk/channel-config-helpers";
|
|
30
|
+
import { adaptScopedAccountAccessor, clearAccountFieldsFromConfigSection, createScopedChannelConfigAdapter, createScopedDmSecurityResolver } from "openclaw/plugin-sdk/channel-config-helpers";
|
|
31
31
|
import { requireChannelOpenAllowFrom, resolveLoggerBackedRuntime } from "openclaw/plugin-sdk/extension-shared";
|
|
32
32
|
import { z } from "zod";
|
|
33
33
|
import os from "node:os";
|
|
@@ -147,13 +147,6 @@ function resolveNextcloudTalkAccount(params) {
|
|
|
147
147
|
const accountEnabled = merged.enabled !== false;
|
|
148
148
|
const enabled = baseEnabled && accountEnabled;
|
|
149
149
|
const secretResolution = resolveNextcloudTalkSecret(accountId, merged);
|
|
150
|
-
const apiCredentialResolution = resolveNextcloudTalkApiCredentialsResult({
|
|
151
|
-
apiUser: merged.apiUser,
|
|
152
|
-
apiPassword: merged.apiPassword,
|
|
153
|
-
apiPasswordFile: merged.apiPasswordFile,
|
|
154
|
-
configPath: `channels.nextcloud-talk.accounts.${accountId}.apiPasswordFile`
|
|
155
|
-
});
|
|
156
|
-
const diagnostics = [secretResolution.diagnostic, apiCredentialResolution.status === "configured_unavailable" ? apiCredentialResolution.diagnostic : void 0].filter((diagnostic) => Boolean(diagnostic));
|
|
157
150
|
const baseUrl = merged.baseUrl?.trim()?.replace(/\/$/, "") ?? "";
|
|
158
151
|
debugAccounts("resolve", {
|
|
159
152
|
accountId,
|
|
@@ -169,8 +162,7 @@ function resolveNextcloudTalkAccount(params) {
|
|
|
169
162
|
secret: secretResolution.secret,
|
|
170
163
|
secretSource: secretResolution.source,
|
|
171
164
|
tokenStatus: secretResolution.status,
|
|
172
|
-
|
|
173
|
-
...diagnostics.length > 0 ? { credentialDiagnostics: diagnostics } : {},
|
|
165
|
+
...secretResolution.diagnostic ? { credentialDiagnostics: [secretResolution.diagnostic] } : {},
|
|
174
166
|
config: merged
|
|
175
167
|
};
|
|
176
168
|
};
|
|
@@ -182,6 +174,21 @@ function resolveNextcloudTalkAccount(params) {
|
|
|
182
174
|
resolveDefaultAccountId: () => resolveDefaultNextcloudTalkAccountId(params.cfg)
|
|
183
175
|
});
|
|
184
176
|
}
|
|
177
|
+
function inspectNextcloudTalkAccount(params) {
|
|
178
|
+
const account = resolveNextcloudTalkAccount(params);
|
|
179
|
+
const apiCredentialResolution = resolveNextcloudTalkApiCredentialsResult({
|
|
180
|
+
apiUser: account.config.apiUser,
|
|
181
|
+
apiPassword: account.config.apiPassword,
|
|
182
|
+
apiPasswordFile: account.config.apiPasswordFile,
|
|
183
|
+
configPath: `channels.nextcloud-talk.accounts.${account.accountId}.apiPasswordFile`
|
|
184
|
+
});
|
|
185
|
+
const credentialDiagnostics = [...account.credentialDiagnostics ?? [], ...apiCredentialResolution.status === "configured_unavailable" ? [apiCredentialResolution.diagnostic] : []];
|
|
186
|
+
return {
|
|
187
|
+
...account,
|
|
188
|
+
apiCredentialStatus: apiCredentialResolution.status,
|
|
189
|
+
...credentialDiagnostics.length > 0 ? { credentialDiagnostics } : {}
|
|
190
|
+
};
|
|
191
|
+
}
|
|
185
192
|
//#endregion
|
|
186
193
|
//#region extensions/nextcloud-talk/src/approval-auth.ts
|
|
187
194
|
function normalizeNextcloudTalkApproverId(value) {
|
|
@@ -203,6 +210,18 @@ async function releaseNextcloudTalkGuardedResponse(params) {
|
|
|
203
210
|
if (!params.response.bodyUsed) await params.response.body?.cancel().catch(() => void 0);
|
|
204
211
|
await params.release();
|
|
205
212
|
}
|
|
213
|
+
async function readNextcloudTalkErrorBody(response, ...credentials) {
|
|
214
|
+
try {
|
|
215
|
+
let body = await readProviderTextResponse(response, "Nextcloud Talk error", {
|
|
216
|
+
maxBytes: 8 * 1024,
|
|
217
|
+
chunkTimeoutMs: 1e4
|
|
218
|
+
});
|
|
219
|
+
for (const credential of credentials) body = body.replaceAll(credential, "***");
|
|
220
|
+
return redactToolPayloadText(body);
|
|
221
|
+
} catch {
|
|
222
|
+
return "";
|
|
223
|
+
}
|
|
224
|
+
}
|
|
206
225
|
//#endregion
|
|
207
226
|
//#region extensions/nextcloud-talk/src/signature.ts
|
|
208
227
|
const SIGNATURE_HEADER = "x-nextcloud-talk-signature";
|
|
@@ -249,7 +268,6 @@ function generateNextcloudTalkSignature(params) {
|
|
|
249
268
|
//#endregion
|
|
250
269
|
//#region extensions/nextcloud-talk/src/bot-preflight.ts
|
|
251
270
|
const BOT_FEATURE_RESPONSE = 2;
|
|
252
|
-
const BOT_PREFLIGHT_ERROR_BODY_LIMIT_BYTES = 8 * 1024;
|
|
253
271
|
function normalizeUrlForMatch(value) {
|
|
254
272
|
if (!value?.trim()) return "";
|
|
255
273
|
try {
|
|
@@ -314,7 +332,7 @@ async function probeNextcloudTalkBotResponseFeature(params) {
|
|
|
314
332
|
});
|
|
315
333
|
try {
|
|
316
334
|
if (!response.ok) {
|
|
317
|
-
const body = await
|
|
335
|
+
const body = await readNextcloudTalkErrorBody(response, auth, credentials.apiPassword);
|
|
318
336
|
return {
|
|
319
337
|
ok: false,
|
|
320
338
|
code: "api_error",
|
|
@@ -366,6 +384,7 @@ const nextcloudTalkConfigAdapter = createScopedChannelConfigAdapter({
|
|
|
366
384
|
sectionKey: "nextcloud-talk",
|
|
367
385
|
listAccountIds: listNextcloudTalkAccountIds,
|
|
368
386
|
resolveAccount: adaptScopedAccountAccessor(resolveNextcloudTalkAccount),
|
|
387
|
+
inspectAccount: adaptScopedAccountAccessor(inspectNextcloudTalkAccount),
|
|
369
388
|
defaultAccountId: resolveDefaultNextcloudTalkAccountId,
|
|
370
389
|
clearBaseFields: [
|
|
371
390
|
"botSecret",
|
|
@@ -401,6 +420,7 @@ const NextcloudTalkConfigSchema = buildMultiAccountChannelSchema(z.object({
|
|
|
401
420
|
name: z.string().optional(),
|
|
402
421
|
enabled: z.boolean().optional(),
|
|
403
422
|
configWrites: z.boolean().optional(),
|
|
423
|
+
replyToMode: ReplyToModeSchema.optional(),
|
|
404
424
|
markdown: MarkdownConfigSchema,
|
|
405
425
|
baseUrl: z.string().optional(),
|
|
406
426
|
botSecret: buildSecretInputSchema().optional(),
|
|
@@ -696,7 +716,6 @@ function looksLikeNextcloudTalkTargetId(raw) {
|
|
|
696
716
|
}
|
|
697
717
|
//#endregion
|
|
698
718
|
//#region extensions/nextcloud-talk/src/send.ts
|
|
699
|
-
const NEXTCLOUD_TALK_ERROR_SNIPPET_MAX_BYTES = 8 * 1024;
|
|
700
719
|
const NEXTCLOUD_TALK_ERROR_SNIPPET_MAX_CHARS = 200;
|
|
701
720
|
const NEXTCLOUD_TALK_SEND_TIMEOUT_MS = 3e4;
|
|
702
721
|
const NEXTCLOUD_TALK_FORMAT_PROFILE = FormatCapabilityProfile.define({
|
|
@@ -717,20 +736,12 @@ function renderNextcloudTalkMarkdown(markdown) {
|
|
|
717
736
|
escapeText: (text) => text
|
|
718
737
|
}, NEXTCLOUD_TALK_FORMAT_PROFILE);
|
|
719
738
|
}
|
|
720
|
-
/** Collapses
|
|
739
|
+
/** Collapses and caps an already-redacted error body for display. */
|
|
721
740
|
function collapseErrorSnippet(text) {
|
|
722
741
|
const collapsed = text.replace(/\s+/g, " ").trim();
|
|
723
742
|
if (collapsed.length > NEXTCLOUD_TALK_ERROR_SNIPPET_MAX_CHARS) return `${truncateUtf16Safe(collapsed, NEXTCLOUD_TALK_ERROR_SNIPPET_MAX_CHARS)}…`;
|
|
724
743
|
return collapsed;
|
|
725
744
|
}
|
|
726
|
-
/** Reads a bounded, collapsed error-body snippet without buffering hostile responses. */
|
|
727
|
-
async function readNextcloudTalkErrorSnippet(response) {
|
|
728
|
-
try {
|
|
729
|
-
return collapseErrorSnippet(await readResponseTextLimited(response, NEXTCLOUD_TALK_ERROR_SNIPPET_MAX_BYTES));
|
|
730
|
-
} catch {
|
|
731
|
-
return "";
|
|
732
|
-
}
|
|
733
|
-
}
|
|
734
745
|
function resolveCredentials(explicit, account) {
|
|
735
746
|
const baseUrl = explicit.baseUrl?.trim() ?? account.baseUrl;
|
|
736
747
|
const secret = explicit.secret?.trim() ?? account.secret;
|
|
@@ -821,7 +832,7 @@ async function sendMessageNextcloudTalk(to, text, opts) {
|
|
|
821
832
|
});
|
|
822
833
|
try {
|
|
823
834
|
if (!response.ok) {
|
|
824
|
-
const errorBody = await
|
|
835
|
+
const errorBody = collapseErrorSnippet(await readNextcloudTalkErrorBody(response, signature));
|
|
825
836
|
const status = response.status;
|
|
826
837
|
let errorMsg = `Nextcloud Talk send failed (${status})`;
|
|
827
838
|
if (status === 400) errorMsg = `Nextcloud Talk: bad request - ${errorBody || "invalid message format"}`;
|
|
@@ -883,7 +894,7 @@ async function sendReactionNextcloudTalk(roomToken, messageId, reaction, opts) {
|
|
|
883
894
|
});
|
|
884
895
|
try {
|
|
885
896
|
if (!response.ok) {
|
|
886
|
-
const errorBody = await
|
|
897
|
+
const errorBody = collapseErrorSnippet(await readNextcloudTalkErrorBody(response, signature));
|
|
887
898
|
throw new Error(`Nextcloud Talk reaction failed: ${response.status} ${errorBody}`.trim());
|
|
888
899
|
}
|
|
889
900
|
return { ok: true };
|
|
@@ -954,7 +965,15 @@ async function handleNextcloudTalkInbound(params) {
|
|
|
954
965
|
accountId: account.accountId
|
|
955
966
|
});
|
|
956
967
|
const rawBody = message.text?.trim() ?? "";
|
|
957
|
-
if (!rawBody)
|
|
968
|
+
if (!rawBody) {
|
|
969
|
+
logInboundDrop({
|
|
970
|
+
log: (messageLocal) => runtime.log?.(messageLocal),
|
|
971
|
+
channel: CHANNEL_ID,
|
|
972
|
+
reason: `empty message body (mediaType=${message.mediaType})`,
|
|
973
|
+
target: message.senderId
|
|
974
|
+
});
|
|
975
|
+
return;
|
|
976
|
+
}
|
|
958
977
|
const roomKind = await resolveNextcloudTalkRoomKind({
|
|
959
978
|
account,
|
|
960
979
|
roomToken: message.roomToken,
|
|
@@ -1414,6 +1433,7 @@ function createNextcloudTalkWebhookServer(opts) {
|
|
|
1414
1433
|
const stop = async () => {
|
|
1415
1434
|
stopRequested = true;
|
|
1416
1435
|
await closeIfListening();
|
|
1436
|
+
webhookAuthRateLimiter.dispose();
|
|
1417
1437
|
};
|
|
1418
1438
|
const start = () => {
|
|
1419
1439
|
if (stopRequested) return Promise.resolve();
|
|
@@ -1440,6 +1460,12 @@ function createNextcloudTalkWebhookServer(opts) {
|
|
|
1440
1460
|
//#endregion
|
|
1441
1461
|
//#region extensions/nextcloud-talk/src/webhook-spool.ts
|
|
1442
1462
|
const NEXTCLOUD_TALK_INGRESS_POLL_INTERVAL_MS = 500;
|
|
1463
|
+
function describeIgnoredWebhookEvent(rawEvent) {
|
|
1464
|
+
const envelope = parseRawObject(rawEvent);
|
|
1465
|
+
const type = typeof envelope.type === "string" ? envelope.type : "unknown";
|
|
1466
|
+
const object = isRecord(envelope.object) ? envelope.object : null;
|
|
1467
|
+
return `type=${type} objectType=${typeof object?.type === "string" ? object.type : "unknown"}`;
|
|
1468
|
+
}
|
|
1443
1469
|
const NextcloudTalkWebhookPayloadSchema = z.object({
|
|
1444
1470
|
type: z.enum([
|
|
1445
1471
|
"Create",
|
|
@@ -1566,7 +1592,11 @@ function createNextcloudTalkWebhookSpool(options) {
|
|
|
1566
1592
|
if (stopping) return Promise.reject(/* @__PURE__ */ new Error("Nextcloud Talk ingress stopped"));
|
|
1567
1593
|
const receiveTask = (async () => {
|
|
1568
1594
|
await startAfterMigration;
|
|
1569
|
-
|
|
1595
|
+
if ((await monitor.admit(rawEvent)).kind === "ignored") {
|
|
1596
|
+
options.runtime.log?.(`nextcloud-talk: ignored non-message webhook event (${describeIgnoredWebhookEvent(rawEvent)})`);
|
|
1597
|
+
return "ignored";
|
|
1598
|
+
}
|
|
1599
|
+
return "accepted";
|
|
1570
1600
|
})();
|
|
1571
1601
|
inFlightReceives.add(receiveTask);
|
|
1572
1602
|
receiveTask.then(() => inFlightReceives.delete(receiveTask), () => inFlightReceives.delete(receiveTask));
|
|
@@ -1710,44 +1740,18 @@ const nextcloudTalkGatewayAdapter = {
|
|
|
1710
1740
|
});
|
|
1711
1741
|
},
|
|
1712
1742
|
logoutAccount: async ({ accountId, cfg }) => {
|
|
1713
|
-
const
|
|
1714
|
-
|
|
1715
|
-
|
|
1716
|
-
|
|
1717
|
-
|
|
1718
|
-
|
|
1719
|
-
delete nextSection.botSecret;
|
|
1720
|
-
cleared = true;
|
|
1721
|
-
changed = true;
|
|
1722
|
-
}
|
|
1723
|
-
const accountCleanup = clearAccountEntryFields({
|
|
1724
|
-
accounts: nextSection.accounts,
|
|
1725
|
-
accountId,
|
|
1726
|
-
fields: ["botSecret"]
|
|
1727
|
-
});
|
|
1728
|
-
if (accountCleanup.changed) {
|
|
1729
|
-
changed = true;
|
|
1730
|
-
if (accountCleanup.cleared) cleared = true;
|
|
1731
|
-
if (accountCleanup.nextAccounts) nextSection.accounts = accountCleanup.nextAccounts;
|
|
1732
|
-
else delete nextSection.accounts;
|
|
1733
|
-
}
|
|
1734
|
-
}
|
|
1735
|
-
if (changed) if (nextSection && Object.keys(nextSection).length > 0) nextCfg.channels = {
|
|
1736
|
-
...nextCfg.channels,
|
|
1737
|
-
"nextcloud-talk": nextSection
|
|
1738
|
-
};
|
|
1739
|
-
else {
|
|
1740
|
-
const nextChannels = { ...nextCfg.channels };
|
|
1741
|
-
delete nextChannels["nextcloud-talk"];
|
|
1742
|
-
if (Object.keys(nextChannels).length > 0) nextCfg.channels = nextChannels;
|
|
1743
|
-
else delete nextCfg.channels;
|
|
1744
|
-
}
|
|
1743
|
+
const { nextConfig, changed, cleared } = clearAccountFieldsFromConfigSection({
|
|
1744
|
+
cfg,
|
|
1745
|
+
sectionKey: "nextcloud-talk",
|
|
1746
|
+
accountId,
|
|
1747
|
+
fields: ["botSecret"]
|
|
1748
|
+
});
|
|
1745
1749
|
const loggedOut = resolveNextcloudTalkAccount({
|
|
1746
|
-
cfg:
|
|
1750
|
+
cfg: nextConfig,
|
|
1747
1751
|
accountId
|
|
1748
1752
|
}).secretSource === "none";
|
|
1749
1753
|
if (changed) await getNextcloudTalkRuntime().config.replaceConfigFile({
|
|
1750
|
-
nextConfig
|
|
1754
|
+
nextConfig,
|
|
1751
1755
|
afterWrite: { mode: "auto" }
|
|
1752
1756
|
});
|
|
1753
1757
|
return {
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { t as nextcloudTalkPlugin } from "./channel-
|
|
1
|
+
import { t as nextcloudTalkPlugin } from "./channel-C7Xe0Nkb.js";
|
|
2
2
|
export { nextcloudTalkPlugin };
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { DEFAULT_ACCOUNT_ID, hasConfiguredAccountValue, mergeAccountConfig } from "openclaw/plugin-sdk/account-core";
|
|
2
|
+
//#region extensions/nextcloud-talk/configured-state.ts
|
|
3
|
+
function hasConfiguredNextcloudAccount(account, env) {
|
|
4
|
+
return Boolean(account?.baseUrl?.trim() && (hasConfiguredAccountValue(account.botSecret) || hasConfiguredAccountValue(account.botSecretFile) || hasConfiguredAccountValue(env.NEXTCLOUD_TALK_BOT_SECRET)));
|
|
5
|
+
}
|
|
6
|
+
/** Require a Nextcloud server plus its account-owned bot credential. */
|
|
7
|
+
function hasConfiguredNextcloudTalkChannelState(params) {
|
|
8
|
+
const channel = params.cfg.channels?.["nextcloud-talk"];
|
|
9
|
+
if (channel?.enabled === false) return false;
|
|
10
|
+
const defaultAccount = channel?.accounts?.[DEFAULT_ACCOUNT_ID];
|
|
11
|
+
if (defaultAccount?.enabled !== false) {
|
|
12
|
+
if (hasConfiguredNextcloudAccount(defaultAccount ? mergeAccountConfig({
|
|
13
|
+
channelConfig: channel,
|
|
14
|
+
accountConfig: defaultAccount,
|
|
15
|
+
omitKeys: ["defaultAccount"]
|
|
16
|
+
}) : channel, params.env ?? process.env)) return true;
|
|
17
|
+
}
|
|
18
|
+
return Object.entries(channel?.accounts ?? {}).some(([accountId, account]) => accountId !== DEFAULT_ACCOUNT_ID && account.enabled !== false && hasConfiguredNextcloudAccount(mergeAccountConfig({
|
|
19
|
+
channelConfig: channel,
|
|
20
|
+
accountConfig: account,
|
|
21
|
+
omitKeys: ["defaultAccount"]
|
|
22
|
+
}), {}));
|
|
23
|
+
}
|
|
24
|
+
//#endregion
|
|
25
|
+
export { hasConfiguredNextcloudTalkChannelState };
|
package/openclaw.plugin.json
CHANGED
|
@@ -32,6 +32,26 @@
|
|
|
32
32
|
"configWrites": {
|
|
33
33
|
"type": "boolean"
|
|
34
34
|
},
|
|
35
|
+
"replyToMode": {
|
|
36
|
+
"anyOf": [
|
|
37
|
+
{
|
|
38
|
+
"type": "string",
|
|
39
|
+
"const": "off"
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
"type": "string",
|
|
43
|
+
"const": "first"
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
"type": "string",
|
|
47
|
+
"const": "all"
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
"type": "string",
|
|
51
|
+
"const": "batched"
|
|
52
|
+
}
|
|
53
|
+
]
|
|
54
|
+
},
|
|
35
55
|
"markdown": {
|
|
36
56
|
"type": "object",
|
|
37
57
|
"properties": {
|
|
@@ -479,6 +499,26 @@
|
|
|
479
499
|
"configWrites": {
|
|
480
500
|
"type": "boolean"
|
|
481
501
|
},
|
|
502
|
+
"replyToMode": {
|
|
503
|
+
"anyOf": [
|
|
504
|
+
{
|
|
505
|
+
"type": "string",
|
|
506
|
+
"const": "off"
|
|
507
|
+
},
|
|
508
|
+
{
|
|
509
|
+
"type": "string",
|
|
510
|
+
"const": "first"
|
|
511
|
+
},
|
|
512
|
+
{
|
|
513
|
+
"type": "string",
|
|
514
|
+
"const": "all"
|
|
515
|
+
},
|
|
516
|
+
{
|
|
517
|
+
"type": "string",
|
|
518
|
+
"const": "batched"
|
|
519
|
+
}
|
|
520
|
+
]
|
|
521
|
+
},
|
|
482
522
|
"markdown": {
|
|
483
523
|
"type": "object",
|
|
484
524
|
"properties": {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@openclaw/nextcloud-talk",
|
|
3
|
-
"version": "2026.8.1
|
|
3
|
+
"version": "2026.8.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.8.1
|
|
11
|
+
"openclaw": ">=2026.8.1"
|
|
12
12
|
},
|
|
13
13
|
"peerDependenciesMeta": {
|
|
14
14
|
"openclaw": {
|
|
@@ -31,7 +31,9 @@
|
|
|
31
31
|
"NEXTCLOUD_TALK_BOT_SECRET",
|
|
32
32
|
"NEXTCLOUD_TALK_API_PASSWORD"
|
|
33
33
|
]
|
|
34
|
-
}
|
|
34
|
+
},
|
|
35
|
+
"specifier": "./dist/configured-state.js",
|
|
36
|
+
"exportName": "hasConfiguredNextcloudTalkChannelState"
|
|
35
37
|
},
|
|
36
38
|
"label": "Nextcloud Talk",
|
|
37
39
|
"selectionLabel": "Nextcloud Talk (self-hosted)",
|
|
@@ -127,10 +129,10 @@
|
|
|
127
129
|
"minHostVersion": ">=2026.4.10"
|
|
128
130
|
},
|
|
129
131
|
"compat": {
|
|
130
|
-
"pluginApi": ">=2026.8.1
|
|
132
|
+
"pluginApi": ">=2026.8.1"
|
|
131
133
|
},
|
|
132
134
|
"build": {
|
|
133
|
-
"openclawVersion": "2026.8.1
|
|
135
|
+
"openclawVersion": "2026.8.1"
|
|
134
136
|
},
|
|
135
137
|
"release": {
|
|
136
138
|
"publishToClawHub": true,
|