96 lines
3.1 KiB
JavaScript
96 lines
3.1 KiB
JavaScript
function isDiscordWebhook(url) {
|
|
return /(^https?:\/\/)(ptb\.|canary\.)?(discord(app)?\.com)\/api\/webhooks\//i.test(String(url || ''));
|
|
}
|
|
|
|
function formatDurationShort(sec) {
|
|
const s = Math.max(0, Math.round(Number(sec) || 0));
|
|
const h = Math.floor(s / 3600);
|
|
const m = Math.floor((s % 3600) / 60);
|
|
const r = s % 60;
|
|
if (h > 0) return `${h}h ${m}m`;
|
|
if (m > 0) return `${m}m ${r}s`;
|
|
return `${r}s`;
|
|
}
|
|
|
|
function summarizePerHosterFromBatch(summary) {
|
|
const out = {};
|
|
if (!summary || !Array.isArray(summary.files)) return out;
|
|
for (const f of summary.files) {
|
|
if (!f || !Array.isArray(f.results)) continue;
|
|
for (const r of f.results) {
|
|
if (!r || !r.hoster) continue;
|
|
const b = out[r.hoster] || (out[r.hoster] = { ok: 0, fail: 0 });
|
|
if (r.status === 'done') b.ok++;
|
|
else b.fail++;
|
|
}
|
|
}
|
|
return out;
|
|
}
|
|
|
|
function resolveDiscordMention(raw) {
|
|
const s = String(raw || '').trim();
|
|
if (!s) return null;
|
|
const keyword = s.replace(/^@/, '').toLowerCase();
|
|
if (keyword === 'here' || keyword === 'everyone') {
|
|
return { token: `@${keyword}`, allowed: { parse: ['everyone'] } };
|
|
}
|
|
const roleMatch = s.match(/^(?:<@&(\d+)>|role:(\d+))$/i);
|
|
if (roleMatch) {
|
|
const id = roleMatch[1] || roleMatch[2];
|
|
return { token: `<@&${id}>`, allowed: { roles: [id] } };
|
|
}
|
|
const userMatch = s.match(/^(?:<@!?(\d+)>|user:(\d+)|(\d{5,30}))$/i);
|
|
if (userMatch) {
|
|
const id = userMatch[1] || userMatch[2] || userMatch[3];
|
|
return { token: `<@${id}>`, allowed: { users: [id] } };
|
|
}
|
|
return null;
|
|
}
|
|
|
|
function buildWebhookRequest(url, summary, meta) {
|
|
const m = meta || {};
|
|
const total = Number(summary && summary.total) || 0;
|
|
const succeeded = Number(summary && summary.succeeded) || 0;
|
|
const failed = Number(summary && summary.failed) || 0;
|
|
const perHoster = summarizePerHosterFromBatch(summary);
|
|
const duration = formatDurationShort(m.durationSec);
|
|
|
|
let body;
|
|
if (isDiscordWebhook(url)) {
|
|
const hosterLines = Object.entries(perHoster)
|
|
.map(([h, b]) => `${h}: ${b.ok}/${b.ok + b.fail}`)
|
|
.join(' · ');
|
|
const lines = [
|
|
`**Multi-Hoster-Upload — Batch fertig**${m.machineName ? ` (${m.machineName})` : ''}`,
|
|
`✅ ${succeeded} ok · ❌ ${failed} Fehler · 📦 ${total} gesamt · ⏱ ${duration}`
|
|
];
|
|
if (hosterLines) lines.push(hosterLines);
|
|
const mention = resolveDiscordMention(m.mention);
|
|
const payload = { content: (mention ? mention.token + ' ' : '') + lines.join('\n') };
|
|
payload.allowed_mentions = mention ? mention.allowed : { parse: [] };
|
|
body = JSON.stringify(payload);
|
|
} else {
|
|
body = JSON.stringify({
|
|
event: 'batch-done',
|
|
app: 'multi-hoster-upload',
|
|
version: m.appVersion || null,
|
|
machine: m.machineName || null,
|
|
total,
|
|
succeeded,
|
|
failed,
|
|
durationSec: Math.round(Number(m.durationSec) || 0),
|
|
perHoster,
|
|
timestamp: m.timestamp || null
|
|
});
|
|
}
|
|
|
|
return {
|
|
url: String(url),
|
|
method: 'POST',
|
|
headers: { 'Content-Type': 'application/json' },
|
|
body
|
|
};
|
|
}
|
|
|
|
module.exports = { isDiscordWebhook, formatDurationShort, summarizePerHosterFromBatch, buildWebhookRequest, resolveDiscordMention };
|