@ryantest/openclaw-qqbot 0.0.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/LICENSE +22 -0
- package/README.md +483 -0
- package/README.zh.md +478 -0
- package/bin/qqbot-cli.js +243 -0
- package/clawdbot.plugin.json +16 -0
- package/dist/index.d.ts +17 -0
- package/dist/index.js +26 -0
- package/dist/src/admin-resolver.d.ts +27 -0
- package/dist/src/admin-resolver.js +122 -0
- package/dist/src/api.d.ts +156 -0
- package/dist/src/api.js +599 -0
- package/dist/src/channel.d.ts +11 -0
- package/dist/src/channel.js +354 -0
- package/dist/src/config.d.ts +25 -0
- package/dist/src/config.js +161 -0
- package/dist/src/credential-backup.d.ts +31 -0
- package/dist/src/credential-backup.js +66 -0
- package/dist/src/gateway.d.ts +18 -0
- package/dist/src/gateway.js +1265 -0
- package/dist/src/image-server.d.ts +68 -0
- package/dist/src/image-server.js +462 -0
- package/dist/src/inbound-attachments.d.ts +58 -0
- package/dist/src/inbound-attachments.js +234 -0
- package/dist/src/known-users.d.ts +100 -0
- package/dist/src/known-users.js +263 -0
- package/dist/src/message-queue.d.ts +50 -0
- package/dist/src/message-queue.js +115 -0
- package/dist/src/onboarding.d.ts +10 -0
- package/dist/src/onboarding.js +203 -0
- package/dist/src/outbound-deliver.d.ts +48 -0
- package/dist/src/outbound-deliver.js +462 -0
- package/dist/src/outbound.d.ts +203 -0
- package/dist/src/outbound.js +1102 -0
- package/dist/src/proactive.d.ts +170 -0
- package/dist/src/proactive.js +399 -0
- package/dist/src/ref-index-store.d.ts +70 -0
- package/dist/src/ref-index-store.js +273 -0
- package/dist/src/reply-dispatcher.d.ts +35 -0
- package/dist/src/reply-dispatcher.js +311 -0
- package/dist/src/runtime.d.ts +3 -0
- package/dist/src/runtime.js +10 -0
- package/dist/src/session-store.d.ts +52 -0
- package/dist/src/session-store.js +254 -0
- package/dist/src/slash-commands.d.ts +71 -0
- package/dist/src/slash-commands.js +1179 -0
- package/dist/src/startup-greeting.d.ts +30 -0
- package/dist/src/startup-greeting.js +78 -0
- package/dist/src/stt.d.ts +21 -0
- package/dist/src/stt.js +70 -0
- package/dist/src/tools/channel.d.ts +16 -0
- package/dist/src/tools/channel.js +234 -0
- package/dist/src/tools/remind.d.ts +2 -0
- package/dist/src/tools/remind.js +247 -0
- package/dist/src/types.d.ts +175 -0
- package/dist/src/types.js +1 -0
- package/dist/src/typing-keepalive.d.ts +27 -0
- package/dist/src/typing-keepalive.js +64 -0
- package/dist/src/update-checker.d.ts +34 -0
- package/dist/src/update-checker.js +166 -0
- package/dist/src/user-messages.d.ts +8 -0
- package/dist/src/user-messages.js +8 -0
- package/dist/src/utils/audio-convert.d.ts +89 -0
- package/dist/src/utils/audio-convert.js +704 -0
- package/dist/src/utils/file-utils.d.ts +55 -0
- package/dist/src/utils/file-utils.js +150 -0
- package/dist/src/utils/image-size.d.ts +51 -0
- package/dist/src/utils/image-size.js +234 -0
- package/dist/src/utils/media-tags.d.ts +14 -0
- package/dist/src/utils/media-tags.js +164 -0
- package/dist/src/utils/payload.d.ts +112 -0
- package/dist/src/utils/payload.js +186 -0
- package/dist/src/utils/platform.d.ts +137 -0
- package/dist/src/utils/platform.js +390 -0
- package/dist/src/utils/text-parsing.d.ts +32 -0
- package/dist/src/utils/text-parsing.js +80 -0
- package/dist/src/utils/upload-cache.d.ts +34 -0
- package/dist/src/utils/upload-cache.js +93 -0
- package/index.ts +31 -0
- package/moltbot.plugin.json +16 -0
- package/node_modules/@eshaz/web-worker/LICENSE +201 -0
- package/node_modules/@eshaz/web-worker/README.md +134 -0
- package/node_modules/@eshaz/web-worker/browser.js +17 -0
- package/node_modules/@eshaz/web-worker/cjs/browser.js +16 -0
- package/node_modules/@eshaz/web-worker/cjs/node.js +219 -0
- package/node_modules/@eshaz/web-worker/index.d.ts +4 -0
- package/node_modules/@eshaz/web-worker/node.js +223 -0
- package/node_modules/@eshaz/web-worker/package.json +54 -0
- package/node_modules/@wasm-audio-decoders/common/index.js +5 -0
- package/node_modules/@wasm-audio-decoders/common/package.json +36 -0
- package/node_modules/@wasm-audio-decoders/common/src/WASMAudioDecoderCommon.js +231 -0
- package/node_modules/@wasm-audio-decoders/common/src/WASMAudioDecoderWorker.js +129 -0
- package/node_modules/@wasm-audio-decoders/common/src/puff/README +67 -0
- package/node_modules/@wasm-audio-decoders/common/src/puff/build_puff.js +31 -0
- package/node_modules/@wasm-audio-decoders/common/src/puff/puff.c +863 -0
- package/node_modules/@wasm-audio-decoders/common/src/puff/puff.h +35 -0
- package/node_modules/@wasm-audio-decoders/common/src/utilities.js +3 -0
- package/node_modules/@wasm-audio-decoders/common/types.d.ts +7 -0
- package/node_modules/mpg123-decoder/README.md +265 -0
- package/node_modules/mpg123-decoder/dist/mpg123-decoder.min.js +185 -0
- package/node_modules/mpg123-decoder/dist/mpg123-decoder.min.js.map +1 -0
- package/node_modules/mpg123-decoder/index.js +8 -0
- package/node_modules/mpg123-decoder/package.json +58 -0
- package/node_modules/mpg123-decoder/src/EmscriptenWasm.js +464 -0
- package/node_modules/mpg123-decoder/src/MPEGDecoder.js +200 -0
- package/node_modules/mpg123-decoder/src/MPEGDecoderWebWorker.js +21 -0
- package/node_modules/mpg123-decoder/types.d.ts +30 -0
- package/node_modules/silk-wasm/LICENSE +21 -0
- package/node_modules/silk-wasm/README.md +85 -0
- package/node_modules/silk-wasm/lib/index.cjs +16 -0
- package/node_modules/silk-wasm/lib/index.d.ts +70 -0
- package/node_modules/silk-wasm/lib/index.mjs +16 -0
- package/node_modules/silk-wasm/lib/silk.wasm +0 -0
- package/node_modules/silk-wasm/lib/utils.d.ts +4 -0
- package/node_modules/silk-wasm/package.json +39 -0
- package/node_modules/simple-yenc/.github/FUNDING.yml +1 -0
- package/node_modules/simple-yenc/.prettierignore +1 -0
- package/node_modules/simple-yenc/LICENSE +7 -0
- package/node_modules/simple-yenc/README.md +163 -0
- package/node_modules/simple-yenc/dist/esm.js +1 -0
- package/node_modules/simple-yenc/dist/index.js +1 -0
- package/node_modules/simple-yenc/package.json +50 -0
- package/node_modules/simple-yenc/rollup.config.js +27 -0
- package/node_modules/simple-yenc/src/simple-yenc.js +302 -0
- package/node_modules/ws/LICENSE +20 -0
- package/node_modules/ws/README.md +548 -0
- package/node_modules/ws/browser.js +8 -0
- package/node_modules/ws/index.js +13 -0
- package/node_modules/ws/lib/buffer-util.js +131 -0
- package/node_modules/ws/lib/constants.js +19 -0
- package/node_modules/ws/lib/event-target.js +292 -0
- package/node_modules/ws/lib/extension.js +203 -0
- package/node_modules/ws/lib/limiter.js +55 -0
- package/node_modules/ws/lib/permessage-deflate.js +528 -0
- package/node_modules/ws/lib/receiver.js +706 -0
- package/node_modules/ws/lib/sender.js +602 -0
- package/node_modules/ws/lib/stream.js +161 -0
- package/node_modules/ws/lib/subprotocol.js +62 -0
- package/node_modules/ws/lib/validation.js +152 -0
- package/node_modules/ws/lib/websocket-server.js +554 -0
- package/node_modules/ws/lib/websocket.js +1393 -0
- package/node_modules/ws/package.json +69 -0
- package/node_modules/ws/wrapper.mjs +8 -0
- package/openclaw.plugin.json +16 -0
- package/package.json +76 -0
- package/scripts/cleanup-legacy-plugins.sh +124 -0
- package/scripts/proactive-api-server.ts +369 -0
- package/scripts/send-proactive.ts +293 -0
- package/scripts/set-markdown.sh +156 -0
- package/scripts/test-sendmedia.ts +116 -0
- package/scripts/upgrade-via-alt-pkg.sh +307 -0
- package/scripts/upgrade-via-npm.ps1 +296 -0
- package/scripts/upgrade-via-npm.sh +301 -0
- package/scripts/upgrade-via-source.sh +774 -0
- package/skills/qqbot-channel/SKILL.md +263 -0
- package/skills/qqbot-channel/references/api_references.md +521 -0
- package/skills/qqbot-media/SKILL.md +56 -0
- package/skills/qqbot-remind/SKILL.md +149 -0
- package/src/admin-resolver.ts +140 -0
- package/src/api.ts +819 -0
- package/src/bot-logs-2026-03-21T11-21-47(2).txt +46 -0
- package/src/channel.ts +381 -0
- package/src/config.ts +187 -0
- package/src/credential-backup.ts +72 -0
- package/src/gateway.log +43 -0
- package/src/gateway.ts +1404 -0
- package/src/image-server.ts +539 -0
- package/src/inbound-attachments.ts +304 -0
- package/src/known-users.ts +353 -0
- package/src/message-queue.ts +169 -0
- package/src/onboarding.ts +274 -0
- package/src/openclaw-2026-03-21.log +3729 -0
- package/src/openclaw-plugin-sdk.d.ts +522 -0
- package/src/outbound-deliver.ts +552 -0
- package/src/outbound.ts +1266 -0
- package/src/proactive.ts +530 -0
- package/src/ref-index-store.ts +357 -0
- package/src/reply-dispatcher.ts +334 -0
- package/src/runtime.ts +14 -0
- package/src/session-store.ts +303 -0
- package/src/slash-commands.ts +1305 -0
- package/src/startup-greeting.ts +98 -0
- package/src/stt.ts +86 -0
- package/src/tools/channel.ts +281 -0
- package/src/tools/remind.ts +296 -0
- package/src/types.ts +183 -0
- package/src/typing-keepalive.ts +59 -0
- package/src/update-checker.ts +179 -0
- package/src/user-messages.ts +7 -0
- package/src/utils/audio-convert.ts +803 -0
- package/src/utils/file-utils.ts +167 -0
- package/src/utils/image-size.ts +266 -0
- package/src/utils/media-tags.ts +182 -0
- package/src/utils/payload.ts +265 -0
- package/src/utils/platform.ts +435 -0
- package/src/utils/text-parsing.ts +82 -0
- package/src/utils/upload-cache.ts +128 -0
- package/tsconfig.json +16 -0
|
@@ -0,0 +1,307 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
|
|
3
|
+
# qqbot 测试脚本:自由切换不同的 QQBot npm 包
|
|
4
|
+
#
|
|
5
|
+
# 支持从任意 npm 包安装指定版本到 openclaw extensions 目录。
|
|
6
|
+
# 可用于在不同包之间切换测试,如 @sliverp/qqbot、@tencent-connect/openclaw-qqbot 等。
|
|
7
|
+
#
|
|
8
|
+
# 用法:
|
|
9
|
+
# upgrade-via-alt-pkg.sh --pkg <包名> --version <version> # 指定包+版本
|
|
10
|
+
# upgrade-via-alt-pkg.sh --pkg <包名> # 指定包,安装 latest
|
|
11
|
+
# upgrade-via-alt-pkg.sh --appid <appid> --secret <secret> # 首次安装时配置
|
|
12
|
+
# upgrade-via-alt-pkg.sh --no-restart # 只做文件替换,不重启
|
|
13
|
+
#
|
|
14
|
+
# 示例:
|
|
15
|
+
# bash scripts/upgrade-via-alt-pkg.sh --pkg @sliverp/qqbot --version 1.5.1
|
|
16
|
+
# bash scripts/upgrade-via-alt-pkg.sh --pkg @sliverp/qqbot --version 1.5.4
|
|
17
|
+
# bash scripts/upgrade-via-alt-pkg.sh --pkg @tencent-connect/openclaw-qqbot --version 1.6.4
|
|
18
|
+
# bash scripts/upgrade-via-alt-pkg.sh --pkg @sliverp/qqbot
|
|
19
|
+
# bash scripts/upgrade-via-alt-pkg.sh --pkg @sliverp/qqbot --version 1.5.4 --appid 12345 --secret abc123
|
|
20
|
+
|
|
21
|
+
set -eo pipefail
|
|
22
|
+
|
|
23
|
+
PKG_NAME=""
|
|
24
|
+
VERSION=""
|
|
25
|
+
INSTALL_SRC=""
|
|
26
|
+
APPID=""
|
|
27
|
+
SECRET=""
|
|
28
|
+
NO_RESTART=false
|
|
29
|
+
|
|
30
|
+
print_usage() {
|
|
31
|
+
echo "用法:"
|
|
32
|
+
echo " upgrade-via-alt-pkg.sh --pkg <包名> --version <版本号>"
|
|
33
|
+
echo " upgrade-via-alt-pkg.sh --pkg <包名> # 安装 latest"
|
|
34
|
+
echo ""
|
|
35
|
+
echo "选项:"
|
|
36
|
+
echo " --pkg <name> npm 包名(必填,如 @sliverp/qqbot、@tencent-connect/openclaw-qqbot)"
|
|
37
|
+
echo " --version <version> 指定版本号(如 1.5.1, 1.5.4, 1.6.4)"
|
|
38
|
+
echo " --appid <appid> QQ机器人 appid(首次安装时必填)"
|
|
39
|
+
echo " --secret <secret> QQ机器人 secret(首次安装时必填)"
|
|
40
|
+
echo " --no-restart 只做文件替换,不重启 gateway"
|
|
41
|
+
echo " -h, --help 显示帮助信息"
|
|
42
|
+
echo ""
|
|
43
|
+
echo "环境变量:"
|
|
44
|
+
echo " QQBOT_APPID QQ机器人 appid"
|
|
45
|
+
echo " QQBOT_SECRET QQ机器人 secret"
|
|
46
|
+
echo " QQBOT_TOKEN QQ机器人 token (appid:secret)"
|
|
47
|
+
echo ""
|
|
48
|
+
echo "示例:"
|
|
49
|
+
echo " # 从 @sliverp/qqbot 包安装 v1.5.1"
|
|
50
|
+
echo " bash scripts/upgrade-via-alt-pkg.sh --pkg @sliverp/qqbot --version 1.5.1"
|
|
51
|
+
echo ""
|
|
52
|
+
echo " # 从 @sliverp/qqbot 包安装 v1.5.4"
|
|
53
|
+
echo " bash scripts/upgrade-via-alt-pkg.sh --pkg @sliverp/qqbot --version 1.5.4"
|
|
54
|
+
echo ""
|
|
55
|
+
echo " # 从官方包安装 v1.6.4"
|
|
56
|
+
echo " bash scripts/upgrade-via-alt-pkg.sh --pkg @tencent-connect/openclaw-qqbot --version 1.6.4"
|
|
57
|
+
echo ""
|
|
58
|
+
echo " # 切回 @sliverp/qqbot 包的 latest"
|
|
59
|
+
echo " bash scripts/upgrade-via-alt-pkg.sh --pkg @sliverp/qqbot"
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
while [[ $# -gt 0 ]]; do
|
|
63
|
+
case "$1" in
|
|
64
|
+
--pkg|--package)
|
|
65
|
+
[ -z "$2" ] && echo "❌ --pkg 需要参数" && exit 1
|
|
66
|
+
PKG_NAME="$2"
|
|
67
|
+
shift 2
|
|
68
|
+
;;
|
|
69
|
+
--version)
|
|
70
|
+
[ -z "$2" ] && echo "❌ --version 需要参数" && exit 1
|
|
71
|
+
VERSION="$2"
|
|
72
|
+
shift 2
|
|
73
|
+
;;
|
|
74
|
+
--tag)
|
|
75
|
+
[ -z "$2" ] && echo "❌ --tag 需要参数" && exit 1
|
|
76
|
+
VERSION="$2"
|
|
77
|
+
shift 2
|
|
78
|
+
;;
|
|
79
|
+
--appid)
|
|
80
|
+
[ -z "$2" ] && echo "❌ --appid 需要参数" && exit 1
|
|
81
|
+
APPID="$2"
|
|
82
|
+
shift 2
|
|
83
|
+
;;
|
|
84
|
+
--secret)
|
|
85
|
+
[ -z "$2" ] && echo "❌ --secret 需要参数" && exit 1
|
|
86
|
+
SECRET="$2"
|
|
87
|
+
shift 2
|
|
88
|
+
;;
|
|
89
|
+
--no-restart)
|
|
90
|
+
NO_RESTART=true
|
|
91
|
+
shift 1
|
|
92
|
+
;;
|
|
93
|
+
-h|--help)
|
|
94
|
+
print_usage
|
|
95
|
+
exit 0
|
|
96
|
+
;;
|
|
97
|
+
*) echo "未知选项: $1"; print_usage; exit 1 ;;
|
|
98
|
+
esac
|
|
99
|
+
done
|
|
100
|
+
|
|
101
|
+
# --pkg 必填
|
|
102
|
+
if [ -z "$PKG_NAME" ]; then
|
|
103
|
+
echo "❌ 必须指定 --pkg 参数"
|
|
104
|
+
echo ""
|
|
105
|
+
print_usage
|
|
106
|
+
exit 1
|
|
107
|
+
fi
|
|
108
|
+
|
|
109
|
+
if [ -n "$VERSION" ]; then
|
|
110
|
+
INSTALL_SRC="${PKG_NAME}@${VERSION}"
|
|
111
|
+
else
|
|
112
|
+
INSTALL_SRC="${PKG_NAME}@latest"
|
|
113
|
+
fi
|
|
114
|
+
|
|
115
|
+
# 环境变量 fallback
|
|
116
|
+
APPID="${APPID:-$QQBOT_APPID}"
|
|
117
|
+
SECRET="${SECRET:-$QQBOT_SECRET}"
|
|
118
|
+
if [ -z "$APPID" ] && [ -z "$SECRET" ] && [ -n "$QQBOT_TOKEN" ]; then
|
|
119
|
+
APPID="${QQBOT_TOKEN%%:*}"
|
|
120
|
+
SECRET="${QQBOT_TOKEN#*:}"
|
|
121
|
+
fi
|
|
122
|
+
|
|
123
|
+
# 检测 CLI(仅用于确定 extensions 目录路径)
|
|
124
|
+
CMD=""
|
|
125
|
+
for name in openclaw clawdbot moltbot; do
|
|
126
|
+
command -v "$name" &>/dev/null && CMD="$name" && break
|
|
127
|
+
done
|
|
128
|
+
[ -z "$CMD" ] && echo "❌ 未找到 openclaw / clawdbot / moltbot" && exit 1
|
|
129
|
+
|
|
130
|
+
EXTENSIONS_DIR="$HOME/.$CMD/extensions"
|
|
131
|
+
|
|
132
|
+
echo "==========================================="
|
|
133
|
+
echo " qqbot 测试升级: $INSTALL_SRC"
|
|
134
|
+
echo "==========================================="
|
|
135
|
+
echo ""
|
|
136
|
+
|
|
137
|
+
# [1/3] 下载并安装新版本到临时目录
|
|
138
|
+
echo "[1/3] 下载新版本..."
|
|
139
|
+
TMPDIR_PACK=$(mktemp -d)
|
|
140
|
+
EXTRACT_DIR=$(mktemp -d)
|
|
141
|
+
trap "rm -rf '$TMPDIR_PACK' '$EXTRACT_DIR'" EXIT
|
|
142
|
+
|
|
143
|
+
cd "$TMPDIR_PACK"
|
|
144
|
+
# 多 registry fallback:npmjs.org → npmmirror(国内镜像)→ 默认 registry
|
|
145
|
+
PACK_OK=false
|
|
146
|
+
for _registry in "https://registry.npmjs.org/" "https://registry.npmmirror.com/" ""; do
|
|
147
|
+
if [ -n "$_registry" ]; then
|
|
148
|
+
echo " 尝试 registry: $_registry"
|
|
149
|
+
npm pack "$INSTALL_SRC" --registry "$_registry" --quiet 2>&1 && PACK_OK=true && break
|
|
150
|
+
else
|
|
151
|
+
echo " 尝试默认 registry..."
|
|
152
|
+
npm pack "$INSTALL_SRC" --quiet 2>&1 && PACK_OK=true && break
|
|
153
|
+
fi
|
|
154
|
+
done
|
|
155
|
+
$PACK_OK || { echo "❌ npm pack 失败(所有 registry 均不可用)"; exit 1; }
|
|
156
|
+
TGZ_FILE=$(ls -1 *.tgz 2>/dev/null | head -1)
|
|
157
|
+
[ -z "$TGZ_FILE" ] && echo "❌ 未找到下载的 tgz 文件" && exit 1
|
|
158
|
+
echo " 已下载: $TGZ_FILE"
|
|
159
|
+
|
|
160
|
+
tar xzf "$TGZ_FILE" -C "$EXTRACT_DIR"
|
|
161
|
+
PACKAGE_DIR="$EXTRACT_DIR/package"
|
|
162
|
+
[ ! -d "$PACKAGE_DIR" ] && echo "❌ 解压失败,未找到 package 目录" && exit 1
|
|
163
|
+
|
|
164
|
+
# 准备 staging 目录
|
|
165
|
+
STAGING_DIR="$(dirname "$EXTENSIONS_DIR")/.qqbot-upgrade-staging"
|
|
166
|
+
rm -rf "$STAGING_DIR"
|
|
167
|
+
mkdir -p "$STAGING_DIR"
|
|
168
|
+
cp -R "$PACKAGE_DIR/." "$STAGING_DIR/"
|
|
169
|
+
|
|
170
|
+
# 依赖处理
|
|
171
|
+
if [ -d "$STAGING_DIR/node_modules" ]; then
|
|
172
|
+
BUNDLED_COUNT=$(find "$STAGING_DIR/node_modules" -mindepth 1 -maxdepth 2 -type d | wc -l | tr -d ' ')
|
|
173
|
+
echo " bundled 依赖已就绪(${BUNDLED_COUNT} 个包)"
|
|
174
|
+
else
|
|
175
|
+
echo " ⚠️ 未找到 bundled node_modules,尝试安装依赖..."
|
|
176
|
+
NPM_TMP_CACHE=$(mktemp -d)
|
|
177
|
+
(cd "$STAGING_DIR" && npm install --omit=dev --omit=peer --ignore-scripts --cache="$NPM_TMP_CACHE" --quiet 2>&1) || echo " ⚠️ 依赖安装失败"
|
|
178
|
+
rm -rf "$NPM_TMP_CACHE"
|
|
179
|
+
fi
|
|
180
|
+
|
|
181
|
+
# 清理下载临时文件
|
|
182
|
+
rm -rf "$TMPDIR_PACK" "$EXTRACT_DIR"
|
|
183
|
+
cd "$HOME"
|
|
184
|
+
|
|
185
|
+
# [2/3] 原子替换插件目录
|
|
186
|
+
echo ""
|
|
187
|
+
echo "[2/3] 原子替换插件目录..."
|
|
188
|
+
TARGET_DIR="$EXTENSIONS_DIR/openclaw-qqbot"
|
|
189
|
+
OLD_DIR="$(dirname "$EXTENSIONS_DIR")/.qqbot-upgrade-old"
|
|
190
|
+
|
|
191
|
+
rm -rf "$OLD_DIR"
|
|
192
|
+
|
|
193
|
+
STAGING_IN_EXT="$EXTENSIONS_DIR/.openclaw-qqbot-new"
|
|
194
|
+
rm -rf "$STAGING_IN_EXT"
|
|
195
|
+
mv "$STAGING_DIR" "$STAGING_IN_EXT"
|
|
196
|
+
|
|
197
|
+
if [ -d "$TARGET_DIR" ]; then
|
|
198
|
+
mv "$TARGET_DIR" "$OLD_DIR" && mv "$STAGING_IN_EXT" "$TARGET_DIR"
|
|
199
|
+
else
|
|
200
|
+
mv "$STAGING_IN_EXT" "$TARGET_DIR"
|
|
201
|
+
fi
|
|
202
|
+
rm -rf "$OLD_DIR"
|
|
203
|
+
|
|
204
|
+
# 清理可能残留的旧版 staging 目录
|
|
205
|
+
rm -rf "$EXTENSIONS_DIR/openclaw-qqbot.staging"
|
|
206
|
+
rm -rf "$EXTENSIONS_DIR/.qqbot-upgrade-staging"
|
|
207
|
+
rm -rf "$EXTENSIONS_DIR/.qqbot-upgrade-old"
|
|
208
|
+
|
|
209
|
+
# 清理历史遗留的其他目录名
|
|
210
|
+
for dir_name in qqbot openclaw-qq; do
|
|
211
|
+
[ -d "$EXTENSIONS_DIR/$dir_name" ] && rm -rf "$EXTENSIONS_DIR/$dir_name"
|
|
212
|
+
done
|
|
213
|
+
echo " 已安装到: $TARGET_DIR"
|
|
214
|
+
|
|
215
|
+
# [3/3] 输出新版本号和升级报告
|
|
216
|
+
echo ""
|
|
217
|
+
echo "[3/3] 验证安装..."
|
|
218
|
+
NEW_VERSION="$(node -e "
|
|
219
|
+
try {
|
|
220
|
+
const fs = require('fs');
|
|
221
|
+
const path = require('path');
|
|
222
|
+
const p = path.join('$EXTENSIONS_DIR', 'openclaw-qqbot', 'package.json');
|
|
223
|
+
if (fs.existsSync(p)) {
|
|
224
|
+
const v = JSON.parse(fs.readFileSync(p, 'utf8')).version;
|
|
225
|
+
if (v) { process.stdout.write(v); process.exit(0); }
|
|
226
|
+
}
|
|
227
|
+
} catch {}
|
|
228
|
+
" 2>/dev/null || true)"
|
|
229
|
+
echo "QQBOT_NEW_VERSION=${NEW_VERSION:-unknown}"
|
|
230
|
+
|
|
231
|
+
if [ -n "$NEW_VERSION" ] && [ "$NEW_VERSION" != "unknown" ]; then
|
|
232
|
+
echo "QQBOT_REPORT=✅ QQBot 升级完成 ($PKG_NAME): v${NEW_VERSION}"
|
|
233
|
+
else
|
|
234
|
+
echo "QQBOT_REPORT=⚠️ QQBot 升级异常,无法确认新版本"
|
|
235
|
+
fi
|
|
236
|
+
|
|
237
|
+
echo ""
|
|
238
|
+
echo "==========================================="
|
|
239
|
+
echo " ✅ 文件安装完成"
|
|
240
|
+
echo "==========================================="
|
|
241
|
+
|
|
242
|
+
# --no-restart 模式
|
|
243
|
+
if [ "$NO_RESTART" = "true" ]; then
|
|
244
|
+
echo ""
|
|
245
|
+
echo "[跳过重启] --no-restart 已指定,脚本立即退出以便调用方触发 gateway restart"
|
|
246
|
+
exit 0
|
|
247
|
+
fi
|
|
248
|
+
|
|
249
|
+
# [4/4] 配置 appid/secret(仅在提供了参数时执行)
|
|
250
|
+
if [ -n "$APPID" ] && [ -n "$SECRET" ]; then
|
|
251
|
+
echo ""
|
|
252
|
+
echo "[配置] 写入 qqbot 通道配置..."
|
|
253
|
+
DESIRED_TOKEN="${APPID}:${SECRET}"
|
|
254
|
+
|
|
255
|
+
CURRENT_TOKEN=""
|
|
256
|
+
for _app in openclaw clawdbot moltbot; do
|
|
257
|
+
_cfg="$HOME/.$_app/$_app.json"
|
|
258
|
+
if [ -f "$_cfg" ]; then
|
|
259
|
+
CURRENT_TOKEN=$(node -e "
|
|
260
|
+
const cfg = JSON.parse(require('fs').readFileSync('$_cfg', 'utf8'));
|
|
261
|
+
const keys = ['qqbot', 'openclaw-qqbot', 'openclaw-qq'];
|
|
262
|
+
for (const key of keys) {
|
|
263
|
+
const ch = cfg.channels && cfg.channels[key];
|
|
264
|
+
if (!ch) continue;
|
|
265
|
+
if (ch.token) { process.stdout.write(ch.token); process.exit(0); }
|
|
266
|
+
if (ch.appId && ch.clientSecret) { process.stdout.write(ch.appId + ':' + ch.clientSecret); process.exit(0); }
|
|
267
|
+
}
|
|
268
|
+
" 2>/dev/null || true)
|
|
269
|
+
[ -n "$CURRENT_TOKEN" ] && break
|
|
270
|
+
fi
|
|
271
|
+
done
|
|
272
|
+
|
|
273
|
+
if [ "$CURRENT_TOKEN" = "$DESIRED_TOKEN" ]; then
|
|
274
|
+
echo " ✅ 当前配置已是目标值,跳过写入"
|
|
275
|
+
elif $CMD channels add --channel qqbot --token "$DESIRED_TOKEN" 2>&1; then
|
|
276
|
+
echo " ✅ 通道配置写入成功"
|
|
277
|
+
else
|
|
278
|
+
echo " ⚠️ $CMD channels add 失败,尝试直接编辑配置文件..."
|
|
279
|
+
CONFIG_FILE="$HOME/.$CMD/$CMD.json"
|
|
280
|
+
if [ -f "$CONFIG_FILE" ] && node -e "
|
|
281
|
+
const fs = require('fs');
|
|
282
|
+
const cfg = JSON.parse(fs.readFileSync('$CONFIG_FILE', 'utf8'));
|
|
283
|
+
if (!cfg.channels) cfg.channels = {};
|
|
284
|
+
if (!cfg.channels.qqbot) cfg.channels.qqbot = {};
|
|
285
|
+
cfg.channels.qqbot.appId = '$APPID';
|
|
286
|
+
cfg.channels.qqbot.clientSecret = '$SECRET';
|
|
287
|
+
fs.writeFileSync('$CONFIG_FILE', JSON.stringify(cfg, null, 4) + '\n');
|
|
288
|
+
" 2>&1; then
|
|
289
|
+
echo " ✅ 通道配置写入成功(直接编辑配置文件)"
|
|
290
|
+
else
|
|
291
|
+
echo " ❌ 配置写入失败,请手动配置:"
|
|
292
|
+
echo " $CMD channels add --channel qqbot --token \"${APPID}:${SECRET}\""
|
|
293
|
+
fi
|
|
294
|
+
fi
|
|
295
|
+
elif [ -n "$APPID" ] || [ -n "$SECRET" ]; then
|
|
296
|
+
echo ""
|
|
297
|
+
echo "⚠️ --appid 和 --secret 必须同时提供"
|
|
298
|
+
fi
|
|
299
|
+
|
|
300
|
+
# [5/5] 重启 gateway 使新版本生效
|
|
301
|
+
echo ""
|
|
302
|
+
echo "[重启] 重启 gateway 使新版本生效..."
|
|
303
|
+
if $CMD gateway restart 2>&1; then
|
|
304
|
+
echo " ✅ gateway 已重启"
|
|
305
|
+
else
|
|
306
|
+
echo " ⚠️ gateway 重启失败,请手动执行: $CMD gateway restart"
|
|
307
|
+
fi
|
|
@@ -0,0 +1,296 @@
|
|
|
1
|
+
# qqbot upgrade via npm package (Windows PowerShell)
|
|
2
|
+
#
|
|
3
|
+
# Windows-native equivalent of upgrade-via-npm.sh.
|
|
4
|
+
# No bash / Git Bash / WSL required.
|
|
5
|
+
#
|
|
6
|
+
# Usage:
|
|
7
|
+
# .\upgrade-via-npm.ps1 # upgrade to latest (default)
|
|
8
|
+
# .\upgrade-via-npm.ps1 -Version <version> # upgrade to specific version
|
|
9
|
+
# .\upgrade-via-npm.ps1 -SelfVersion # upgrade to local package.json version
|
|
10
|
+
# .\upgrade-via-npm.ps1 -AppId <appid> -Secret <secret> # configure on first install
|
|
11
|
+
# .\upgrade-via-npm.ps1 -NoRestart # file replacement only (for hot-upgrade)
|
|
12
|
+
|
|
13
|
+
param(
|
|
14
|
+
[string]$Version = "",
|
|
15
|
+
[switch]$SelfVersion,
|
|
16
|
+
[string]$AppId = "",
|
|
17
|
+
[string]$Secret = "",
|
|
18
|
+
[switch]$NoRestart,
|
|
19
|
+
[string]$Tag = "",
|
|
20
|
+
[switch]$Help
|
|
21
|
+
)
|
|
22
|
+
|
|
23
|
+
$ErrorActionPreference = "Stop"
|
|
24
|
+
$PKG_NAME = "@tencent-connect/openclaw-qqbot"
|
|
25
|
+
$SCRIPT_DIR = Split-Path -Parent $MyInvocation.MyCommand.Definition
|
|
26
|
+
$PROJECT_DIR = Split-Path -Parent $SCRIPT_DIR
|
|
27
|
+
|
|
28
|
+
# Read local version
|
|
29
|
+
$LOCAL_VERSION = ""
|
|
30
|
+
try {
|
|
31
|
+
$pkgPath = Join-Path $PROJECT_DIR "package.json"
|
|
32
|
+
if (Test-Path $pkgPath) {
|
|
33
|
+
$pkg = Get-Content $pkgPath -Raw | ConvertFrom-Json
|
|
34
|
+
$LOCAL_VERSION = $pkg.version
|
|
35
|
+
}
|
|
36
|
+
} catch {}
|
|
37
|
+
|
|
38
|
+
if ($Help) {
|
|
39
|
+
Write-Host "Usage:"
|
|
40
|
+
Write-Host " .\upgrade-via-npm.ps1 # upgrade to latest (default)"
|
|
41
|
+
Write-Host " .\upgrade-via-npm.ps1 -Version [version] # upgrade to specific version"
|
|
42
|
+
Write-Host " .\upgrade-via-npm.ps1 -SelfVersion # upgrade to repo version ($LOCAL_VERSION)"
|
|
43
|
+
Write-Host ""
|
|
44
|
+
Write-Host " -AppId [appid] QQ bot appid (required on first install)"
|
|
45
|
+
Write-Host " -Secret [secret] QQ bot secret (required on first install)"
|
|
46
|
+
exit 0
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
# Determine install source
|
|
50
|
+
$INSTALL_SRC = ""
|
|
51
|
+
if ($Tag) {
|
|
52
|
+
$INSTALL_SRC = "${PKG_NAME}@${Tag}"
|
|
53
|
+
} elseif ($Version) {
|
|
54
|
+
$INSTALL_SRC = "${PKG_NAME}@${Version}"
|
|
55
|
+
} elseif ($SelfVersion) {
|
|
56
|
+
if (-not $LOCAL_VERSION) {
|
|
57
|
+
Write-Host "[ERROR] Cannot read version from package.json" -ForegroundColor Red
|
|
58
|
+
exit 1
|
|
59
|
+
}
|
|
60
|
+
$INSTALL_SRC = "${PKG_NAME}@${LOCAL_VERSION}"
|
|
61
|
+
} else {
|
|
62
|
+
$INSTALL_SRC = "${PKG_NAME}@latest"
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
# Environment variable fallback
|
|
66
|
+
if (-not $AppId) { $AppId = $env:QQBOT_APPID }
|
|
67
|
+
if (-not $Secret) { $Secret = $env:QQBOT_SECRET }
|
|
68
|
+
if ((-not $AppId) -and (-not $Secret) -and $env:QQBOT_TOKEN) {
|
|
69
|
+
$parts = $env:QQBOT_TOKEN -split ":", 2
|
|
70
|
+
$AppId = $parts[0]
|
|
71
|
+
$Secret = $parts[1]
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
# Detect CLI
|
|
75
|
+
$CMD = ""
|
|
76
|
+
foreach ($name in @("openclaw", "clawdbot", "moltbot")) {
|
|
77
|
+
try {
|
|
78
|
+
$null = Get-Command $name -ErrorAction Stop
|
|
79
|
+
$CMD = $name
|
|
80
|
+
break
|
|
81
|
+
} catch {}
|
|
82
|
+
}
|
|
83
|
+
if (-not $CMD) {
|
|
84
|
+
Write-Host "[ERROR] openclaw / clawdbot / moltbot not found" -ForegroundColor Red
|
|
85
|
+
exit 1
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
$HOME_DIR = $env:USERPROFILE
|
|
89
|
+
if (-not $HOME_DIR) { $HOME_DIR = [Environment]::GetFolderPath("UserProfile") }
|
|
90
|
+
$EXTENSIONS_DIR = Join-Path (Join-Path $HOME_DIR ".$CMD") "extensions"
|
|
91
|
+
|
|
92
|
+
Write-Host "==========================================="
|
|
93
|
+
Write-Host " qqbot npm upgrade: $INSTALL_SRC"
|
|
94
|
+
Write-Host "==========================================="
|
|
95
|
+
Write-Host ""
|
|
96
|
+
|
|
97
|
+
# [1/3] Download and extract new version
|
|
98
|
+
Write-Host "[1/3] Downloading new version..."
|
|
99
|
+
$TMPDIR_PACK = Join-Path ([System.IO.Path]::GetTempPath()) "qqbot-pack-$([guid]::NewGuid().ToString('N').Substring(0,8))"
|
|
100
|
+
$EXTRACT_DIR = Join-Path ([System.IO.Path]::GetTempPath()) "qqbot-extract-$([guid]::NewGuid().ToString('N').Substring(0,8))"
|
|
101
|
+
New-Item -ItemType Directory -Path $TMPDIR_PACK -Force | Out-Null
|
|
102
|
+
New-Item -ItemType Directory -Path $EXTRACT_DIR -Force | Out-Null
|
|
103
|
+
|
|
104
|
+
try {
|
|
105
|
+
Push-Location $TMPDIR_PACK
|
|
106
|
+
|
|
107
|
+
# Multi-registry fallback
|
|
108
|
+
$PACK_OK = $false
|
|
109
|
+
$registries = @("https://registry.npmjs.org/", "https://registry.npmmirror.com/", "")
|
|
110
|
+
foreach ($registry in $registries) {
|
|
111
|
+
try {
|
|
112
|
+
if ($registry) {
|
|
113
|
+
Write-Host " Trying registry: $registry"
|
|
114
|
+
& npm pack $INSTALL_SRC --registry $registry --quiet 2>&1 | Out-Null
|
|
115
|
+
} else {
|
|
116
|
+
Write-Host " Trying default registry..."
|
|
117
|
+
& npm pack $INSTALL_SRC --quiet 2>&1 | Out-Null
|
|
118
|
+
}
|
|
119
|
+
if ($LASTEXITCODE -eq 0) {
|
|
120
|
+
$PACK_OK = $true
|
|
121
|
+
break
|
|
122
|
+
}
|
|
123
|
+
} catch {}
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
if (-not $PACK_OK) {
|
|
127
|
+
Write-Host "[ERROR] npm pack failed (all registries unavailable)" -ForegroundColor Red
|
|
128
|
+
exit 1
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
$TGZ_FILE = Get-ChildItem -Path $TMPDIR_PACK -Filter "*.tgz" | Select-Object -First 1
|
|
132
|
+
if (-not $TGZ_FILE) {
|
|
133
|
+
Write-Host "[ERROR] Downloaded tgz file not found" -ForegroundColor Red
|
|
134
|
+
exit 1
|
|
135
|
+
}
|
|
136
|
+
Write-Host " Downloaded: $($TGZ_FILE.Name)"
|
|
137
|
+
|
|
138
|
+
# Extract tgz (tar is built-in on Windows 10+)
|
|
139
|
+
& tar xzf $TGZ_FILE.FullName -C $EXTRACT_DIR
|
|
140
|
+
$PACKAGE_DIR = Join-Path $EXTRACT_DIR "package"
|
|
141
|
+
if (-not (Test-Path $PACKAGE_DIR)) {
|
|
142
|
+
Write-Host "[ERROR] Extraction failed, package directory not found" -ForegroundColor Red
|
|
143
|
+
exit 1
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
Pop-Location
|
|
147
|
+
|
|
148
|
+
# Prepare staging directory
|
|
149
|
+
$STAGING_DIR = Join-Path (Split-Path $EXTENSIONS_DIR -Parent) ".qqbot-upgrade-staging"
|
|
150
|
+
if (Test-Path $STAGING_DIR) { Remove-Item -Recurse -Force $STAGING_DIR }
|
|
151
|
+
Copy-Item -Recurse -Force $PACKAGE_DIR $STAGING_DIR
|
|
152
|
+
|
|
153
|
+
# Check bundled dependencies
|
|
154
|
+
$nmDir = Join-Path $STAGING_DIR "node_modules"
|
|
155
|
+
if (Test-Path $nmDir) {
|
|
156
|
+
$bundledCount = (Get-ChildItem -Directory $nmDir -ErrorAction SilentlyContinue | Measure-Object).Count
|
|
157
|
+
# Count scoped packages
|
|
158
|
+
Get-ChildItem -Directory $nmDir -Filter "@*" -ErrorAction SilentlyContinue | ForEach-Object {
|
|
159
|
+
$bundledCount += (Get-ChildItem -Directory $_.FullName -ErrorAction SilentlyContinue | Measure-Object).Count - 1
|
|
160
|
+
}
|
|
161
|
+
Write-Host " Bundled dependencies ready (${bundledCount} packages)"
|
|
162
|
+
} else {
|
|
163
|
+
Write-Host " [WARN] Bundled node_modules not found, installing dependencies..."
|
|
164
|
+
Push-Location $STAGING_DIR
|
|
165
|
+
try { & npm install --omit=dev --omit=peer --ignore-scripts --quiet 2>&1 | Out-Null } catch {}
|
|
166
|
+
Pop-Location
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
} finally {
|
|
170
|
+
# Clean up temp files
|
|
171
|
+
if (Test-Path $TMPDIR_PACK) { Remove-Item -Recurse -Force $TMPDIR_PACK -ErrorAction SilentlyContinue }
|
|
172
|
+
if (Test-Path $EXTRACT_DIR) { Remove-Item -Recurse -Force $EXTRACT_DIR -ErrorAction SilentlyContinue }
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
# [2/3] Replace plugin directory (in-place overwrite to avoid file-lock issues)
|
|
176
|
+
Write-Host ""
|
|
177
|
+
Write-Host "[2/3] Replacing plugin directory..."
|
|
178
|
+
$TARGET_DIR = Join-Path $EXTENSIONS_DIR "openclaw-qqbot"
|
|
179
|
+
|
|
180
|
+
if (-not (Test-Path $TARGET_DIR)) {
|
|
181
|
+
# Fresh install: just move staging into place
|
|
182
|
+
Move-Item -Path $STAGING_DIR -Destination $TARGET_DIR
|
|
183
|
+
} else {
|
|
184
|
+
# In-place overwrite using robocopy /MIR (mirrors source to dest, works even with locked files)
|
|
185
|
+
Write-Host " Overwriting in-place with robocopy /MIR ..."
|
|
186
|
+
$roboArgs = @($STAGING_DIR, $TARGET_DIR, "/MIR", "/NFL", "/NDL", "/NJH", "/NJS", "/NP", "/R:3", "/W:2")
|
|
187
|
+
$roboResult = & robocopy @roboArgs 2>&1
|
|
188
|
+
$roboExit = $LASTEXITCODE
|
|
189
|
+
# robocopy exit codes: 0-7 = success (various levels of copy), 8+ = error
|
|
190
|
+
if ($roboExit -ge 8) {
|
|
191
|
+
Write-Host " robocopy failed (exit $roboExit), falling back to Copy-Item..." -ForegroundColor Yellow
|
|
192
|
+
# Fallback: recursive Copy-Item -Force (overwrites files even if target exists)
|
|
193
|
+
try {
|
|
194
|
+
Copy-Item -Path (Join-Path $STAGING_DIR "*") -Destination $TARGET_DIR -Recurse -Force -ErrorAction Stop
|
|
195
|
+
Write-Host " Copy-Item fallback succeeded"
|
|
196
|
+
} catch {
|
|
197
|
+
Write-Host " [ERROR] Copy-Item also failed: $($_.Exception.Message)" -ForegroundColor Red
|
|
198
|
+
exit 1
|
|
199
|
+
}
|
|
200
|
+
} else {
|
|
201
|
+
Write-Host " robocopy completed (exit $roboExit)"
|
|
202
|
+
}
|
|
203
|
+
# Clean up staging
|
|
204
|
+
Remove-Item -Recurse -Force $STAGING_DIR -ErrorAction SilentlyContinue
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
# Clean up leftover directories
|
|
208
|
+
foreach ($leftover in @("openclaw-qqbot.staging", ".qqbot-upgrade-staging", ".qqbot-upgrade-old", ".openclaw-qqbot-new")) {
|
|
209
|
+
$p = Join-Path $EXTENSIONS_DIR $leftover
|
|
210
|
+
if (Test-Path $p) { Remove-Item -Recurse -Force $p -ErrorAction SilentlyContinue }
|
|
211
|
+
}
|
|
212
|
+
$oldDir = Join-Path (Split-Path $EXTENSIONS_DIR -Parent) ".qqbot-upgrade-old"
|
|
213
|
+
if (Test-Path $oldDir) { Remove-Item -Recurse -Force $oldDir -ErrorAction SilentlyContinue }
|
|
214
|
+
foreach ($legacyName in @("qqbot", "openclaw-qq")) {
|
|
215
|
+
$p = Join-Path $EXTENSIONS_DIR $legacyName
|
|
216
|
+
if (Test-Path $p) { Remove-Item -Recurse -Force $p -ErrorAction SilentlyContinue }
|
|
217
|
+
}
|
|
218
|
+
Write-Host " Installed to: $TARGET_DIR"
|
|
219
|
+
|
|
220
|
+
# [3/3] Verify installation
|
|
221
|
+
Write-Host ""
|
|
222
|
+
Write-Host "[3/3] Verifying installation..."
|
|
223
|
+
$NEW_VERSION = "unknown"
|
|
224
|
+
try {
|
|
225
|
+
$newPkgPath = Join-Path $TARGET_DIR "package.json"
|
|
226
|
+
if (Test-Path $newPkgPath) {
|
|
227
|
+
$newPkg = Get-Content $newPkgPath -Raw | ConvertFrom-Json
|
|
228
|
+
if ($newPkg.version) { $NEW_VERSION = $newPkg.version }
|
|
229
|
+
}
|
|
230
|
+
} catch {}
|
|
231
|
+
|
|
232
|
+
Write-Host "QQBOT_NEW_VERSION=$NEW_VERSION"
|
|
233
|
+
|
|
234
|
+
if ($NEW_VERSION -ne "unknown") {
|
|
235
|
+
Write-Host "QQBOT_REPORT=QQBot upgrade complete: v${NEW_VERSION}"
|
|
236
|
+
} else {
|
|
237
|
+
Write-Host "QQBOT_REPORT=[WARN] QQBot upgrade status unknown, cannot confirm new version"
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
Write-Host ""
|
|
241
|
+
Write-Host "==========================================="
|
|
242
|
+
Write-Host " File installation complete"
|
|
243
|
+
Write-Host "==========================================="
|
|
244
|
+
|
|
245
|
+
# --NoRestart mode
|
|
246
|
+
if ($NoRestart) {
|
|
247
|
+
Write-Host ""
|
|
248
|
+
Write-Host "[Skip restart] -NoRestart specified, exiting for caller to trigger gateway restart"
|
|
249
|
+
exit 0
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
# [4/4] Configure appid/secret
|
|
253
|
+
if ($AppId -and $Secret) {
|
|
254
|
+
Write-Host ""
|
|
255
|
+
Write-Host "[Config] Writing qqbot channel config..."
|
|
256
|
+
$DESIRED_TOKEN = "${AppId}:${Secret}"
|
|
257
|
+
|
|
258
|
+
try {
|
|
259
|
+
& $CMD channels add --channel qqbot --token $DESIRED_TOKEN 2>&1 | Out-Null
|
|
260
|
+
if ($LASTEXITCODE -eq 0) {
|
|
261
|
+
Write-Host " Channel config saved"
|
|
262
|
+
} else { throw "channels add failed" }
|
|
263
|
+
} catch {
|
|
264
|
+
Write-Host " [WARN] $CMD channels add failed, trying direct config edit..." -ForegroundColor Yellow
|
|
265
|
+
$CONFIG_FILE = Join-Path (Join-Path $HOME_DIR ".$CMD") "$CMD.json"
|
|
266
|
+
if (Test-Path $CONFIG_FILE) {
|
|
267
|
+
try {
|
|
268
|
+
$cfg = Get-Content $CONFIG_FILE -Raw | ConvertFrom-Json
|
|
269
|
+
if (-not $cfg.channels) { $cfg | Add-Member -NotePropertyName channels -NotePropertyValue @{} }
|
|
270
|
+
if (-not $cfg.channels.qqbot) { $cfg.channels | Add-Member -NotePropertyName qqbot -NotePropertyValue @{} }
|
|
271
|
+
$cfg.channels.qqbot | Add-Member -NotePropertyName appId -NotePropertyValue $AppId -Force
|
|
272
|
+
$cfg.channels.qqbot | Add-Member -NotePropertyName clientSecret -NotePropertyValue $Secret -Force
|
|
273
|
+
$cfg | ConvertTo-Json -Depth 10 | Set-Content $CONFIG_FILE -Encoding UTF8
|
|
274
|
+
Write-Host " Channel config saved (direct file edit)"
|
|
275
|
+
} catch {
|
|
276
|
+
Write-Host " [ERROR] Config write failed, please configure manually:" -ForegroundColor Red
|
|
277
|
+
Write-Host " $CMD channels add --channel qqbot --token `"${AppId}:${Secret}`""
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
} elseif ($AppId -or $Secret) {
|
|
282
|
+
Write-Host ""
|
|
283
|
+
Write-Host "[WARN] -AppId and -Secret must be provided together" -ForegroundColor Yellow
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
# [5/5] Restart gateway
|
|
287
|
+
Write-Host ""
|
|
288
|
+
Write-Host "[Restart] Restarting gateway..."
|
|
289
|
+
try {
|
|
290
|
+
& $CMD gateway restart 2>&1 | Out-Null
|
|
291
|
+
if ($LASTEXITCODE -eq 0) {
|
|
292
|
+
Write-Host " Gateway restarted"
|
|
293
|
+
} else { throw "restart failed" }
|
|
294
|
+
} catch {
|
|
295
|
+
Write-Host " [WARN] Gateway restart failed, please run manually: $CMD gateway restart" -ForegroundColor Yellow
|
|
296
|
+
}
|