@openclaw/qqbot 2026.5.3-beta.4 → 2026.5.4-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 +13 -2
- package/dist/{channel-N6Y_Rcjp.js → channel-YUxl6Z0S.js} +1 -1
- package/dist/channel-plugin-api.js +1 -1
- package/dist/{gateway-CmSUJKSt.js → gateway-C78cdZZC.js} +33 -6
- package/dist/{request-context-DXtpwWui.js → request-context-C-VU3Sf9.js} +2 -0
- package/package.json +4 -4
package/dist/api.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { C as recordMessageReply, E as setOutboundAudioPort, S as getMessageReplyStats, T as OUTBOUND_ERROR_CODES, _ as sendVoice, a as sendText, b as checkMessageReplyLimit, d as buildMediaTarget, f as parseTarget, g as sendVideoMsg, h as sendPhoto, i as sendProactiveMessage, m as sendDocument, n as sendCronMessage, p as resolveOutboundMediaPath, r as sendMedia, v as resolveUserFacingMediaError, w as DEFAULT_MEDIA_SEND_ERROR, x as getMessageReplyConfig, y as MESSAGE_REPLY_LIMIT } from "./outbound-BJfhwrPg.js";
|
|
2
2
|
import { a as resolveQQBotAccount, i as resolveDefaultQQBotAccountId, n as applyQQBotAccountConfig, r as listQQBotAccountIds, t as DEFAULT_ACCOUNT_ID } from "./config-D6545NkC.js";
|
|
3
|
-
import { t as qqbotPlugin } from "./channel-
|
|
3
|
+
import { t as qqbotPlugin } from "./channel-YUxl6Z0S.js";
|
|
4
4
|
import { C as debugLog, L as formatErrorMessage, S as debugError, o as getAccessToken } from "./sender-p-B14eLG.js";
|
|
5
5
|
import { t as qqbotSetupPlugin } from "./channel.setup-ByCRAe5H.js";
|
|
6
|
-
import { r as getFrameworkCommands, t as getRequestContext } from "./request-context-
|
|
6
|
+
import { r as getFrameworkCommands, t as getRequestContext } from "./request-context-C-VU3Sf9.js";
|
|
7
7
|
import { callGatewayTool } from "openclaw/plugin-sdk/agent-harness-runtime";
|
|
8
8
|
//#region extensions/qqbot/src/engine/tools/channel-api.ts
|
|
9
9
|
/**
|
|
@@ -612,6 +612,16 @@ async function dispatchFrameworkSlashResult({ result, account, from, logger }) {
|
|
|
612
612
|
}
|
|
613
613
|
//#endregion
|
|
614
614
|
//#region extensions/qqbot/src/bridge/commands/framework-registration.ts
|
|
615
|
+
const PRIVATE_CHAT_ONLY_TEXT = "💡 请在私聊中使用此指令";
|
|
616
|
+
function isExplicitQQBotC2cFrom(from) {
|
|
617
|
+
const raw = (from ?? "").trim();
|
|
618
|
+
const stripped = raw.replace(/^qqbot:/iu, "");
|
|
619
|
+
const colonIdx = stripped.indexOf(":");
|
|
620
|
+
if (colonIdx === -1) return false;
|
|
621
|
+
const kind = stripped.slice(0, colonIdx).toLowerCase();
|
|
622
|
+
const targetId = stripped.slice(colonIdx + 1).trim();
|
|
623
|
+
return /^qqbot:/iu.test(raw) && kind === "c2c" && targetId.length > 0;
|
|
624
|
+
}
|
|
615
625
|
function registerQQBotFrameworkCommands(api) {
|
|
616
626
|
for (const cmd of getFrameworkCommands()) api.registerCommand({
|
|
617
627
|
name: cmd.name,
|
|
@@ -619,6 +629,7 @@ function registerQQBotFrameworkCommands(api) {
|
|
|
619
629
|
requireAuth: true,
|
|
620
630
|
acceptsArgs: true,
|
|
621
631
|
handler: async (ctx) => {
|
|
632
|
+
if (cmd.c2cOnly && !isExplicitQQBotC2cFrom(ctx.from)) return { text: PRIVATE_CHAT_ONLY_TEXT };
|
|
622
633
|
const from = parseQQBotFrom(ctx.from);
|
|
623
634
|
const account = resolveQQBotAccount(ctx.config, ctx.accountId ?? void 0);
|
|
624
635
|
const slashCtx = buildFrameworkSlashContext({
|
|
@@ -344,7 +344,7 @@ function clearAccountCredentials(cfg, accountId) {
|
|
|
344
344
|
//#region extensions/qqbot/src/channel.ts
|
|
345
345
|
let _gatewayModulePromise;
|
|
346
346
|
function loadGatewayModule() {
|
|
347
|
-
_gatewayModulePromise ??= import("./gateway-
|
|
347
|
+
_gatewayModulePromise ??= import("./gateway-C78cdZZC.js");
|
|
348
348
|
return _gatewayModulePromise;
|
|
349
349
|
}
|
|
350
350
|
const EXEC_APPROVAL_COMMAND_RE = /\/approve(?:@[^\s]+)?\s+[A-Za-z0-9][A-Za-z0-9._:-]*\s+(?:allow-once|allow-always|always|deny)\b/i;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { t as qqbotPlugin } from "./channel-
|
|
1
|
+
import { t as qqbotPlugin } from "./channel-YUxl6Z0S.js";
|
|
2
2
|
export { qqbotPlugin };
|
|
@@ -6,7 +6,7 @@ import { t as toGatewayAccount } from "./narrowing-BoieBTIU.js";
|
|
|
6
6
|
import { B as StreamInputState, C as debugLog, E as getNextMsgSeq, I as formatDuration, L as formatErrorMessage, N as getImageMimeType, P as getMaxUploadSize, R as StreamContentType, S as debugError, a as createRawInputNotifyFn, b as withTokenRetry, c as getMessageApi, d as initSender, f as onMessageSent, g as sendText, h as sendMedia$1, i as clearTokenCache, j as formatFileSize, k as downloadFile, l as getPluginUserAgent, m as sendInputNotify, n as acknowledgeInteraction, o as getAccessToken, p as registerAccount, r as buildDeliveryTarget, s as getGatewayUrl, t as accountToCreds, u as initApiConfig, v as startBackgroundTokenRefresh, w as debugWarn, x as openLocalFile, y as stopBackgroundTokenRefresh, z as StreamInputMode } from "./sender-p-B14eLG.js";
|
|
7
7
|
import { n as getQQBotRuntimeForEngine, t as getQQBotRuntime } from "./runtime-BJAS3eXW.js";
|
|
8
8
|
import { a as getHomeDir, c as getQQBotMediaDir, d as isLocalPath, f as isWindows, i as checkSilkWasmAvailable, m as resolveQQBotPayloadLocalFilePath, o as getQQBotDataDir, p as normalizePath$1, s as getQQBotDataPath, u as getTempDir } from "./target-parser-Y0prnrXD.js";
|
|
9
|
-
import { a as getPluginVersion, i as getFrameworkVersion, n as runWithRequestContext, o as initCommands, s as matchSlashCommand } from "./request-context-
|
|
9
|
+
import { a as getPluginVersion, i as getFrameworkVersion, n as runWithRequestContext, o as initCommands, s as matchSlashCommand } from "./request-context-C-VU3Sf9.js";
|
|
10
10
|
import * as fs$1 from "node:fs";
|
|
11
11
|
import fs from "node:fs";
|
|
12
12
|
import * as os$1 from "node:os";
|
|
@@ -642,22 +642,47 @@ function buildResultBase(ctx) {
|
|
|
642
642
|
* A wide-open DM policy means "anyone can chat", not "anyone can run
|
|
643
643
|
* admin commands".
|
|
644
644
|
*/
|
|
645
|
+
function isSlashCommandAuthEntry(value) {
|
|
646
|
+
return typeof value === "string" || typeof value === "number";
|
|
647
|
+
}
|
|
648
|
+
function readSlashCommandAuthList(value) {
|
|
649
|
+
if (!Array.isArray(value)) return;
|
|
650
|
+
return value.filter(isSlashCommandAuthEntry);
|
|
651
|
+
}
|
|
652
|
+
/**
|
|
653
|
+
* Resolve the command-specific QQBot allowlist from the root OpenClaw config.
|
|
654
|
+
*
|
|
655
|
+
* `commands.allowFrom.qqbot` takes precedence over the global
|
|
656
|
+
* `commands.allowFrom["*"]`, matching the framework command authorization
|
|
657
|
+
* contract used by registered plugin commands.
|
|
658
|
+
*/
|
|
659
|
+
function resolveQQBotCommandsAllowFrom(cfg) {
|
|
660
|
+
if (!cfg || typeof cfg !== "object") return;
|
|
661
|
+
const commands = cfg.commands;
|
|
662
|
+
if (!commands || typeof commands !== "object") return;
|
|
663
|
+
const allowFrom = commands.allowFrom;
|
|
664
|
+
if (!allowFrom || typeof allowFrom !== "object" || Array.isArray(allowFrom)) return;
|
|
665
|
+
const byProvider = allowFrom;
|
|
666
|
+
return readSlashCommandAuthList(byProvider.qqbot) ?? readSlashCommandAuthList(byProvider["*"]);
|
|
667
|
+
}
|
|
645
668
|
/**
|
|
646
669
|
* Determine whether `senderId` is authorized to execute `requireAuth`
|
|
647
670
|
* slash commands for the given account configuration.
|
|
648
671
|
*
|
|
649
672
|
* Authorization rules:
|
|
673
|
+
* - `commands.allowFrom.qqbot` / `commands.allowFrom["*"]` configured →
|
|
674
|
+
* use that command-specific list instead of channel allowFrom
|
|
650
675
|
* - `allowFrom` not configured / empty / only `["*"]` → **false**
|
|
651
676
|
* (wildcard means "open to everyone", not explicit authorization)
|
|
652
677
|
* - `allowFrom` contains at least one concrete entry AND sender
|
|
653
|
-
* matches → **true**
|
|
678
|
+
* matches a concrete entry → **true**
|
|
654
679
|
* - Group messages use `groupAllowFrom` when present, falling back
|
|
655
680
|
* to `allowFrom`.
|
|
656
681
|
*/
|
|
657
682
|
function resolveSlashCommandAuth(params) {
|
|
658
|
-
const
|
|
659
|
-
if (
|
|
660
|
-
return createQQBotSenderMatcher(params.senderId)(
|
|
683
|
+
const explicitEntries = normalizeQQBotAllowFrom(params.commandsAllowFrom ?? (params.isGroup && params.groupAllowFrom && params.groupAllowFrom.length > 0 ? params.groupAllowFrom : params.allowFrom)).filter((entry) => entry !== "*");
|
|
684
|
+
if (explicitEntries.length === 0) return false;
|
|
685
|
+
return createQQBotSenderMatcher(params.senderId)(explicitEntries);
|
|
661
686
|
}
|
|
662
687
|
//#endregion
|
|
663
688
|
//#region extensions/qqbot/src/engine/commands/slash-command-handler.ts
|
|
@@ -697,7 +722,8 @@ async function trySlashCommand(msg, ctx) {
|
|
|
697
722
|
senderId: msg.senderId,
|
|
698
723
|
isGroup: msg.type === "group" || msg.type === "guild",
|
|
699
724
|
allowFrom: account.config?.allowFrom,
|
|
700
|
-
groupAllowFrom: account.config?.groupAllowFrom
|
|
725
|
+
groupAllowFrom: account.config?.groupAllowFrom,
|
|
726
|
+
commandsAllowFrom: resolveQQBotCommandsAllowFrom(ctx.cfg)
|
|
701
727
|
}),
|
|
702
728
|
queueSnapshot: ctx.getQueueSnapshot(peerId)
|
|
703
729
|
};
|
|
@@ -1830,6 +1856,7 @@ var GatewayConnection = class {
|
|
|
1830
1856
|
this.currentWs = ws;
|
|
1831
1857
|
const slashCtx = {
|
|
1832
1858
|
account,
|
|
1859
|
+
cfg: this.ctx.cfg,
|
|
1833
1860
|
log,
|
|
1834
1861
|
getMessagePeerId: (msg) => this.msgQueue.getMessagePeerId(msg),
|
|
1835
1862
|
getQueueSnapshot: (peerId) => this.msgQueue.getSnapshot(peerId)
|
|
@@ -673,6 +673,7 @@ function registerStreamingCommands(registry) {
|
|
|
673
673
|
registry.register({
|
|
674
674
|
name: "bot-streaming",
|
|
675
675
|
description: "一键开关流式消息",
|
|
676
|
+
requireAuth: true,
|
|
676
677
|
c2cOnly: true,
|
|
677
678
|
usage: [
|
|
678
679
|
`/bot-streaming on 开启流式消息`,
|
|
@@ -801,6 +802,7 @@ var SlashCommandRegistry = class {
|
|
|
801
802
|
name: cmd.name,
|
|
802
803
|
description: cmd.description,
|
|
803
804
|
usage: cmd.usage,
|
|
805
|
+
c2cOnly: cmd.c2cOnly,
|
|
804
806
|
handler: cmd.handler
|
|
805
807
|
}));
|
|
806
808
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@openclaw/qqbot",
|
|
3
|
-
"version": "2026.5.
|
|
3
|
+
"version": "2026.5.4-beta.1",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "OpenClaw QQ Bot channel plugin",
|
|
6
6
|
"repository": {
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
"openclaw": "workspace:*"
|
|
22
22
|
},
|
|
23
23
|
"peerDependencies": {
|
|
24
|
-
"openclaw": ">=2026.5.
|
|
24
|
+
"openclaw": ">=2026.5.4-beta.1"
|
|
25
25
|
},
|
|
26
26
|
"peerDependenciesMeta": {
|
|
27
27
|
"openclaw": {
|
|
@@ -50,10 +50,10 @@
|
|
|
50
50
|
"minHostVersion": ">=2026.4.10"
|
|
51
51
|
},
|
|
52
52
|
"compat": {
|
|
53
|
-
"pluginApi": ">=2026.5.
|
|
53
|
+
"pluginApi": ">=2026.5.4-beta.1"
|
|
54
54
|
},
|
|
55
55
|
"build": {
|
|
56
|
-
"openclawVersion": "2026.5.
|
|
56
|
+
"openclawVersion": "2026.5.4-beta.1"
|
|
57
57
|
},
|
|
58
58
|
"release": {
|
|
59
59
|
"publishToClawHub": true,
|