Bug-Reports, Devlog-Threads und Watchdog
- /bug (alle Member): erstellt Gitea-Issue inkl. Screenshot-Upload als Asset; bug_reports-Tabelle für den Rückkanal — Issue geschlossen (issues-Webhook) → DM an den Reporter - Auto-Thread '💬 Devlog <Datum>' unter jedem Devlog-Post (Setting, Default an) - Watchdog: prüft Setting watchdog_urls alle 2 min, DM an Admin nach 2 Fails in Folge + Entwarnung mit Downtime-Dauer - Setup-Seite: Bug-Repo, Threads-Toggle, Watchdog-URLs; Env GITEA_API_TOKEN/GITEA_URL Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,75 @@
|
||||
// /bug — Bug-Report aus Discord: erstellt ein Gitea-Issue (inkl. Screenshot-Upload)
|
||||
import { SlashCommandBuilder, MessageFlags } from 'discord.js';
|
||||
import { config } from '../../config.js';
|
||||
import { bugReportRepo } from '../../runtime-settings.js';
|
||||
import { createIssue, uploadIssueAsset } from '../../gitea-api.js';
|
||||
import { saveBugReport } from '../../db.js';
|
||||
|
||||
export const data = new SlashCommandBuilder()
|
||||
.setName('bug')
|
||||
.setDescription('Bug melden — landet direkt beim Entwickler')
|
||||
.addStringOption((o) =>
|
||||
o.setName('titel').setDescription('Kurze Zusammenfassung').setRequired(true).setMaxLength(120)
|
||||
)
|
||||
.addStringOption((o) =>
|
||||
o.setName('beschreibung')
|
||||
.setDescription('Was ist passiert? Was hast du erwartet?')
|
||||
.setRequired(true)
|
||||
.setMaxLength(1500)
|
||||
)
|
||||
.addAttachmentOption((o) =>
|
||||
o.setName('screenshot').setDescription('Optional: Screenshot des Problems')
|
||||
);
|
||||
|
||||
export async function execute(interaction) {
|
||||
await interaction.deferReply({ flags: MessageFlags.Ephemeral });
|
||||
|
||||
if (!config.giteaApiToken) {
|
||||
await interaction.editReply('❌ Bug-Reports sind gerade nicht konfiguriert (kein Gitea-Token).');
|
||||
return;
|
||||
}
|
||||
|
||||
const repo = bugReportRepo();
|
||||
const titel = interaction.options.getString('titel');
|
||||
const beschreibung = interaction.options.getString('beschreibung');
|
||||
const screenshot = interaction.options.getAttachment('screenshot');
|
||||
|
||||
const body = `${beschreibung}\n\n---\n🎮 Gemeldet via Discord von **${interaction.user.tag}**`;
|
||||
|
||||
try {
|
||||
const issue = await createIssue(repo, `[Bug] ${titel}`, body);
|
||||
|
||||
// Screenshot als Issue-Attachment hochladen (Discord-CDN-Links laufen ab)
|
||||
if (screenshot?.contentType?.startsWith('image/')) {
|
||||
try {
|
||||
const res = await fetch(screenshot.url);
|
||||
if (res.ok) {
|
||||
await uploadIssueAsset(
|
||||
repo,
|
||||
issue.number,
|
||||
screenshot.name ?? 'screenshot.png',
|
||||
Buffer.from(await res.arrayBuffer())
|
||||
);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('[bug] Screenshot-Upload fehlgeschlagen:', error.message);
|
||||
}
|
||||
}
|
||||
|
||||
// Für den Rückkanal merken: Issue geschlossen → DM an den Reporter
|
||||
saveBugReport({
|
||||
repo,
|
||||
issue_number: issue.number,
|
||||
discord_user_id: interaction.user.id,
|
||||
title: titel,
|
||||
});
|
||||
|
||||
await interaction.editReply(
|
||||
`✅ Danke! Dein Bug ist erfasst als [#${issue.number}](${issue.html_url}) — ` +
|
||||
`du bekommst eine DM, sobald er behoben ist.`
|
||||
);
|
||||
} catch (error) {
|
||||
console.error('[bug] Issue-Erstellung fehlgeschlagen:', error);
|
||||
await interaction.editReply('❌ Konnte das Issue nicht anlegen — bitte später nochmal versuchen.');
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user