功能特性: - 支持 /upload, /u 命令上传文件到七牛云 - 支持 /qiniu-config 配置管理 - 支持飞书卡片交互 - 支持指定上传路径和存储桶 - 自动刷新 CDN 缓存 - 支持文件覆盖上传 包含组件: - OpenClaw 处理器 (openclaw-processor.js) - 独立监听器 (scripts/feishu-listener.js) - 核心上传脚本 (scripts/upload-to-qiniu.js) - 部署脚本 (deploy.sh) - 完整文档 部署方式: 1. 复制 skill 到 ~/.openclaw/workspace/skills/ 2. 配置 ~/.openclaw/credentials/qiniu-config.json 3. 重启 OpenClaw Gateway
167 lines
4.5 KiB
JavaScript
167 lines
4.5 KiB
JavaScript
#!/usr/bin/env node
|
||
|
||
/**
|
||
* 七牛云存储桶设置更新脚本
|
||
*
|
||
* 用途:更新存储桶的防覆盖等设置
|
||
*
|
||
* 用法:
|
||
* node update-bucket-setting.js <bucket-name> <setting> <value>
|
||
*
|
||
* 示例:
|
||
* node update-bucket-setting.js mybucket noOverwrite 0 # 允许覆盖
|
||
* node update-bucket-setting.js mybucket noOverwrite 1 # 禁止覆盖
|
||
*/
|
||
|
||
const fs = require('fs');
|
||
const path = require('path');
|
||
const crypto = require('crypto');
|
||
const https = require('https');
|
||
const http = require('http');
|
||
|
||
const DEFAULT_CONFIG_PATH = path.join(process.env.HOME || process.env.USERPROFILE, '.openclaw/credentials/qiniu-config.json');
|
||
|
||
function loadConfig() {
|
||
if (!fs.existsSync(DEFAULT_CONFIG_PATH)) {
|
||
throw new Error(`配置文件不存在:${DEFAULT_CONFIG_PATH}`);
|
||
}
|
||
return JSON.parse(fs.readFileSync(DEFAULT_CONFIG_PATH, 'utf-8'));
|
||
}
|
||
|
||
function hmacSha1(data, secret) {
|
||
return crypto.createHmac('sha1', secret).update(data).digest();
|
||
}
|
||
|
||
function urlSafeBase64(data) {
|
||
return Buffer.from(data).toString('base64')
|
||
.replace(/\+/g, '-')
|
||
.replace(/\//g, '_');
|
||
}
|
||
|
||
function generateAccessToken(accessKey, secretKey, method, path, body = '') {
|
||
const host = 'api.qiniu.com';
|
||
const contentType = 'application/json';
|
||
|
||
const signData = `${method} ${path}\nHost: ${host}\nContent-Type: ${contentType}\n\n${body}`;
|
||
const signature = hmacSha1(signData, secretKey);
|
||
const encodedSign = urlSafeBase64(signature);
|
||
|
||
return `Qiniu ${accessKey}:${encodedSign}`;
|
||
}
|
||
|
||
function httpRequest(url, options, body = null) {
|
||
return new Promise((resolve, reject) => {
|
||
const protocol = url.startsWith('https') ? https : http;
|
||
|
||
const req = protocol.request(url, options, (res) => {
|
||
let data = '';
|
||
res.on('data', chunk => data += chunk);
|
||
res.on('end', () => {
|
||
try {
|
||
const json = JSON.parse(data);
|
||
resolve({ status: res.statusCode, data: json });
|
||
} catch (e) {
|
||
resolve({ status: res.statusCode, data: data });
|
||
}
|
||
});
|
||
});
|
||
|
||
req.on('error', reject);
|
||
|
||
if (body) {
|
||
req.write(body);
|
||
}
|
||
|
||
req.end();
|
||
});
|
||
}
|
||
|
||
async function updateBucketSetting(bucketName, setting, value) {
|
||
const config = loadConfig();
|
||
const bucketConfig = config.buckets['default'];
|
||
|
||
if (!bucketConfig) {
|
||
throw new Error(`默认存储桶配置不存在`);
|
||
}
|
||
|
||
const { accessKey, secretKey, bucket } = bucketConfig;
|
||
|
||
console.log('🔄 更新存储桶设置...\n');
|
||
console.log(`存储桶:${bucket}`);
|
||
console.log(`设置项:${setting}`);
|
||
console.log(`值:${value}`);
|
||
console.log('');
|
||
|
||
// 七牛云存储桶设置 API
|
||
// 文档:https://developer.qiniu.com/kodo/api/1313/bucket-settings-update
|
||
const updateUrl = `https://api.qiniu.com/buckets/${bucket}/settings`;
|
||
|
||
const body = JSON.stringify({
|
||
[setting]: value === '1' || value === 'true' ? 1 : 0
|
||
});
|
||
|
||
const accessToken = generateAccessToken(accessKey, secretKey, 'PUT', `/buckets/${bucket}/settings`, body);
|
||
|
||
const options = {
|
||
method: 'PUT',
|
||
headers: {
|
||
'Host': 'api.qiniu.com',
|
||
'Content-Type': 'application/json',
|
||
'Content-Length': body.length,
|
||
'Authorization': accessToken
|
||
}
|
||
};
|
||
|
||
console.log('📤 发送更新请求...');
|
||
const result = await httpRequest(updateUrl, options, body);
|
||
|
||
if (result.status !== 200) {
|
||
console.error('❌ 更新失败:', result.data);
|
||
console.log('\n可能原因:');
|
||
console.log('1. AccessKey/SecretKey 权限不足,需要存储桶管理权限');
|
||
console.log('2. 存储桶名称不正确');
|
||
console.log('3. 设置项不支持通过 API 修改');
|
||
return;
|
||
}
|
||
|
||
console.log('✅ 设置已更新成功!\n');
|
||
console.log('提示:设置可能需要几分钟生效,请稍后重试上传。');
|
||
}
|
||
|
||
function printUsage() {
|
||
console.log(`
|
||
用法:node update-bucket-setting.js <bucket-name> <setting> <value>
|
||
|
||
设置项:
|
||
noOverwrite - 防覆盖设置 (0=允许覆盖,1=禁止覆盖)
|
||
|
||
示例:
|
||
node update-bucket-setting.js mybucket noOverwrite 0 # 允许覆盖
|
||
node update-bucket-setting.js mybucket noOverwrite 1 # 禁止覆盖
|
||
`);
|
||
}
|
||
|
||
async function main() {
|
||
const args = process.argv.slice(2);
|
||
|
||
if (args.length < 3) {
|
||
printUsage();
|
||
process.exit(1);
|
||
}
|
||
|
||
const [bucketName, setting, value] = args;
|
||
|
||
try {
|
||
await updateBucketSetting(bucketName, setting, value);
|
||
} catch (error) {
|
||
console.error('❌ 错误:', error.message);
|
||
process.exit(1);
|
||
}
|
||
}
|
||
|
||
if (require.main === module) {
|
||
main();
|
||
}
|
||
|
||
module.exports = { updateBucketSetting };
|