@openclaw/qqbot 2026.5.3 → 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 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-N6Y_Rcjp.js";
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-DXtpwWui.js";
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-CmSUJKSt.js");
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-N6Y_Rcjp.js";
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-DXtpwWui.js";
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 normalized = normalizeQQBotAllowFrom(params.isGroup && params.groupAllowFrom && params.groupAllowFrom.length > 0 ? params.groupAllowFrom : params.allowFrom);
659
- if (!normalized.some((entry) => entry !== "*")) return false;
660
- return createQQBotSenderMatcher(params.senderId)(normalized);
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",
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.3"
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.3"
53
+ "pluginApi": ">=2026.5.4-beta.1"
54
54
  },
55
55
  "build": {
56
- "openclawVersion": "2026.5.3"
56
+ "openclawVersion": "2026.5.4-beta.1"
57
57
  },
58
58
  "release": {
59
59
  "publishToClawHub": true,