Screenshots zu Ideen, und der Bot legt die Forum-Tags selbst an
Zwei Fragen, zwei Antworten — eine davon ein Nein mit Umweg. ## Bilder im Eingabefenster: geht nicht Discord-Modals koennen nur Textfelder. Kein Datei-Anhang, keine Umgehung — das ist eine Grenze der Plattform, nicht unseres Codes. Der Umweg ist besser als er klingt: Wer nach dem Einreichen einen Screenshot in den Thread haengt, sieht ihn auf der Ideen-Seite. Die Bestaetigung nach dem Absenden sagt das jetzt auch. Damit kann man auch nachtraeglich noch Bilder dazulegen, was im Eingabefenster gar nicht ginge. ## Warum nicht einfach der Discord-Link Discord haengt seit einiger Zeit eine Signatur an die Anhang-Links (?ex=&is=&hm=), die nach etwa einem Tag ablaeuft. Ein gespeicherter Link zeigt morgen ein kaputtes Bild. Deshalb laden Devlogs und Galerie seit dem ersten Tag herunter — im Kopf von devlog-archive.js steht der Grund. Wuensche machen es jetzt genauso, ausgeliefert unter /wish-assets/. Beim Loeschen eines Beitrags oder eines ganzen Wunsches gehen die Dateien mit; sonst waechst der Ordner mit Bildern, auf die nichts mehr zeigt. Das Herunterladen stand vorher zweimal fast wortgleich im Code. Mit den Wuenschen waeren es drei Kopien geworden — also einmal nach bot/bilder.js, und Devlogs und Galerie ziehen mit um. Ein Fehler steckt jetzt an einer Stelle statt an dreien. ## Forum-Tags per Knopf Bisher musstest du sie von Hand anlegen. Jetzt macht es das Panel: die Bereiche von dort plus die fuenf Staende, mit ihren Emojis. Vorhandene bleiben, auch fremde — die Liste wird ergaenzt und nicht ersetzt. Discords Grenze von 20 Tags wird eingehalten, was nicht mehr reinpasst, wird gemeldet statt still verschluckt. Geprueft: forumTagsAnlegen gegen eine Kanal-Attrappe — leeres Forum, teilweise vorhandene, Gross/Kleinschreibung, fremde Tags, nichts zu tun (dann wird auch nicht geschrieben), volles Forum, kein Forum, kein Kanal. Im Browser die Ideen-Seite mit Bildern in einem Beitrag, einem Beitrag nur aus Bild ohne Text, und der Lightbox darueber. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,54 @@
|
||||
// Bilder aus Discord-Nachrichten lokal sichern.
|
||||
//
|
||||
// Discord-CDN-Links laufen ab — wer sie nur speichert, hat nach ein paar Wochen
|
||||
// eine Seite voller kaputter Vorschaubilder. Deshalb wird heruntergeladen und
|
||||
// vom Webserver selbst ausgeliefert.
|
||||
//
|
||||
// Stand vorher dreimal fast gleich im Code (Devlogs, Galerie, jetzt Wünsche);
|
||||
// hier einmal, damit ein Fehler auch nur einmal drinsteckt.
|
||||
import { mkdirSync } from 'node:fs';
|
||||
import { writeFile, rm } from 'node:fs/promises';
|
||||
import { join, dirname, resolve } from 'node:path';
|
||||
import { config } from '../config.js';
|
||||
|
||||
/** Ordner neben der SQLite anlegen und zurückgeben */
|
||||
export function bildOrdner(name) {
|
||||
const dir = join(dirname(resolve(config.dbPath)), name);
|
||||
mkdirSync(dir, { recursive: true });
|
||||
return dir;
|
||||
}
|
||||
|
||||
/**
|
||||
* Bild-Anhänge einer Nachricht herunterladen.
|
||||
*
|
||||
* @param {import('discord.js').Message} message
|
||||
* @param {{ dir: string, max?: number, tag?: string }} opts
|
||||
* @returns {Promise<string[]>} gespeicherte Dateinamen
|
||||
*/
|
||||
export async function bilderSichern(message, { dir, max = 4, tag = 'bilder' }) {
|
||||
const files = [];
|
||||
for (const att of [...(message.attachments?.values?.() ?? [])]) {
|
||||
if (files.length >= max) break;
|
||||
if (!att.contentType?.startsWith('image/')) continue;
|
||||
|
||||
// Endung säubern: der Name kommt vom Hochladenden und landet im Dateisystem
|
||||
const ext = (att.name?.split('.').pop() || 'png').toLowerCase().replace(/[^a-z0-9]/g, '') || 'png';
|
||||
const file = `${message.id}_${files.length}.${ext}`;
|
||||
try {
|
||||
const res = await fetch(att.url);
|
||||
if (!res.ok) continue;
|
||||
await writeFile(join(dir, file), Buffer.from(await res.arrayBuffer()));
|
||||
files.push(file);
|
||||
} catch (error) {
|
||||
console.error(`[${tag}] Bild-Download fehlgeschlagen (${att.url}):`, error.message);
|
||||
}
|
||||
}
|
||||
return files;
|
||||
}
|
||||
|
||||
/** Gespeicherte Bilder wieder wegräumen */
|
||||
export async function bilderLoeschen(dir, files) {
|
||||
for (const file of files ?? []) {
|
||||
await rm(join(dir, file), { force: true });
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user