@leoqlin/openclaw-qqbot 1.6.19 → 1.6.20
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/index.js +0 -20
- package/dist/src/slash-commands.js +43 -31
- package/index.ts +0 -24
- package/package.json +1 -1
- package/scripts/upgrade-via-npm.sh +1 -1
- package/skills/qqbot-upgrade/SKILL.md +2 -2
- package/src/slash-commands.ts +47 -33
package/dist/index.js
CHANGED
|
@@ -13,26 +13,6 @@ const plugin = {
|
|
|
13
13
|
api.registerChannel({ plugin: qqbotPlugin });
|
|
14
14
|
registerChannelTool(api);
|
|
15
15
|
registerRemindTool(api);
|
|
16
|
-
// 禁用内置 qqbot 插件,避免与本插件冲突
|
|
17
|
-
try {
|
|
18
|
-
const configApi = api.runtime.config;
|
|
19
|
-
const currentCfg = structuredClone(configApi.loadConfig());
|
|
20
|
-
const plugins = (currentCfg.plugins ?? {});
|
|
21
|
-
const entries = (plugins.entries ?? {});
|
|
22
|
-
const qqbotEntry = (entries.qqbot ?? {});
|
|
23
|
-
if (qqbotEntry.enabled !== false) {
|
|
24
|
-
qqbotEntry.enabled = false;
|
|
25
|
-
entries.qqbot = qqbotEntry;
|
|
26
|
-
plugins.entries = entries;
|
|
27
|
-
currentCfg.plugins = plugins;
|
|
28
|
-
configApi.writeConfigFile(currentCfg).catch((e) => {
|
|
29
|
-
console.warn(`[qqbot] failed to disable builtin qqbot plugin: ${e?.message ?? e}`);
|
|
30
|
-
});
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
catch (e) {
|
|
34
|
-
console.warn(`[qqbot] failed to disable builtin qqbot plugin: ${e?.message ?? e}`);
|
|
35
|
-
}
|
|
36
16
|
},
|
|
37
17
|
};
|
|
38
18
|
export default plugin;
|
|
@@ -1773,41 +1773,71 @@ registerCommand({
|
|
|
1773
1773
|
handler: async (ctx) => {
|
|
1774
1774
|
// 流式消息仅支持 C2C(私聊),群/频道场景直接提示
|
|
1775
1775
|
if (ctx.type !== "c2c") {
|
|
1776
|
-
return
|
|
1776
|
+
return `⚠️ 流式消息仅支持私聊场景,请在私聊中使用 /bot-streaming 指令`;
|
|
1777
1777
|
}
|
|
1778
1778
|
const arg = ctx.args.trim().toLowerCase();
|
|
1779
|
-
// 读取当前 streaming 状态
|
|
1780
1779
|
const currentStreaming = ctx.accountConfig?.streaming === true;
|
|
1780
|
+
// 指令 & 手动配置命令
|
|
1781
|
+
const slashOn = "/bot-streaming on";
|
|
1782
|
+
const slashOff = "/bot-streaming off";
|
|
1783
|
+
const cmdOn = "openclaw config set channels.qqbot.streaming true";
|
|
1784
|
+
const cmdOff = "openclaw config set channels.qqbot.streaming false";
|
|
1785
|
+
// 检测 runtime 是否可用(缓存结果,避免重复调用)
|
|
1786
|
+
let runtime = null;
|
|
1787
|
+
try {
|
|
1788
|
+
runtime = getQQBotRuntime();
|
|
1789
|
+
}
|
|
1790
|
+
catch { }
|
|
1791
|
+
// 构造指引文案:runtime 可用时用斜杠指令,否则用手动命令
|
|
1792
|
+
const guideLine = runtime
|
|
1793
|
+
? [
|
|
1794
|
+
`使用 <qqbot-cmd-input text="${slashOn}" show="${slashOn}"/> 开启`,
|
|
1795
|
+
`使用 <qqbot-cmd-input text="${slashOff}" show="${slashOff}"/> 关闭`,
|
|
1796
|
+
]
|
|
1797
|
+
: [
|
|
1798
|
+
`点击指令 <qqbot-cmd-input text="${cmdOn}" show="${cmdOn}"/> 开启`,
|
|
1799
|
+
`点击指令 <qqbot-cmd-input text="${cmdOff}" show="${cmdOff}"/> 关闭`,
|
|
1800
|
+
];
|
|
1781
1801
|
// 无参数:查看当前状态
|
|
1782
1802
|
if (!arg) {
|
|
1803
|
+
const icon = runtime ? "📡" : "👀";
|
|
1783
1804
|
return [
|
|
1784
|
-
|
|
1805
|
+
`${icon}${runtime ? " " : ""}当前流式消息状态:${currentStreaming ? "✅ 已开启" : "🚫 已关闭"}`,
|
|
1785
1806
|
``,
|
|
1786
|
-
|
|
1787
|
-
`使用 <qqbot-cmd-input text="/bot-streaming off" show="/bot-streaming off"/> 关闭`,
|
|
1807
|
+
...guideLine,
|
|
1788
1808
|
].join("\n");
|
|
1789
1809
|
}
|
|
1790
1810
|
if (arg !== "on" && arg !== "off") {
|
|
1791
|
-
return
|
|
1811
|
+
return `⚠️ 参数错误,请使用 on 或 off\n\n示例:${slashOn}`;
|
|
1812
|
+
}
|
|
1813
|
+
// runtime 不可用,无法修改配置,返回降级文案
|
|
1814
|
+
if (!runtime) {
|
|
1815
|
+
const fwVer = getFrameworkVersion();
|
|
1816
|
+
return [
|
|
1817
|
+
`⚠️ 当前版本不支持该指令`,
|
|
1818
|
+
``,
|
|
1819
|
+
`🦞 框架版本:${fwVer}`,
|
|
1820
|
+
`🤖 QQBot 插件版本:v${PLUGIN_VERSION}`,
|
|
1821
|
+
``,
|
|
1822
|
+
...guideLine,
|
|
1823
|
+
].join("\n");
|
|
1792
1824
|
}
|
|
1793
1825
|
const newStreaming = arg === "on";
|
|
1794
1826
|
// 如果状态没变,直接返回
|
|
1795
1827
|
if (newStreaming === currentStreaming) {
|
|
1796
1828
|
return `📡 流式消息已经是${newStreaming ? "开启" : "关闭"}状态,无需操作`;
|
|
1797
1829
|
}
|
|
1798
|
-
//
|
|
1830
|
+
// 更新配置
|
|
1799
1831
|
try {
|
|
1800
|
-
const runtime = getQQBotRuntime();
|
|
1801
1832
|
const configApi = runtime.config;
|
|
1802
1833
|
const currentCfg = structuredClone(configApi.loadConfig());
|
|
1803
1834
|
const qqbot = (currentCfg.channels ?? {}).qqbot;
|
|
1804
1835
|
if (!qqbot) {
|
|
1805
|
-
return
|
|
1836
|
+
return `⚠️ 配置文件中未找到 qqbot 通道配置`;
|
|
1806
1837
|
}
|
|
1807
1838
|
const accountId = ctx.accountId;
|
|
1808
1839
|
const isNamedAccount = accountId !== "default" && qqbot.accounts?.[accountId];
|
|
1809
1840
|
if (isNamedAccount) {
|
|
1810
|
-
// 命名账户:更新 accounts.{accountId}.streaming
|
|
1811
1841
|
const accounts = qqbot.accounts;
|
|
1812
1842
|
const acct = accounts[accountId] ?? {};
|
|
1813
1843
|
acct.streaming = newStreaming;
|
|
@@ -1815,36 +1845,18 @@ registerCommand({
|
|
|
1815
1845
|
qqbot.accounts = accounts;
|
|
1816
1846
|
}
|
|
1817
1847
|
else {
|
|
1818
|
-
// 默认账户:更新 qqbot.streaming
|
|
1819
1848
|
qqbot.streaming = newStreaming;
|
|
1820
1849
|
}
|
|
1821
1850
|
await configApi.writeConfigFile(currentCfg);
|
|
1822
1851
|
return [
|
|
1823
1852
|
`✅ 流式消息已${newStreaming ? "开启" : "关闭"}`,
|
|
1824
|
-
``,
|
|
1825
1853
|
newStreaming
|
|
1826
|
-
?
|
|
1827
|
-
:
|
|
1854
|
+
? `我的回复将以流式形式逐步显示(仅私聊生效)。`
|
|
1855
|
+
: `我的回复将以完整消息发送。`,
|
|
1828
1856
|
].join("\n");
|
|
1829
1857
|
}
|
|
1830
1858
|
catch (err) {
|
|
1831
|
-
|
|
1832
|
-
return [
|
|
1833
|
-
`❌ 当前版本不支持该指令`,
|
|
1834
|
-
``,
|
|
1835
|
-
`🦞框架版本:${fwVer}`,
|
|
1836
|
-
`🤖QQBot 插件版本:v${PLUGIN_VERSION}`,
|
|
1837
|
-
``,
|
|
1838
|
-
`可通过以下命令手动开启流式消息:`,
|
|
1839
|
-
``,
|
|
1840
|
-
`\`\`\`shell`,
|
|
1841
|
-
`# 1. 开启流式消息`,
|
|
1842
|
-
`openclaw config set channels.qqbot.streaming true`,
|
|
1843
|
-
``,
|
|
1844
|
-
`# 2. 重启网关使配置生效`,
|
|
1845
|
-
`openclaw gateway restart`,
|
|
1846
|
-
`\`\`\``,
|
|
1847
|
-
].join("\n");
|
|
1859
|
+
return `⚠️ 配置写入失败:${err?.message ?? err}`;
|
|
1848
1860
|
}
|
|
1849
1861
|
},
|
|
1850
1862
|
});
|
package/index.ts
CHANGED
|
@@ -16,30 +16,6 @@ const plugin = {
|
|
|
16
16
|
api.registerChannel({ plugin: qqbotPlugin as any });
|
|
17
17
|
registerChannelTool(api);
|
|
18
18
|
registerRemindTool(api);
|
|
19
|
-
|
|
20
|
-
// 禁用内置 qqbot 插件,避免与本插件冲突
|
|
21
|
-
try {
|
|
22
|
-
const configApi = api.runtime.config as {
|
|
23
|
-
loadConfig: () => Record<string, unknown>;
|
|
24
|
-
writeConfigFile: (cfg: unknown) => Promise<void>;
|
|
25
|
-
};
|
|
26
|
-
const currentCfg = structuredClone(configApi.loadConfig()) as Record<string, unknown>;
|
|
27
|
-
const plugins = (currentCfg.plugins ?? {}) as Record<string, unknown>;
|
|
28
|
-
const entries = (plugins.entries ?? {}) as Record<string, unknown>;
|
|
29
|
-
const qqbotEntry = (entries.qqbot ?? {}) as Record<string, unknown>;
|
|
30
|
-
|
|
31
|
-
if (qqbotEntry.enabled !== false) {
|
|
32
|
-
qqbotEntry.enabled = false;
|
|
33
|
-
entries.qqbot = qqbotEntry;
|
|
34
|
-
plugins.entries = entries;
|
|
35
|
-
currentCfg.plugins = plugins;
|
|
36
|
-
configApi.writeConfigFile(currentCfg).catch((e: any) => {
|
|
37
|
-
console.warn(`[qqbot] failed to disable builtin qqbot plugin: ${e?.message ?? e}`);
|
|
38
|
-
});
|
|
39
|
-
}
|
|
40
|
-
} catch (e: any) {
|
|
41
|
-
console.warn(`[qqbot] failed to disable builtin qqbot plugin: ${e?.message ?? e}`);
|
|
42
|
-
}
|
|
43
19
|
},
|
|
44
20
|
};
|
|
45
21
|
|
package/package.json
CHANGED
|
@@ -350,7 +350,7 @@ find "${TMPDIR:-/tmp}" -maxdepth 1 \( -name ".qqbot-upgrade-backup-*" -o -name "
|
|
|
350
350
|
# ============================================================================
|
|
351
351
|
# 参数解析
|
|
352
352
|
# ============================================================================
|
|
353
|
-
PKG_NAME="@
|
|
353
|
+
PKG_NAME="@tencent-connect/openclaw-qqbot"
|
|
354
354
|
PLUGIN_ID="openclaw-qqbot"
|
|
355
355
|
TARGET_VERSION=""
|
|
356
356
|
APPID=""
|
|
@@ -49,13 +49,13 @@ echo "远端最新: $REMOTE_VER"
|
|
|
49
49
|
在 **bash** 环境中执行(需已安装 `curl`,且能访问 GitHub):
|
|
50
50
|
|
|
51
51
|
```bash
|
|
52
|
-
curl -fsSL https://raw.githubusercontent.com/
|
|
52
|
+
curl -fsSL https://raw.githubusercontent.com/tencent-connect/openclaw-qqbot/main/scripts/upgrade-via-npm.sh | bash
|
|
53
53
|
```
|
|
54
54
|
|
|
55
55
|
说明:
|
|
56
56
|
|
|
57
57
|
- `-f`:HTTP 错误时失败;`-sS`:静默但保留错误输出;`-L`:跟随重定向
|
|
58
|
-
- 脚本由 [
|
|
58
|
+
- 脚本由 [tencent-connect/openclaw-qqbot](https://github.com/tencent-connect/openclaw-qqbot) 仓库 `main` 分支提供,通过 npm 完成升级流程(具体步骤以脚本为准)
|
|
59
59
|
|
|
60
60
|
---
|
|
61
61
|
|
package/src/slash-commands.ts
CHANGED
|
@@ -1918,26 +1918,60 @@ registerCommand({
|
|
|
1918
1918
|
handler: async (ctx) => {
|
|
1919
1919
|
// 流式消息仅支持 C2C(私聊),群/频道场景直接提示
|
|
1920
1920
|
if (ctx.type !== "c2c") {
|
|
1921
|
-
return
|
|
1921
|
+
return `⚠️ 流式消息仅支持私聊场景,请在私聊中使用 /bot-streaming 指令`;
|
|
1922
1922
|
}
|
|
1923
1923
|
|
|
1924
1924
|
const arg = ctx.args.trim().toLowerCase();
|
|
1925
|
-
|
|
1926
|
-
// 读取当前 streaming 状态
|
|
1927
1925
|
const currentStreaming = ctx.accountConfig?.streaming === true;
|
|
1928
1926
|
|
|
1927
|
+
// 指令 & 手动配置命令
|
|
1928
|
+
const slashOn = "/bot-streaming on";
|
|
1929
|
+
const slashOff = "/bot-streaming off";
|
|
1930
|
+
const cmdOn = "openclaw config set channels.qqbot.streaming true";
|
|
1931
|
+
const cmdOff = "openclaw config set channels.qqbot.streaming false";
|
|
1932
|
+
|
|
1933
|
+
// 检测 runtime 是否可用(缓存结果,避免重复调用)
|
|
1934
|
+
let runtime: ReturnType<typeof getQQBotRuntime> | null = null;
|
|
1935
|
+
try {
|
|
1936
|
+
runtime = getQQBotRuntime();
|
|
1937
|
+
} catch {}
|
|
1938
|
+
|
|
1939
|
+
// 构造指引文案:runtime 可用时用斜杠指令,否则用手动命令
|
|
1940
|
+
const guideLine = runtime
|
|
1941
|
+
? [
|
|
1942
|
+
`使用 <qqbot-cmd-input text="${slashOn}" show="${slashOn}"/> 开启`,
|
|
1943
|
+
`使用 <qqbot-cmd-input text="${slashOff}" show="${slashOff}"/> 关闭`,
|
|
1944
|
+
]
|
|
1945
|
+
: [
|
|
1946
|
+
`点击指令 <qqbot-cmd-input text="${cmdOn}" show="${cmdOn}"/> 开启`,
|
|
1947
|
+
`点击指令 <qqbot-cmd-input text="${cmdOff}" show="${cmdOff}"/> 关闭`,
|
|
1948
|
+
];
|
|
1949
|
+
|
|
1929
1950
|
// 无参数:查看当前状态
|
|
1930
1951
|
if (!arg) {
|
|
1952
|
+
const icon = runtime ? "📡" : "👀";
|
|
1931
1953
|
return [
|
|
1932
|
-
|
|
1954
|
+
`${icon}${runtime ? " " : ""}当前流式消息状态:${currentStreaming ? "✅ 已开启" : "🚫 已关闭"}`,
|
|
1933
1955
|
``,
|
|
1934
|
-
|
|
1935
|
-
`使用 <qqbot-cmd-input text="/bot-streaming off" show="/bot-streaming off"/> 关闭`,
|
|
1956
|
+
...guideLine,
|
|
1936
1957
|
].join("\n");
|
|
1937
1958
|
}
|
|
1938
1959
|
|
|
1939
1960
|
if (arg !== "on" && arg !== "off") {
|
|
1940
|
-
return
|
|
1961
|
+
return `⚠️ 参数错误,请使用 on 或 off\n\n示例:${slashOn}`;
|
|
1962
|
+
}
|
|
1963
|
+
|
|
1964
|
+
// runtime 不可用,无法修改配置,返回降级文案
|
|
1965
|
+
if (!runtime) {
|
|
1966
|
+
const fwVer = getFrameworkVersion();
|
|
1967
|
+
return [
|
|
1968
|
+
`⚠️ 当前版本不支持该指令`,
|
|
1969
|
+
``,
|
|
1970
|
+
`🦞 框架版本:${fwVer}`,
|
|
1971
|
+
`🤖 QQBot 插件版本:v${PLUGIN_VERSION}`,
|
|
1972
|
+
``,
|
|
1973
|
+
...guideLine,
|
|
1974
|
+
].join("\n");
|
|
1941
1975
|
}
|
|
1942
1976
|
|
|
1943
1977
|
const newStreaming = arg === "on";
|
|
@@ -1947,9 +1981,8 @@ registerCommand({
|
|
|
1947
1981
|
return `📡 流式消息已经是${newStreaming ? "开启" : "关闭"}状态,无需操作`;
|
|
1948
1982
|
}
|
|
1949
1983
|
|
|
1950
|
-
//
|
|
1984
|
+
// 更新配置
|
|
1951
1985
|
try {
|
|
1952
|
-
const runtime = getQQBotRuntime();
|
|
1953
1986
|
const configApi = runtime.config as {
|
|
1954
1987
|
loadConfig: () => Record<string, unknown>;
|
|
1955
1988
|
writeConfigFile: (cfg: unknown) => Promise<void>;
|
|
@@ -1959,21 +1992,19 @@ registerCommand({
|
|
|
1959
1992
|
const qqbot = ((currentCfg.channels ?? {}) as Record<string, unknown>).qqbot as Record<string, unknown> | undefined;
|
|
1960
1993
|
|
|
1961
1994
|
if (!qqbot) {
|
|
1962
|
-
return
|
|
1995
|
+
return `⚠️ 配置文件中未找到 qqbot 通道配置`;
|
|
1963
1996
|
}
|
|
1964
1997
|
|
|
1965
1998
|
const accountId = ctx.accountId;
|
|
1966
1999
|
const isNamedAccount = accountId !== "default" && (qqbot.accounts as Record<string, Record<string, unknown>> | undefined)?.[accountId];
|
|
1967
2000
|
|
|
1968
2001
|
if (isNamedAccount) {
|
|
1969
|
-
// 命名账户:更新 accounts.{accountId}.streaming
|
|
1970
2002
|
const accounts = qqbot.accounts as Record<string, Record<string, unknown>>;
|
|
1971
2003
|
const acct = accounts[accountId] ?? {};
|
|
1972
2004
|
acct.streaming = newStreaming;
|
|
1973
2005
|
accounts[accountId] = acct;
|
|
1974
2006
|
qqbot.accounts = accounts;
|
|
1975
2007
|
} else {
|
|
1976
|
-
// 默认账户:更新 qqbot.streaming
|
|
1977
2008
|
qqbot.streaming = newStreaming;
|
|
1978
2009
|
}
|
|
1979
2010
|
|
|
@@ -1981,29 +2012,12 @@ registerCommand({
|
|
|
1981
2012
|
|
|
1982
2013
|
return [
|
|
1983
2014
|
`✅ 流式消息已${newStreaming ? "开启" : "关闭"}`,
|
|
1984
|
-
``,
|
|
1985
2015
|
newStreaming
|
|
1986
|
-
?
|
|
1987
|
-
:
|
|
1988
|
-
].join("\n");
|
|
1989
|
-
} catch (err) {
|
|
1990
|
-
const fwVer = getFrameworkVersion();
|
|
1991
|
-
return [
|
|
1992
|
-
`❌ 当前版本不支持该指令`,
|
|
1993
|
-
``,
|
|
1994
|
-
`🦞框架版本:${fwVer}`,
|
|
1995
|
-
`🤖QQBot 插件版本:v${PLUGIN_VERSION}`,
|
|
1996
|
-
``,
|
|
1997
|
-
`可通过以下命令手动开启流式消息:`,
|
|
1998
|
-
``,
|
|
1999
|
-
`\`\`\`shell`,
|
|
2000
|
-
`# 1. 开启流式消息`,
|
|
2001
|
-
`openclaw config set channels.qqbot.streaming true`,
|
|
2002
|
-
``,
|
|
2003
|
-
`# 2. 重启网关使配置生效`,
|
|
2004
|
-
`openclaw gateway restart`,
|
|
2005
|
-
`\`\`\``,
|
|
2016
|
+
? `我的回复将以流式形式逐步显示(仅私聊生效)。`
|
|
2017
|
+
: `我的回复将以完整消息发送。`,
|
|
2006
2018
|
].join("\n");
|
|
2019
|
+
} catch (err: any) {
|
|
2020
|
+
return `⚠️ 配置写入失败:${err?.message ?? err}`;
|
|
2007
2021
|
}
|
|
2008
2022
|
},
|
|
2009
2023
|
});
|