Willkommens-Karten, Geburtstage, Devlog-Permalinks mit OG-Vorschau, Auto-Publish
- Willkommens-Karten: gerendertes PNG (SVG → sharp) mit Avatar im Neon-Ring, Willkommens-Schriftzug und Member-Nummer; Fallback aufs bisherige Embed wenn das Rendering scheitert; Dockerfile installiert fonts-dejavu-core für die Text-Darstellung - Geburtstags-System: /geburtstag setzen|entfernen (birthdays-Tabelle), tägliche Runde ab 09:00 Europe/Berlin (Doppel-Post-Schutz über last_birthday_run), Gratulations-Embed + Tages-Rolle (wird am nächsten Morgen wieder abgeräumt); Kanal + Rolle im Community-Tab - Devlog-Permalinks: /devlogs/:id als eigene Seite (GET /api/devlogs/:id), Link-Symbol an jeder Karte, Link-kopieren-Button; der Server injiziert Open-Graph-Tags ins SPA-HTML — Devlog-Links zeigen Titel, Anriss und Bild, alle anderen Seiten bekommen Default-Tags (auch die Startseite) - Auto-Publish: maybeCrosspost() veröffentlicht Devlog-, Release-, Composer- und geplante Posts automatisch in Ankündigungs-Kanälen - brandEmbed: leere Avatar-URL crasht nicht mehr die Footer-Validierung Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
+18
-3
@@ -1,5 +1,5 @@
|
||||
// Moderation & Kontakt: Modmail (DM ↔ Staff-Thread), Willkommens-Embed, Mod-Log
|
||||
import { ChannelType, EmbedBuilder, Events } from 'discord.js';
|
||||
import { AttachmentBuilder, ChannelType, EmbedBuilder, Events } from 'discord.js';
|
||||
import { saveModmail, modmailByUser, modmailByThread, saveStickyRoles, stickyRolesOf } from '../db.js';
|
||||
import { modmailChannelId, welcomeChannelId, modlogChannelId, publicUrl, autoroleId, stickyRolesEnabled, brandColor, brandColor2, brandFooter } from '../runtime-settings.js';
|
||||
|
||||
@@ -86,7 +86,6 @@ async function handleMemberAdd(member) {
|
||||
const embed = new EmbedBuilder()
|
||||
.setColor(brandColor())
|
||||
.setTitle(`👋 Willkommen, ${member.displayName}!`)
|
||||
.setThumbnail(member.user.displayAvatarURL({ size: 128 }))
|
||||
.setDescription(
|
||||
`Schön, dass du da bist — du bist Mitglied **#${member.guild.memberCount}**.\n\n` +
|
||||
`📔 Devlogs & Roadmap: ${publicUrl()}\n` +
|
||||
@@ -96,7 +95,23 @@ async function handleMemberAdd(member) {
|
||||
.setFooter({ text: brandFooter('COMMUNITY'), iconURL: member.client?.user?.displayAvatarURL?.({ size: 64 }) })
|
||||
.setTimestamp();
|
||||
|
||||
await channel.send({ content: `<@${member.id}>`, embeds: [embed] });
|
||||
// Gerenderte Willkommens-Karte — wenn das Rendering klemmt, gibt's das Embed pur
|
||||
let files = [];
|
||||
try {
|
||||
const { buildWelcomeCard } = await import('./welcome-card.js');
|
||||
const png = await buildWelcomeCard({
|
||||
username: member.displayName,
|
||||
avatarUrl: member.user.displayAvatarURL({ extension: 'png', size: 128 }),
|
||||
memberNumber: member.guild.memberCount,
|
||||
});
|
||||
files = [new AttachmentBuilder(png, { name: 'welcome.png' })];
|
||||
embed.setImage('attachment://welcome.png');
|
||||
} catch (error) {
|
||||
embed.setThumbnail(member.user.displayAvatarURL({ size: 128 }));
|
||||
console.error('[welcome] Karte fehlgeschlagen, nutze Embed:', error.message);
|
||||
}
|
||||
|
||||
await channel.send({ content: `<@${member.id}>`, embeds: [embed], files });
|
||||
}
|
||||
|
||||
/* ── Auto- & Sticky-Roles ──────────────────────────── */
|
||||
|
||||
Reference in New Issue
Block a user