Files
qqbot/bin/qqbot-cli.js
2026-02-05 17:05:33 +08:00

228 lines
6.3 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/usr/bin/env node
/**
* QQBot CLI - 用于升级和管理 QQBot 插件
*
* 用法:
* npx @sliverp/qqbot upgrade # 升级插件
* npx @sliverp/qqbot install # 安装插件
*/
import { execSync } from 'child_process';
import { existsSync, readFileSync, writeFileSync, rmSync } from 'fs';
import { homedir } from 'os';
import { join, dirname } from 'path';
import { fileURLToPath } from 'url';
const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);
// 获取包的根目录
const PKG_ROOT = join(__dirname, '..');
const args = process.argv.slice(2);
const command = args[0];
// 检测使用的是 clawdbot 还是 openclaw
function detectInstallation() {
const home = homedir();
if (existsSync(join(home, '.openclaw'))) {
return 'openclaw';
}
if (existsSync(join(home, '.clawdbot'))) {
return 'clawdbot';
}
return null;
}
// 清理旧版本插件,返回旧的 qqbot 配置
function cleanupInstallation(appName) {
const home = homedir();
const appDir = join(home, `.${appName}`);
const configFile = join(appDir, `${appName}.json`);
const extensionDir = join(appDir, 'extensions', 'qqbot');
let oldQqbotConfig = null;
console.log(`\n>>> 处理 ${appName} 安装...`);
// 1. 先读取旧的 qqbot 配置
if (existsSync(configFile)) {
try {
const config = JSON.parse(readFileSync(configFile, 'utf8'));
if (config.channels?.qqbot) {
oldQqbotConfig = { ...config.channels.qqbot };
console.log('已保存旧的 qqbot 配置');
}
} catch (err) {
console.error('读取配置文件失败:', err.message);
}
}
// 2. 删除旧的扩展目录
if (existsSync(extensionDir)) {
console.log(`删除旧版本插件: ${extensionDir}`);
rmSync(extensionDir, { recursive: true, force: true });
} else {
console.log('未找到旧版本插件目录,跳过删除');
}
// 3. 清理配置文件中的 qqbot 相关字段
if (existsSync(configFile)) {
console.log('清理配置文件中的 qqbot 字段...');
try {
const config = JSON.parse(readFileSync(configFile, 'utf8'));
// 删除 channels.qqbot
if (config.channels?.qqbot) {
delete config.channels.qqbot;
console.log(' - 已删除 channels.qqbot');
}
// 删除 plugins.entries.qqbot
if (config.plugins?.entries?.qqbot) {
delete config.plugins.entries.qqbot;
console.log(' - 已删除 plugins.entries.qqbot');
}
// 删除 plugins.installs.qqbot
if (config.plugins?.installs?.qqbot) {
delete config.plugins.installs.qqbot;
console.log(' - 已删除 plugins.installs.qqbot');
}
writeFileSync(configFile, JSON.stringify(config, null, 2));
console.log('配置文件已更新');
} catch (err) {
console.error('清理配置文件失败:', err.message);
}
} else {
console.log(`未找到配置文件: ${configFile}`);
}
return oldQqbotConfig;
}
// 执行命令并继承 stdio
function runCommand(cmd, args = []) {
try {
execSync([cmd, ...args].join(' '), { stdio: 'inherit' });
return true;
} catch (err) {
return false;
}
}
// 升级命令
function upgrade() {
console.log('=== QQBot 插件升级脚本 ===');
let foundInstallation = null;
let savedConfig = null;
const home = homedir();
// 检查 openclaw
if (existsSync(join(home, '.openclaw'))) {
savedConfig = cleanupInstallation('openclaw');
foundInstallation = 'openclaw';
}
// 检查 clawdbot
if (existsSync(join(home, '.clawdbot'))) {
const clawdbotConfig = cleanupInstallation('clawdbot');
if (!savedConfig) savedConfig = clawdbotConfig;
foundInstallation = 'clawdbot';
}
if (!foundInstallation) {
console.log('\n未找到 clawdbot 或 openclaw 安装目录');
console.log('请确认已安装 clawdbot 或 openclaw');
process.exit(1);
}
console.log('\n=== 清理完成 ===');
// 自动安装插件
console.log('\n[1/2] 安装新版本插件...');
runCommand(foundInstallation, ['plugins', 'install', '@sliverp/qqbot']);
// 自动配置通道(使用保存的 appId 和 clientSecret
console.log('\n[2/2] 配置机器人通道...');
if (savedConfig?.appId && savedConfig?.clientSecret) {
const token = `${savedConfig.appId}:${savedConfig.clientSecret}`;
console.log(`使用已保存的配置: appId=${savedConfig.appId}`);
runCommand(foundInstallation, ['channels', 'add', '--channel', 'qqbot', '--token', `"${token}"`]);
// 恢复其他配置项(如 markdownSupport
if (savedConfig.markdownSupport !== undefined) {
runCommand(foundInstallation, ['config', 'set', 'channels.qqbot.markdownSupport', String(savedConfig.markdownSupport)]);
}
} else {
console.log('未找到已保存的 qqbot 配置,请手动配置:');
console.log(` ${foundInstallation} channels add --channel qqbot --token "AppID:AppSecret"`);
return;
}
console.log('\n=== 升级完成 ===');
console.log(`\n可以运行以下命令前台运行启动机器人:`);
console.log(` ${foundInstallation} gateway stop && ${foundInstallation} gateway --port 18789 --verbose`);
}
// 安装命令
function install() {
console.log('=== QQBot 插件安装 ===');
const cmd = detectInstallation();
if (!cmd) {
console.log('未找到 clawdbot 或 openclaw 安装');
console.log('请先安装 openclaw 或 clawdbot');
process.exit(1);
}
console.log(`\n使用 ${cmd} 安装插件...`);
runCommand(cmd, ['plugins', 'install', '@sliverp/qqbot']);
console.log('\n=== 安装完成 ===');
console.log('\n请配置机器人通道:');
console.log(` ${cmd} channels add --channel qqbot --token "AppID:AppSecret"`);
}
// 显示帮助
function showHelp() {
console.log(`
QQBot CLI - QQ机器人插件管理工具
用法:
npx @sliverp/qqbot <命令>
命令:
upgrade 清理旧版本插件(升级前执行)
install 安装插件到 openclaw/clawdbot
示例:
npx @sliverp/qqbot upgrade
npx @sliverp/qqbot install
`);
}
// 主入口
switch (command) {
case 'upgrade':
upgrade();
break;
case 'install':
install();
break;
case '-h':
case '--help':
case 'help':
showHelp();
break;
default:
if (command) {
console.log(`未知命令: ${command}`);
}
showHelp();
process.exit(command ? 1 : 0);
}