Update bot configuration and activity type in schema

- Modified package.json to add a new script for setting the bot banner.
- Changed the default activity type in schema.prisma from 'Playing' to 'Watching' for improved bot presence management.
This commit is contained in:
TheOnlyMace
2026-07-22 20:04:11 +02:00
parent bb57b842b9
commit dd93b78c94
5 changed files with 120 additions and 2 deletions

View File

@@ -10,7 +10,7 @@
"test": "vitest run",
"typecheck": "tsc --noEmit -p tsconfig.json",
"prisma:generate": "prisma generate",
"prisma:migrate": "prisma migrate deploy"
"profile:banner": "tsx scripts/set-bot-banner.ts"
},
"dependencies": {
"@nexumi/shared": "workspace:*",

View File

@@ -854,7 +854,7 @@ model FeatureFlag {
model BotPresenceConfig {
id String @id @default("singleton")
status String @default("online")
activityType String @default("Playing")
activityType String @default("Watching")
activityText String @default("nexumi.de")
rotatingMessages Json?
maintenanceMode Boolean @default(false)

View File

@@ -0,0 +1,60 @@
/**
* Uploads docs/logo/nexumi-banner.png as the bot user banner (and optional bio)
* via Discord API.
*
* Usage (from repo root):
* pnpm --filter @nexumi/bot profile:banner
*
* Requires BOT_TOKEN in the environment (or root/.env / apps/bot/.env).
*/
import { readFileSync, existsSync } from 'node:fs';
import { resolve, dirname } from 'node:path';
import { fileURLToPath } from 'node:url';
import { config as loadEnv } from 'dotenv';
const here = dirname(fileURLToPath(import.meta.url));
const repoRoot = resolve(here, '../../..');
for (const candidate of [resolve(repoRoot, '.env'), resolve(here, '../.env')]) {
if (existsSync(candidate)) {
loadEnv({ path: candidate });
}
}
const token = process.env.BOT_TOKEN;
if (!token) {
console.error('BOT_TOKEN is missing.');
process.exit(1);
}
const bannerPath = resolve(repoRoot, 'docs/logo/nexumi-banner.png');
if (!existsSync(bannerPath)) {
console.error(`Banner not found: ${bannerPath}`);
process.exit(1);
}
const png = readFileSync(bannerPath);
const bannerDataUri = `data:image/png;base64,${png.toString('base64')}`;
const bio =
'Moderation, Community & Integrationen — in einem Bot.\n' +
'Dashboard: https://dashboard.nexumi.de\n' +
'nexumi.de';
const response = await fetch('https://discord.com/api/v10/users/@me', {
method: 'PATCH',
headers: {
Authorization: `Bot ${token}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({ banner: bannerDataUri, bio })
});
const body = await response.text();
if (!response.ok) {
console.error(`Failed (${response.status}): ${body}`);
process.exit(1);
}
console.log('Bot profile updated successfully.');
console.log(body);

BIN
docs/logo/nexumi-banner.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 446 KiB

View File

@@ -0,0 +1,58 @@
<svg xmlns="http://www.w3.org/2000/svg" width="1200" height="480" viewBox="0 0 1200 480" role="img" aria-label="Nexumi Discord banner">
<defs>
<linearGradient id="bg" x1="0" y1="0" x2="1" y2="1">
<stop offset="0" stop-color="#0C0E15"/>
<stop offset="0.55" stop-color="#12141F"/>
<stop offset="1" stop-color="#0A0A0D"/>
</linearGradient>
<radialGradient id="glow" cx="28%" cy="48%" r="45%">
<stop offset="0" stop-color="#6366F1" stop-opacity="0.35"/>
<stop offset="0.55" stop-color="#6366F1" stop-opacity="0.12"/>
<stop offset="1" stop-color="#6366F1" stop-opacity="0"/>
</radialGradient>
<linearGradient id="mark" x1="0" y1="1" x2="1" y2="0">
<stop offset="0" stop-color="#6366F1"/>
<stop offset="1" stop-color="#8B5CF6"/>
</linearGradient>
</defs>
<rect width="1200" height="480" fill="url(#bg)"/>
<rect width="1200" height="480" fill="url(#glow)"/>
<!-- faint network dots -->
<g fill="#6366F1" fill-opacity="0.18">
<circle cx="620" cy="90" r="3"/>
<circle cx="760" cy="140" r="2.5"/>
<circle cx="900" cy="100" r="3"/>
<circle cx="980" cy="200" r="2"/>
<circle cx="840" cy="280" r="2.5"/>
<circle cx="1040" cy="320" r="3"/>
<circle cx="700" cy="360" r="2"/>
<circle cx="1120" cy="160" r="2.5"/>
</g>
<g stroke="#6366F1" stroke-opacity="0.12" stroke-width="1.5" fill="none">
<path d="M620 90 L760 140 L900 100 L980 200"/>
<path d="M760 140 L840 280 L700 360"/>
<path d="M900 100 L1120 160 L1040 320"/>
</g>
<!-- N mark (scaled from logo proportions) -->
<g transform="translate(110,40) scale(1.05)">
<g fill="none" stroke="url(#mark)" stroke-linecap="round" stroke-linejoin="round">
<path d="M170 362 V150 L342 362 V150" stroke-width="78" stroke-opacity="0.10"/>
<path d="M170 362 V150 L342 362 V150" stroke-width="52" stroke-opacity="0.16"/>
<path d="M170 362 V150 L342 362 V150" stroke-width="30"/>
</g>
<g fill="url(#mark)">
<circle cx="170" cy="150" r="34"/>
<circle cx="170" cy="362" r="34"/>
<circle cx="342" cy="362" r="34"/>
<circle cx="342" cy="150" r="34"/>
</g>
<circle cx="342" cy="150" r="14" fill="#C7D2FE"/>
</g>
<!-- wordmark -->
<text x="620" y="250" fill="#E6E6EA" font-family="Inter, ui-sans-serif, system-ui, sans-serif" font-size="92" font-weight="700" letter-spacing="-2">Nexumi</text>
<text x="624" y="300" fill="#9A9AA5" font-family="Inter, ui-sans-serif, system-ui, sans-serif" font-size="28" font-weight="500">nexumi.de</text>
</svg>

After

Width:  |  Height:  |  Size: 2.5 KiB