Files
WhoPays/server.js
T

162 lines
3.7 KiB
JavaScript

import express from "express";
import fs from "fs";
import path from "path";
import { fileURLToPath } from "url";
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
const app = express();
app.use(express.json());
app.use(express.static(path.join(__dirname, "public")));
const stateFile = path.join(__dirname, "state.json");
// --------------------
// Konfiguration
// --------------------
const CONFIG = {
A: {
name: "Marc",
color: 0x2ecc71, // grün
icon: "a.png"
},
B: {
name: "Laila",
color: 0xe74c3c, // rot
icon: "b.png"
}
};
// Öffentliche URL zu deinem Server (WICHTIG für Discord Icons!)
const PUBLIC_BASE_URL = process.env.PUBLIC_BASE_URL
|| "http://localhost:3000";
// 🔔 Discord Webhook URL
const DISCORD_WEBHOOK_URL = process.env.DISCORD_WEBHOOK_URL
|| "https://discord.com/api/webhooks/1450872860607381515/zRbiXOykKPUfLJ_H87wD2OxQJPLdro6yQzU2T48Pg4fxSNaXEqBFgxdHGTiIDmmKGHIF";
// --------------------
// State Handling
// --------------------
function getState() {
if (!fs.existsSync(stateFile)) {
fs.writeFileSync(
stateFile,
JSON.stringify({ current: "A", lastReason: null }, null, 2)
);
}
return JSON.parse(fs.readFileSync(stateFile, "utf-8"));
}
function setState(newState) {
fs.writeFileSync(stateFile, JSON.stringify(newState, null, 2));
}
// --------------------
// Discord Webhook
// --------------------
async function sendDiscordEmbed(previousKey, currentKey, reason) {
const previous = CONFIG[previousKey];
const current = CONFIG[currentKey];
if (!DISCORD_WEBHOOK_URL) return;
const fields = [
{
name: "Von",
value: previous.name,
inline: true
},
{
name: "Zu",
value: current.name,
inline: true
}
];
// Add reason field if provided
if (reason) {
fields.push({
name: "📝 Grund",
value: reason,
inline: false
});
}
const embed = {
title: "💸 Zahl-Wechsel",
description: `**${current.name}** ist jetzt dran zu zahlen`,
color: current.color,
thumbnail: {
url: `${PUBLIC_BASE_URL}/img/${current.icon}`
},
fields: fields,
footer: {
text: new Date().toLocaleString("de-DE")
}
};
try {
await fetch(DISCORD_WEBHOOK_URL, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
embeds: [embed]
})
});
console.log("✅ Discord Benachrichtigung gesendet");
} catch (err) {
console.error("❌ Discord Webhook Fehler:", err.message);
}
}
// --------------------
// Routes
// --------------------
// GET: aktueller Zustand
app.get("/status", (req, res) => {
res.json(getState());
});
// POST: wechseln
app.post("/toggle", async (req, res) => {
const state = getState();
const previousKey = state.current;
const reason = req.body?.reason;
state.current = state.current === "A" ? "B" : "A";
state.lastReason = reason || null;
setState(state);
const logMessage = reason
? `Zahl-Wechsel: ${CONFIG[previousKey].name} → ${CONFIG[state.current].name} (Grund: ${reason})`
: `Zahl-Wechsel: ${CONFIG[previousKey].name} → ${CONFIG[state.current].name}`;
console.log(logMessage);
await sendDiscordEmbed(previousKey, state.current, reason);
res.json({
current: state.current,
name: CONFIG[state.current].name,
lastReason: state.lastReason
});
});
// Fallback
app.get(/.*/, (req, res) => {
res.sendFile(path.join(__dirname, "public/index.html"));
});
// --------------------
// Start
// --------------------
const PORT = process.env.PORT || 3000;
app.listen(PORT, () =>
console.log(`WhoPays läuft auf http://localhost:${PORT}`)
);