@tencent-connect/openclaw-qqbot 1.6.4-alpha.16 → 1.6.4-alpha.18
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/src/inbound-attachments.js +2 -2
- package/dist/src/outbound.js +3 -3
- package/dist/src/slash-commands.js +20 -13
- package/dist/src/update-checker.d.ts +5 -0
- package/dist/src/update-checker.js +13 -5
- package/package.json +1 -1
- package/scripts/cleanup-legacy-plugins.sh +3 -6
- package/scripts/upgrade-via-source.sh +50 -0
- package/src/inbound-attachments.ts +2 -2
- package/src/outbound.ts +3 -3
- package/src/slash-commands.ts +21 -13
- package/src/update-checker.ts +21 -5
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
import { downloadFile } from "./image-server.js";
|
|
8
8
|
import { convertSilkToWav, isVoiceAttachment, formatDuration } from "./utils/audio-convert.js";
|
|
9
9
|
import { transcribeAudio, resolveSTTConfig } from "./stt.js";
|
|
10
|
-
import {
|
|
10
|
+
import { getQQBotMediaDir } from "./utils/platform.js";
|
|
11
11
|
// ============ 空结果常量 ============
|
|
12
12
|
const EMPTY_RESULT = {
|
|
13
13
|
attachmentInfo: "",
|
|
@@ -33,7 +33,7 @@ export async function processAttachments(attachments, ctx) {
|
|
|
33
33
|
if (!attachments?.length)
|
|
34
34
|
return EMPTY_RESULT;
|
|
35
35
|
const { accountId, cfg, log } = ctx;
|
|
36
|
-
const downloadDir =
|
|
36
|
+
const downloadDir = getQQBotMediaDir("downloads");
|
|
37
37
|
const prefix = `[qqbot:${accountId}]`;
|
|
38
38
|
// 结果收集
|
|
39
39
|
const imageUrls = [];
|
package/dist/src/outbound.js
CHANGED
|
@@ -7,7 +7,7 @@ import { getAccessToken, sendC2CMessage, sendChannelMessage, sendGroupMessage, s
|
|
|
7
7
|
import { isAudioFile, audioFileToSilkBase64, waitForFile, shouldTranscodeVoice } from "./utils/audio-convert.js";
|
|
8
8
|
import { normalizeMediaTags } from "./utils/media-tags.js";
|
|
9
9
|
import { checkFileSize, readFileAsync, fileExistsAsync, formatFileSize } from "./utils/file-utils.js";
|
|
10
|
-
import { isLocalPath as isLocalFilePath, normalizePath, sanitizeFileName,
|
|
10
|
+
import { isLocalPath as isLocalFilePath, normalizePath, sanitizeFileName, getQQBotMediaDir } from "./utils/platform.js";
|
|
11
11
|
import { downloadFile } from "./image-server.js";
|
|
12
12
|
// ============ 消息回复限流器 ============
|
|
13
13
|
// 同一 message_id 1小时内最多回复 4 次,超过 1 小时无法被动回复(需改为主动消息)
|
|
@@ -269,7 +269,7 @@ export async function sendPhoto(ctx, imagePath) {
|
|
|
269
269
|
*/
|
|
270
270
|
async function downloadAndRetrySendPhoto(ctx, httpUrl, prefix) {
|
|
271
271
|
try {
|
|
272
|
-
const downloadDir =
|
|
272
|
+
const downloadDir = getQQBotMediaDir("downloads", "url-fallback");
|
|
273
273
|
const localFile = await downloadFile(httpUrl, downloadDir);
|
|
274
274
|
if (!localFile) {
|
|
275
275
|
console.error(`${prefix} sendPhoto fallback: download also failed for ${httpUrl.slice(0, 80)}`);
|
|
@@ -566,7 +566,7 @@ async function sendDocumentFromLocal(ctx, mediaPath, prefix) {
|
|
|
566
566
|
*/
|
|
567
567
|
async function downloadToFallbackDir(httpUrl, prefix, caller) {
|
|
568
568
|
try {
|
|
569
|
-
const downloadDir =
|
|
569
|
+
const downloadDir = getQQBotMediaDir("downloads", "url-fallback");
|
|
570
570
|
const localFile = await downloadFile(httpUrl, downloadDir);
|
|
571
571
|
if (!localFile) {
|
|
572
572
|
console.error(`${prefix} ${caller} fallback: download also failed for ${httpUrl.slice(0, 80)}`);
|
|
@@ -606,13 +606,14 @@ registerCommand({
|
|
|
606
606
|
].join("\n");
|
|
607
607
|
}
|
|
608
608
|
if (!info.hasUpdate) {
|
|
609
|
-
|
|
609
|
+
const lines = [
|
|
610
610
|
`✅ 当前已是最新版本 v${PLUGIN_VERSION}`,
|
|
611
611
|
``,
|
|
612
612
|
`项目地址:[GitHub](${GITHUB_URL})`,
|
|
613
|
-
]
|
|
613
|
+
];
|
|
614
|
+
return lines.join("\n");
|
|
614
615
|
}
|
|
615
|
-
// 有新版本:展示信息 +
|
|
616
|
+
// 有新版本:展示信息 + 确认按钮(同通道:alpha 只展示 alpha,正式版只展示正式版)
|
|
616
617
|
return [
|
|
617
618
|
`🆕 发现新版本`,
|
|
618
619
|
``,
|
|
@@ -656,6 +657,8 @@ registerCommand({
|
|
|
656
657
|
}
|
|
657
658
|
}
|
|
658
659
|
const targetVersion = versionArg || info.latest || undefined;
|
|
660
|
+
// --force 时如果 targetVersion 等于当前版本,属于强制重装
|
|
661
|
+
const isReinstall = isForce && targetVersion === PLUGIN_VERSION;
|
|
659
662
|
// ── 环境兼容性检查 ──
|
|
660
663
|
const compat = checkUpgradeCompatibility();
|
|
661
664
|
if (!compat.ok) {
|
|
@@ -704,16 +707,20 @@ registerCommand({
|
|
|
704
707
|
].join("\n");
|
|
705
708
|
}
|
|
706
709
|
saveUpgradeGreetingTarget(ctx.accountId, ctx.appId, ctx.senderId);
|
|
707
|
-
const resultLines =
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
710
|
+
const resultLines = isReinstall
|
|
711
|
+
? [
|
|
712
|
+
`🔄 正在重新安装 v${PLUGIN_VERSION}...`,
|
|
713
|
+
``,
|
|
714
|
+
`预计 30~60 秒完成,届时会自动通知您`,
|
|
715
|
+
]
|
|
716
|
+
: [
|
|
717
|
+
`🔄 正在升级...`,
|
|
718
|
+
``,
|
|
719
|
+
`当前版本:v${PLUGIN_VERSION}`,
|
|
720
|
+
...(targetVersion ? [`目标版本:v${targetVersion}`] : []),
|
|
721
|
+
``,
|
|
722
|
+
`预计 30~60 秒完成,届时会自动通知您`,
|
|
723
|
+
];
|
|
717
724
|
return resultLines.join("\n");
|
|
718
725
|
},
|
|
719
726
|
});
|
|
@@ -9,7 +9,12 @@
|
|
|
9
9
|
*/
|
|
10
10
|
export interface UpdateInfo {
|
|
11
11
|
current: string;
|
|
12
|
+
/** 最佳升级目标(prerelease 用户优先 alpha,稳定版用户取 latest) */
|
|
12
13
|
latest: string | null;
|
|
14
|
+
/** 稳定版 dist-tag */
|
|
15
|
+
stable: string | null;
|
|
16
|
+
/** alpha dist-tag */
|
|
17
|
+
alpha: string | null;
|
|
13
18
|
hasUpdate: boolean;
|
|
14
19
|
checkedAt: number;
|
|
15
20
|
error?: string;
|
|
@@ -64,13 +64,21 @@ async function fetchDistTags() {
|
|
|
64
64
|
}
|
|
65
65
|
function buildUpdateInfo(tags) {
|
|
66
66
|
const currentIsPrerelease = CURRENT_VERSION.includes("-");
|
|
67
|
-
const
|
|
68
|
-
|
|
69
|
-
|
|
67
|
+
const stableTag = tags.latest || null;
|
|
68
|
+
const alphaTag = tags.alpha || null;
|
|
69
|
+
// 严格隔离:alpha 只跟 alpha 比,正式版只跟正式版比,不交叉
|
|
70
|
+
const compareTarget = currentIsPrerelease ? alphaTag : stableTag;
|
|
70
71
|
const hasUpdate = typeof compareTarget === "string"
|
|
71
72
|
&& compareTarget !== CURRENT_VERSION
|
|
72
73
|
&& compareVersions(compareTarget, CURRENT_VERSION) > 0;
|
|
73
|
-
return {
|
|
74
|
+
return {
|
|
75
|
+
current: CURRENT_VERSION,
|
|
76
|
+
latest: compareTarget,
|
|
77
|
+
stable: stableTag,
|
|
78
|
+
alpha: alphaTag,
|
|
79
|
+
hasUpdate,
|
|
80
|
+
checkedAt: Date.now(),
|
|
81
|
+
};
|
|
74
82
|
}
|
|
75
83
|
/** gateway 启动时调用,保存 log 引用 */
|
|
76
84
|
export function triggerUpdateCheck(log) {
|
|
@@ -91,7 +99,7 @@ export async function getUpdateInfo() {
|
|
|
91
99
|
}
|
|
92
100
|
catch (err) {
|
|
93
101
|
_log?.debug?.(`[qqbot:update-checker] check failed: ${err.message}`);
|
|
94
|
-
return { current: CURRENT_VERSION, latest: null, hasUpdate: false, checkedAt: Date.now(), error: err.message };
|
|
102
|
+
return { current: CURRENT_VERSION, latest: null, stable: null, alpha: null, hasUpdate: false, checkedAt: Date.now(), error: err.message };
|
|
95
103
|
}
|
|
96
104
|
}
|
|
97
105
|
/**
|
package/package.json
CHANGED
|
@@ -50,12 +50,9 @@ cleanup_installation() {
|
|
|
50
50
|
const ids = ['qqbot', 'openclaw-qq', '@sliverp/qqbot', '@tencent-connect/qqbot', '@tencent-connect/openclaw-qq', '@tencent-connect/openclaw-qqbot', 'openclaw-qqbot'];
|
|
51
51
|
|
|
52
52
|
for (const id of ids) {
|
|
53
|
-
//
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
console.log(' - 已删除 channels.' + id);
|
|
57
|
-
}
|
|
58
|
-
|
|
53
|
+
// 注意: 不删除 channels.<id>,因为里面保存了用户的 appid/secret 凭证
|
|
54
|
+
// 凭证与插件版本无关,清理插件时不应清除凭证
|
|
55
|
+
|
|
59
56
|
// 删除 plugins.entries.<id>
|
|
60
57
|
if (config.plugins && config.plugins.entries && config.plugins.entries[id]) {
|
|
61
58
|
delete config.plugins.entries[id];
|
|
@@ -186,6 +186,34 @@ INSTALL_LOG="/tmp/openclaw-install-$(date +%s).log"
|
|
|
186
186
|
echo "安装日志文件: $INSTALL_LOG"
|
|
187
187
|
echo "详细信息将记录到日志文件中..."
|
|
188
188
|
|
|
189
|
+
# ── 临时移除 channels.qqbot 配置 ──
|
|
190
|
+
# openclaw CLI 任何子命令(包括 gateway stop、plugins install)启动时都会校验 openclaw.json,
|
|
191
|
+
# 如果 channels.qqbot 存在但插件还未安装,CLI 不认识该 channel id,
|
|
192
|
+
# 导致 "Config invalid: unknown channel id: qqbot" 而命令失败(鸡生蛋问题)。
|
|
193
|
+
# 解决方案:在所有 openclaw 命令之前把 channels.qqbot 暂存,完成后恢复。
|
|
194
|
+
_QQBOT_CHANNEL_STASH=""
|
|
195
|
+
for _app in openclaw clawdbot moltbot; do
|
|
196
|
+
_cfg="$HOME/.$_app/$_app.json"
|
|
197
|
+
if [ -f "$_cfg" ]; then
|
|
198
|
+
_QQBOT_CHANNEL_STASH=$(node -e "
|
|
199
|
+
const fs = require('fs');
|
|
200
|
+
const cfg = JSON.parse(fs.readFileSync('$_cfg', 'utf8'));
|
|
201
|
+
if (cfg.channels && cfg.channels.qqbot) {
|
|
202
|
+
const stashed = JSON.stringify(cfg.channels.qqbot);
|
|
203
|
+
delete cfg.channels.qqbot;
|
|
204
|
+
fs.writeFileSync('$_cfg', JSON.stringify(cfg, null, 4) + '\n');
|
|
205
|
+
process.stdout.write(stashed);
|
|
206
|
+
}
|
|
207
|
+
" 2>/dev/null || true)
|
|
208
|
+
if [ -n "$_QQBOT_CHANNEL_STASH" ]; then
|
|
209
|
+
_STASH_APP="$_app"
|
|
210
|
+
_STASH_CFG="$_cfg"
|
|
211
|
+
echo " 已暂存 channels.qqbot 配置(避免 CLI 校验失败)"
|
|
212
|
+
fi
|
|
213
|
+
break
|
|
214
|
+
fi
|
|
215
|
+
done
|
|
216
|
+
|
|
189
217
|
# 安装前先 stop gateway,防止 chokidar 在 plugins install 写入配置的中间状态
|
|
190
218
|
# 触发 restart,导致 "unknown channel id: qqbot" 等错误
|
|
191
219
|
_gw_was_running=0
|
|
@@ -251,6 +279,16 @@ if ! openclaw plugins install . 2>&1 | tee "$INSTALL_LOG"; then
|
|
|
251
279
|
* )
|
|
252
280
|
echo "安装失败,脚本退出。"
|
|
253
281
|
echo "请先解决安装问题后再运行此脚本。"
|
|
282
|
+
# 恢复 channels.qqbot 后再退出
|
|
283
|
+
if [ -n "$_QQBOT_CHANNEL_STASH" ] && [ -n "$_STASH_CFG" ] && [ -f "$_STASH_CFG" ]; then
|
|
284
|
+
node -e "
|
|
285
|
+
const fs = require('fs');
|
|
286
|
+
const cfg = JSON.parse(fs.readFileSync('$_STASH_CFG', 'utf8'));
|
|
287
|
+
if (!cfg.channels) cfg.channels = {};
|
|
288
|
+
cfg.channels.qqbot = $_QQBOT_CHANNEL_STASH;
|
|
289
|
+
fs.writeFileSync('$_STASH_CFG', JSON.stringify(cfg, null, 4) + '\n');
|
|
290
|
+
" 2>/dev/null || true
|
|
291
|
+
fi
|
|
254
292
|
exit 1
|
|
255
293
|
;;
|
|
256
294
|
esac
|
|
@@ -424,6 +462,18 @@ else
|
|
|
424
462
|
' 2>/dev/null || echo "unknown")
|
|
425
463
|
fi
|
|
426
464
|
|
|
465
|
+
# ── 恢复 channels.qqbot 配置 ──
|
|
466
|
+
# 安装完成(无论成功或失败),把之前暂存的 channels.qqbot 写回 openclaw.json
|
|
467
|
+
if [ -n "$_QQBOT_CHANNEL_STASH" ] && [ -n "$_STASH_CFG" ] && [ -f "$_STASH_CFG" ]; then
|
|
468
|
+
node -e "
|
|
469
|
+
const fs = require('fs');
|
|
470
|
+
const cfg = JSON.parse(fs.readFileSync('$_STASH_CFG', 'utf8'));
|
|
471
|
+
if (!cfg.channels) cfg.channels = {};
|
|
472
|
+
cfg.channels.qqbot = $_QQBOT_CHANNEL_STASH;
|
|
473
|
+
fs.writeFileSync('$_STASH_CFG', JSON.stringify(cfg, null, 4) + '\n');
|
|
474
|
+
" 2>/dev/null && echo " 已恢复 channels.qqbot 配置" || echo " ⚠️ 恢复 channels.qqbot 配置失败"
|
|
475
|
+
fi
|
|
476
|
+
|
|
427
477
|
# 4. 配置机器人通道(仅在需要变更时写入配置,避免无意义覆盖)
|
|
428
478
|
echo ""
|
|
429
479
|
echo "[4/6] 配置机器人通道..."
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
import { downloadFile } from "./image-server.js";
|
|
9
9
|
import { convertSilkToWav, isVoiceAttachment, formatDuration } from "./utils/audio-convert.js";
|
|
10
10
|
import { transcribeAudio, resolveSTTConfig } from "./stt.js";
|
|
11
|
-
import {
|
|
11
|
+
import { getQQBotMediaDir } from "./utils/platform.js";
|
|
12
12
|
|
|
13
13
|
// ============ 类型定义 ============
|
|
14
14
|
|
|
@@ -85,7 +85,7 @@ export async function processAttachments(
|
|
|
85
85
|
if (!attachments?.length) return EMPTY_RESULT;
|
|
86
86
|
|
|
87
87
|
const { accountId, cfg, log } = ctx;
|
|
88
|
-
const downloadDir =
|
|
88
|
+
const downloadDir = getQQBotMediaDir("downloads");
|
|
89
89
|
const prefix = `[qqbot:${accountId}]`;
|
|
90
90
|
|
|
91
91
|
// 结果收集
|
package/src/outbound.ts
CHANGED
|
@@ -24,7 +24,7 @@ import {
|
|
|
24
24
|
import { isAudioFile, audioFileToSilkBase64, waitForFile, shouldTranscodeVoice } from "./utils/audio-convert.js";
|
|
25
25
|
import { normalizeMediaTags } from "./utils/media-tags.js";
|
|
26
26
|
import { checkFileSize, readFileAsync, fileExistsAsync, isLargeFile, formatFileSize } from "./utils/file-utils.js";
|
|
27
|
-
import { isLocalPath as isLocalFilePath, normalizePath, sanitizeFileName, getQQBotDataDir } from "./utils/platform.js";
|
|
27
|
+
import { isLocalPath as isLocalFilePath, normalizePath, sanitizeFileName, getQQBotDataDir, getQQBotMediaDir } from "./utils/platform.js";
|
|
28
28
|
import { downloadFile } from "./image-server.js";
|
|
29
29
|
|
|
30
30
|
// ============ 消息回复限流器 ============
|
|
@@ -378,7 +378,7 @@ async function downloadAndRetrySendPhoto(
|
|
|
378
378
|
prefix: string,
|
|
379
379
|
): Promise<OutboundResult | null> {
|
|
380
380
|
try {
|
|
381
|
-
const downloadDir =
|
|
381
|
+
const downloadDir = getQQBotMediaDir("downloads", "url-fallback");
|
|
382
382
|
const localFile = await downloadFile(httpUrl, downloadDir);
|
|
383
383
|
if (!localFile) {
|
|
384
384
|
console.error(`${prefix} sendPhoto fallback: download also failed for ${httpUrl.slice(0, 80)}`);
|
|
@@ -702,7 +702,7 @@ async function sendDocumentFromLocal(ctx: MediaTargetContext, mediaPath: string,
|
|
|
702
702
|
*/
|
|
703
703
|
async function downloadToFallbackDir(httpUrl: string, prefix: string, caller: string): Promise<string | null> {
|
|
704
704
|
try {
|
|
705
|
-
const downloadDir =
|
|
705
|
+
const downloadDir = getQQBotMediaDir("downloads", "url-fallback");
|
|
706
706
|
const localFile = await downloadFile(httpUrl, downloadDir);
|
|
707
707
|
if (!localFile) {
|
|
708
708
|
console.error(`${prefix} ${caller} fallback: download also failed for ${httpUrl.slice(0, 80)}`);
|
package/src/slash-commands.ts
CHANGED
|
@@ -710,14 +710,15 @@ registerCommand({
|
|
|
710
710
|
].join("\n");
|
|
711
711
|
}
|
|
712
712
|
if (!info.hasUpdate) {
|
|
713
|
-
|
|
713
|
+
const lines = [
|
|
714
714
|
`✅ 当前已是最新版本 v${PLUGIN_VERSION}`,
|
|
715
715
|
``,
|
|
716
716
|
`项目地址:[GitHub](${GITHUB_URL})`,
|
|
717
|
-
]
|
|
717
|
+
];
|
|
718
|
+
return lines.join("\n");
|
|
718
719
|
}
|
|
719
720
|
|
|
720
|
-
// 有新版本:展示信息 +
|
|
721
|
+
// 有新版本:展示信息 + 确认按钮(同通道:alpha 只展示 alpha,正式版只展示正式版)
|
|
721
722
|
return [
|
|
722
723
|
`🆕 发现新版本`,
|
|
723
724
|
``,
|
|
@@ -766,6 +767,9 @@ registerCommand({
|
|
|
766
767
|
|
|
767
768
|
const targetVersion = versionArg || info.latest || undefined;
|
|
768
769
|
|
|
770
|
+
// --force 时如果 targetVersion 等于当前版本,属于强制重装
|
|
771
|
+
const isReinstall = isForce && targetVersion === PLUGIN_VERSION;
|
|
772
|
+
|
|
769
773
|
// ── 环境兼容性检查 ──
|
|
770
774
|
const compat = checkUpgradeCompatibility();
|
|
771
775
|
if (!compat.ok) {
|
|
@@ -819,16 +823,20 @@ registerCommand({
|
|
|
819
823
|
|
|
820
824
|
saveUpgradeGreetingTarget(ctx.accountId, ctx.appId, ctx.senderId);
|
|
821
825
|
|
|
822
|
-
const resultLines =
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
826
|
+
const resultLines = isReinstall
|
|
827
|
+
? [
|
|
828
|
+
`🔄 正在重新安装 v${PLUGIN_VERSION}...`,
|
|
829
|
+
``,
|
|
830
|
+
`预计 30~60 秒完成,届时会自动通知您`,
|
|
831
|
+
]
|
|
832
|
+
: [
|
|
833
|
+
`🔄 正在升级...`,
|
|
834
|
+
``,
|
|
835
|
+
`当前版本:v${PLUGIN_VERSION}`,
|
|
836
|
+
...(targetVersion ? [`目标版本:v${targetVersion}`] : []),
|
|
837
|
+
``,
|
|
838
|
+
`预计 30~60 秒完成,届时会自动通知您`,
|
|
839
|
+
];
|
|
832
840
|
return resultLines.join("\n");
|
|
833
841
|
},
|
|
834
842
|
});
|
package/src/update-checker.ts
CHANGED
|
@@ -31,7 +31,12 @@ try {
|
|
|
31
31
|
|
|
32
32
|
export interface UpdateInfo {
|
|
33
33
|
current: string;
|
|
34
|
+
/** 最佳升级目标(prerelease 用户优先 alpha,稳定版用户取 latest) */
|
|
34
35
|
latest: string | null;
|
|
36
|
+
/** 稳定版 dist-tag */
|
|
37
|
+
stable: string | null;
|
|
38
|
+
/** alpha dist-tag */
|
|
39
|
+
alpha: string | null;
|
|
35
40
|
hasUpdate: boolean;
|
|
36
41
|
checkedAt: number;
|
|
37
42
|
error?: string;
|
|
@@ -73,13 +78,24 @@ async function fetchDistTags(): Promise<Record<string, string>> {
|
|
|
73
78
|
|
|
74
79
|
function buildUpdateInfo(tags: Record<string, string>): UpdateInfo {
|
|
75
80
|
const currentIsPrerelease = CURRENT_VERSION.includes("-");
|
|
76
|
-
const
|
|
77
|
-
|
|
78
|
-
|
|
81
|
+
const stableTag = tags.latest || null;
|
|
82
|
+
const alphaTag = tags.alpha || null;
|
|
83
|
+
|
|
84
|
+
// 严格隔离:alpha 只跟 alpha 比,正式版只跟正式版比,不交叉
|
|
85
|
+
const compareTarget = currentIsPrerelease ? alphaTag : stableTag;
|
|
86
|
+
|
|
79
87
|
const hasUpdate = typeof compareTarget === "string"
|
|
80
88
|
&& compareTarget !== CURRENT_VERSION
|
|
81
89
|
&& compareVersions(compareTarget, CURRENT_VERSION) > 0;
|
|
82
|
-
|
|
90
|
+
|
|
91
|
+
return {
|
|
92
|
+
current: CURRENT_VERSION,
|
|
93
|
+
latest: compareTarget,
|
|
94
|
+
stable: stableTag,
|
|
95
|
+
alpha: alphaTag,
|
|
96
|
+
hasUpdate,
|
|
97
|
+
checkedAt: Date.now(),
|
|
98
|
+
};
|
|
83
99
|
}
|
|
84
100
|
|
|
85
101
|
/** gateway 启动时调用,保存 log 引用 */
|
|
@@ -104,7 +120,7 @@ export async function getUpdateInfo(): Promise<UpdateInfo> {
|
|
|
104
120
|
return buildUpdateInfo(tags);
|
|
105
121
|
} catch (err: any) {
|
|
106
122
|
_log?.debug?.(`[qqbot:update-checker] check failed: ${err.message}`);
|
|
107
|
-
return { current: CURRENT_VERSION, latest: null, hasUpdate: false, checkedAt: Date.now(), error: err.message };
|
|
123
|
+
return { current: CURRENT_VERSION, latest: null, stable: null, alpha: null, hasUpdate: false, checkedAt: Date.now(), error: err.message };
|
|
108
124
|
}
|
|
109
125
|
}
|
|
110
126
|
|