Files
CloudFlare-ImgBed/functions/utils/sysConfig.js
axibayuit 24d88fd9a1 feat: 添加 Discord 渠道支持
- 新增 Discord API 封装类 (discordAPI.js)
- 支持 Discord 文件上传(10MB 限制,超过自动切换其他渠道)
- 支持 Discord 文件读取和代理 URL(国内访问)
- 前端添加 Discord 渠道配置 UI(负载均衡、表单验证)
- 支持环境变量配置:DISCORD_BOT_TOKEN, DISCORD_CHANNEL_ID, DISCORD_PROXY_URL
- 修复 sysConfig.js 中 Discord 渠道过滤
2025-12-30 15:08:19 +08:00

131 lines
4.7 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.
import { getUploadConfig } from '../api/manage/sysConfig/upload';
import { getSecurityConfig } from '../api/manage/sysConfig/security';
import { getPageConfig } from '../api/manage/sysConfig/page';
import { getOthersConfig } from '../api/manage/sysConfig/others';
import { getDatabase } from './databaseAdapter.js';
import { getIndexMeta } from './indexManager.js';
/**
* 根据容量限制过滤渠道
* @param {Object} context - 上下文对象(包含 env
* @param {Array} channels - 渠道列表
* @returns {Array} 过滤后的渠道列表
*/
async function filterChannelsByQuota(context, channels) {
// 先检查是否有任何渠道启用了容量限制,如果都没启用则跳过 KV 读取
const hasQuotaEnabled = channels.some(ch => ch.quota?.enabled && ch.quota?.limitGB);
if (!hasQuotaEnabled) {
return channels; // 无需读取 KV直接返回所有渠道
}
// 获取索引元数据(只需 1 次读取)
const indexMeta = await getIndexMeta(context);
const channelStats = indexMeta.channelStats || {};
const result = [];
for (const channel of channels) {
// 未启用容量限制,直接通过
if (!channel.quota?.enabled || !channel.quota?.limitGB) {
result.push(channel);
continue;
}
try {
// 从索引元数据中获取该渠道的容量统计
const stats = channelStats[channel.name] || { usedMB: 0, fileCount: 0 };
const usedGB = stats.usedMB / 1024;
const limitGB = channel.quota.limitGB;
const threshold = channel.quota.threshold || 95;
// 未超过阈值,渠道可用
if ((usedGB / limitGB) * 100 < threshold) {
result.push(channel);
} else {
console.log(`Channel ${channel.name} quota exceeded: ${usedGB.toFixed(2)}GB / ${limitGB}GB (${threshold}% threshold)`);
}
} catch (error) {
console.error(`Failed to check quota for channel ${channel.name}:`, error);
// 检查失败时保守处理,允许使用该渠道
result.push(channel);
}
}
return result;
}
export async function fetchUploadConfig(env, context = null) {
try {
const db = getDatabase(env);
const settings = await getUploadConfig(db, env);
// 去除 已禁用 的渠道
settings.telegram.channels = settings.telegram.channels.filter((channel) => channel.enabled);
settings.cfr2.channels = settings.cfr2.channels.filter((channel) => channel.enabled);
settings.s3.channels = settings.s3.channels.filter((channel) => channel.enabled);
settings.discord.channels = settings.discord.channels.filter((channel) => channel.enabled);
// 根据容量限制过滤渠道(仅 R2 和 S3
// 需要 context 来调用 getIndexMeta
if (context) {
settings.cfr2.channels = await filterChannelsByQuota(context, settings.cfr2.channels);
settings.s3.channels = await filterChannelsByQuota(context, settings.s3.channels);
}
return settings;
} catch (error) {
console.error('Failed to fetch upload config:', error);
// 返回默认配置
return {
telegram: { channels: [] },
cfr2: { channels: [] },
s3: { channels: [] },
discord: { channels: [] }
};
}
}
export async function fetchSecurityConfig(env) {
try {
const db = getDatabase(env);
const settings = await getSecurityConfig(db, env);
return settings;
} catch (error) {
console.error('Failed to fetch security config:', error);
// 返回默认配置
return {
auth: {
user: { authCode: "" },
admin: { adminUsername: "", adminPassword: "" }
},
upload: {
moderate: { enabled: false, channel: "default", moderateContentApiKey: "", nsfwApiPath: "" }
},
access: { allowedDomains: "", whiteListMode: false }
};
}
}
export async function fetchPageConfig(env) {
try {
const db = getDatabase(env);
const settings = await getPageConfig(db, env);
return settings;
} catch (error) {
console.error('Failed to fetch page config:', error);
// 返回默认配置
return { config: [] };
}
}
export async function fetchOthersConfig(env) {
try {
const db = getDatabase(env);
const settings = await getOthersConfig(db, env);
return settings;
} catch (error) {
console.error('Failed to fetch others config:', error);
// 返回默认配置
return {
telemetry: { enabled: false }
};
}
}