Setup-Seite: Kanal-Auswahl, Feed-Regeln und Status im Webinterface

- Settings-Tabelle in SQLite; Env-Variablen nur noch Fallback, Änderungen greifen sofort
- /settings (Admin): Devlog-/Commit-Kanal als Dropdown aus allen sichtbaren Textkanälen,
  je mit Test-senden-Button
- Commit-Feed-Regeln: an/aus, Branch-Filter, ignorierte Repos (archiviert wird immer,
  gefiltert wird nur das Posten; ignorierte Repos komplett übersprungen)
- Status-Panel: Bot-Tag, Uptime, Devlog-/Commit-Zahlen, DB-Größe
- API: GET/PUT /api/settings, POST /api/settings/test/:target (alles Admin-only)
- COMMIT_CHANNEL_ID/DEVLOG_CHANNEL_ID in config optional

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-07-23 10:21:05 +02:00
co-authored by Claude Opus 4.8
parent 71d2bb07f1
commit ae5732a61b
14 changed files with 516 additions and 23 deletions
+3 -2
View File
@@ -1,6 +1,7 @@
// Discord-Client: Commands laden, registrieren und Interactions verarbeiten
import { Client, Collection, Events, GatewayIntentBits, Partials, REST, Routes } from 'discord.js';
import { config } from '../config.js';
import { devlogChannelId } from '../runtime-settings.js';
import { archiveDevlogMessage, removeDevlog } from './devlog-archive.js';
import * as ping from './commands/ping.js';
import * as devlogBackfill from './commands/devlog-backfill.js';
@@ -34,7 +35,7 @@ export async function startBot() {
// Live-Archivierung: neue Devlogs (Webhook-Posts im Devlog-Kanal) sofort sichern
client.on(Events.MessageCreate, async (message) => {
if (message.channelId !== config.devlogChannelId) return;
if (message.channelId !== devlogChannelId()) return;
try {
if (await archiveDevlogMessage(message)) {
console.log(`[devlog] Neues Devlog archiviert (${message.id})`);
@@ -46,7 +47,7 @@ export async function startBot() {
// In Discord gelöscht = im Archiv gelöscht (inkl. lokaler Bilder)
client.on(Events.MessageDelete, async (message) => {
if (message.channelId !== config.devlogChannelId) return;
if (message.channelId !== devlogChannelId()) return;
try {
if (await removeDevlog(message.id)) {
console.log(`[devlog] Archiv-Eintrag entfernt (Discord-Nachricht ${message.id} gelöscht)`);
+7 -2
View File
@@ -1,6 +1,6 @@
// /devlog-backfill — komplette Kanal-Historie scannen und alte Devlogs nacharchivieren (Admin only)
import { SlashCommandBuilder, PermissionFlagsBits, MessageFlags } from 'discord.js';
import { config } from '../../config.js';
import { devlogChannelId } from '../../runtime-settings.js';
import { archiveDevlogMessage } from '../devlog-archive.js';
export const data = new SlashCommandBuilder()
@@ -11,7 +11,12 @@ export const data = new SlashCommandBuilder()
export async function execute(interaction) {
await interaction.deferReply({ flags: MessageFlags.Ephemeral });
const channel = await interaction.client.channels.fetch(config.devlogChannelId);
const targetChannel = devlogChannelId();
if (!targetChannel) {
await interaction.editReply('❌ Kein Devlog-Kanal konfiguriert (Settings-Seite im Webinterface).');
return;
}
const channel = await interaction.client.channels.fetch(targetChannel);
if (!channel?.isTextBased()) {
await interaction.editReply('❌ Devlog-Kanal nicht gefunden oder kein Textkanal.');
return;
+7 -3
View File
@@ -1,6 +1,6 @@
// Baut aus einem Gitea-Push ein hübsches Embed und postet es in den Commit-Kanal
import { EmbedBuilder } from 'discord.js';
import { config } from '../config.js';
import { commitChannelId } from '../runtime-settings.js';
const GITEA_GREEN = 0x609926;
const MAX_COMMITS_SHOWN = 10;
@@ -19,9 +19,13 @@ function firstLine(message, maxLen = 72) {
* commits: Array<{sha: string, message: string, url: string, author_name: string}> }} push
*/
export async function postPushEmbed(client, push) {
const channel = await client.channels.fetch(config.commitChannelId);
const channelId = commitChannelId();
if (!channelId) {
throw new Error('Kein Commit-Kanal konfiguriert (Settings-Seite oder COMMIT_CHANNEL_ID)');
}
const channel = await client.channels.fetch(channelId);
if (!channel?.isTextBased()) {
throw new Error(`Commit-Kanal ${config.commitChannelId} nicht gefunden oder kein Textkanal`);
throw new Error(`Commit-Kanal ${channelId} nicht gefunden oder kein Textkanal`);
}
const count = push.commits.length;