add auto role for new member and member in vocal

This commit is contained in:
Arthur Puechberty
2026-01-16 00:25:06 +01:00
parent 2164c13a04
commit cfa4f05a2d
8 changed files with 688 additions and 248 deletions
+48
View File
@@ -42,6 +42,18 @@ client.on(Events.GuildMemberAdd, member => {
}
}
);
db.get(
"SELECT enabled, role_id FROM autorole_newuser_config WHERE guild_id = ?",
[member.guild.id],
(err, row) => {
if (err || !row || !row.enabled) return;
const role = member.guild.roles.cache.get(row.role_id);
if (role) {
member.roles.add(role);
}
}
);
});
@@ -67,6 +79,42 @@ client.on(Events.GuildMemberRemove, member => {
});
client.on(Events.VoiceStateUpdate, (oldState, newState) => {
if (newState.member.user.bot) return;
const guildId = newState.guild.id;
db.get(
"SELECT enabled, role_id, exclude_channel_ids FROM autorole_vocal_config WHERE guild_id = ?",
[guildId],
(err, row) => {
if (err || !row || !row.enabled) return;
let excludeChannelIds = [];
try {
excludeChannelIds = row.exclude_channel_ids
? JSON.parse(row.exclude_channel_ids)
: [];
} catch (err) {
console.error("Erreur parsing exclude_channel_ids", err);
excludeChannelIds = [];
}
const role = newState.guild.roles.cache.get(row.role_id);
if (!role) return;
// User joins a voice channel and it's not excluded et a pas déjà le rôle
if (newState.channelId && !excludeChannelIds.includes(newState.channelId) && !newState.member.roles.cache.has(role.id)) {
newState.member.roles.add(role);
}
// User leaves a voice channel or joins an excluded one
else if (!newState.channelId || excludeChannelIds.includes(newState.channelId)) {
newState.member.roles.remove(role);
}
}
);
});
client.login(process.env.BOT_TOKEN);
module.exports = client;
+13
View File
@@ -24,6 +24,19 @@ db.exec(`
enabled INTEGER NOT NULL,
message TEXT NOT NULL
);
CREATE TABLE IF NOT EXISTS autorole_newuser_config (
guild_id TEXT PRIMARY KEY,
role_id TEXT,
enabled INTEGER NOT NULL
);
CREATE TABLE IF NOT EXISTS autorole_vocal_config (
guild_id TEXT PRIMARY KEY,
role_id TEXT,
exclude_channel_ids TEXT,
enabled INTEGER NOT NULL
);
`);
module.exports = db;
+58 -1
View File
@@ -139,4 +139,61 @@ small code {
form {
padding: 15px;
}
}
}
#autorole-vocal-exclude-channel {
background-color: #0f1115;
color: #e5e7eb;
border: 1px solid #2a2f3a;
border-radius: 8px;
padding: 8px;
font-size: 14px;
min-width: 240px;
outline: none;
}
/* options */
#autorole-vocal-exclude-channel option {
background-color: #0f1115;
color: #e5e7eb;
padding: 6px;
}
/* hover */
#autorole-vocal-exclude-channel option:hover {
background-color: #1f2937;
}
/* sélection */
#autorole-vocal-exclude-channel option:checked {
background-color: #2563eb; /* bleu */
color: #ffffff;
}
/* focus */
#autorole-vocal-exclude-channel:focus {
border-color: #2563eb;
box-shadow: 0 0 0 1px #2563eb;
}
/* scrollbar (Chrome / Edge) */
#autorole-vocal-exclude-channel::-webkit-scrollbar {
width: 8px;
}
#autorole-vocal-exclude-channel::-webkit-scrollbar-track {
background: #0f1115;
}
#autorole-vocal-exclude-channel::-webkit-scrollbar-thumb {
background: #2a2f3a;
border-radius: 4px;
}
#autorole-vocal-exclude-channel::-webkit-scrollbar-thumb:hover {
background: #3b4252;
}
+160 -12
View File
@@ -88,6 +88,49 @@
<button type="submit">Sauvegarder</button>
<div id="status-goodbye-form"></div>
</form>
<form id="autorole-newuser-form">
<label>
<input type="checkbox" id="autorole-enabled" />
Activer le rôle automatique pour les nouveaux membres
</label>
<label>
Rôle à attribuer :
<br />
<select id="autorole-role">
</select>
</label>
<button type="submit">Sauvegarder</button>
<div id="status-autorole-form"></div>
</form>
<form id="autorole-vocal-form">
<label>
<input type="checkbox" id="autorole-vocal-enabled" />
Activer le rôle automatique pour les membres en vocal
</label>
<label>
Rôle à attribuer :
<br />
<select id="autorole-vocal-role">
</select>
</label>
<label>
Salon à éviter :
<br />
<select id="autorole-vocal-exclude-channel" multiple size="5">
</select>
</label>
<button type="submit">Sauvegarder</button>
<div id="status-autorole-vocal-form"></div>
</form>
<script>
@@ -107,6 +150,68 @@
"guild-name"
).textContent = `Dashboard : ${guild.name}`;
});
fetch(`/api/bot/get-text-channels/${guildId}`)
.then(res => res.json())
.then(channels => {
const selectWelcome = document.getElementById("welcome-channel");
const selectGoodbye = document.getElementById("goodbye-channel");
channels.forEach(channel => {
const option = document.createElement("option");
option.value = channel.id;
option.textContent = `#${channel.name}`;
selectWelcome.appendChild(option);
selectGoodbye.appendChild(option.cloneNode(true));
});
});
const selectExclude = document.getElementById("autorole-vocal-exclude-channel");
selectExclude.innerHTML = ""; // reset
fetch(`/api/bot/get-voice-channels/${guildId}`)
.then(res => res.json())
.then(channels => {
channels.forEach(channel => {
const option = document.createElement("option");
option.value = channel.id;
option.textContent = `#${channel.name}`;
selectExclude.appendChild(option);
});
return fetch(`/api/bot/get-autorole-vocal-config/${guildId}`);
})
.then(res => res.json())
.then(cfg => {
document.getElementById("autorole-vocal-enabled").checked = !!cfg.enabled;
document.getElementById("autorole-vocal-role").value = cfg.roleId ?? "";
const excluded = Array.isArray(cfg.excludeChannelIds)
? cfg.excludeChannelIds.map(String) // sécurité
: [];
Array.from(selectExclude.options).forEach(option => {
option.selected = excluded.includes(option.value);
});
})
.catch(console.error);
fetch(`/api/bot/get-roles/${guildId}`)
.then(res => res.json())
.then(roles => {
const selectAutorole = document.getElementById("autorole-role");
const selectAutoroleVocal = document.getElementById("autorole-vocal-role");
roles.forEach(role => {
const option = document.createElement("option");
option.value = role.id;
option.textContent = role.name;
selectAutorole.appendChild(option);
selectAutoroleVocal.appendChild(option.cloneNode(true));
});
});
const welcomeForm = document.getElementById("welcome-form");
@@ -159,20 +264,53 @@
});
fetch(`/api/bot/get-text-channels/${guildId}`)
.then(res => res.json())
.then(channels => {
const selectWelcome = document.getElementById("welcome-channel");
const selectGoodbye = document.getElementById("goodbye-channel");
channels.forEach(channel => {
const option = document.createElement("option");
option.value = channel.id;
option.textContent = `#${channel.name}`;
selectWelcome.appendChild(option);
selectGoodbye.appendChild(option.cloneNode(true));
});
const autoroleNewUserForm = document.getElementById("autorole-newuser-form");
autoroleNewUserForm.addEventListener("submit", async (e) => {
e.preventDefault();
const enabled = document.getElementById("autorole-enabled").checked;
const roleId = document.getElementById("autorole-role").value;
const res = await fetch("/api/bot/save-autorole-newuser-config", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
guildId,
roleId,
enabled,
}),
});
const data = await res.json();
document.getElementById("status-autorole-form").textContent = data.success
? "Config d'auto-rôle pour nouveaux membres sauvegardée ✅"
: "Erreur ❌";
});
const autoroleVocalForm = document.getElementById("autorole-vocal-form");
autoroleVocalForm.addEventListener("submit", async (e) => {
e.preventDefault();
const enabled = document.getElementById("autorole-vocal-enabled").checked;
const roleId = document.getElementById("autorole-vocal-role").value;
const excludeChannelSelect = document.getElementById("autorole-vocal-exclude-channel");
const excludeChannelId = Array.from(excludeChannelSelect.selectedOptions).map(option => option.value);
const res = await fetch("/api/bot/save-autorole-vocal-config", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
guildId,
roleId,
excludeChannelId,
enabled,
}),
});
const data = await res.json();
document.getElementById("status-autorole-vocal-form").textContent = data.success
? "Config d'auto-rôle pour membres en vocal sauvegardée ✅"
: "Erreur ❌";
});
fetch(`/api/bot/get-welcome-config/${guildId}`)
.then(res => res.json())
@@ -190,6 +328,16 @@
document.getElementById("goodbye-channel").value = cfg.channelId;
document.getElementById("goodbye-message").value = cfg.message;
});
fetch(`/api/bot/get-autorole-newuser-config/${guildId}`)
.then(res => res.json())
.then(cfg => {
document.getElementById("autorole-enabled").checked = cfg.enabled;
document.getElementById("autorole-role").value = cfg.roleId;
});
</script>
</body>
</html>
+1 -1
View File
@@ -13,7 +13,7 @@
<div id="profil">
<img id="avatar" src="" alt="Avatar">
<span id="username"></span>
<a id="logout" href="/logout">Se déconnecter</a>
<a id="logout" href="/auth/logout">Se déconnecter</a>
</div>
</nav>
<h1>LazyBot</h1>
+339
View File
@@ -0,0 +1,339 @@
const express = require("express");
const router = express.Router();
module.exports = (app, db, client) => {
// --- User info ---
router.get("/user", (req, res) => {
if (req.session.user) res.json(req.session.user);
else res.status(401).json({ error: "Utilisateur non connecté" });
});
router.get("/guilds", (req, res) => {
const userGuilds = req.session.guilds;
if (!userGuilds) return res.status(401).json({ error: "Utilisateur non connecté" });
const botGuildIds = client.guilds.cache.map(g => g.id);
const validGuilds = userGuilds.filter(g => {
const hasAdmin = (g.permissions & 0x8) === 0x8;
return hasAdmin && botGuildIds.includes(g.id);
});
res.json(validGuilds);
});
// API pour sauvegarder la configuration de bienvenue
router.post("/bot/save-welcome-config", express.json(), (req, res) => {
const { guildId, channelId, welcomeEnabled, welcomeMessage } = req.body;
if (!req.session.guilds) {
return res.status(401).json({ success: false });
}
const isAdmin = req.session.guilds.find(
g => g.id === guildId && (BigInt(g.permissions) & 0x8n) === 0x8n
);
if (!isAdmin) {
return res.status(403).json({ success: false });
}
db.run(
`
INSERT INTO welcome_config (guild_id, channel_id, enabled, message)
VALUES (?, ?, ?, ?)
ON CONFLICT(guild_id)
DO UPDATE SET channel_id = ?, enabled = ?, message = ?
`,
[
guildId,
channelId,
welcomeEnabled ? 1 : 0,
welcomeMessage,
channelId,
welcomeEnabled ? 1 : 0,
welcomeMessage
],
err => {
if (err) {
console.error(err);
return res.status(500).json({ success: false });
}
res.json({ success: true });
}
);
});
router.get("/bot/get-welcome-config/:guildId", (req, res) => {
const { guildId } = req.params;
db.get(
"SELECT enabled, channel_id, message FROM welcome_config WHERE guild_id = ?",
[guildId],
(err, row) => {
if (err || !row) {
return res.json({ enabled: false, channelId: null, message: "" });
}
res.json({
enabled: !!row.enabled,
channelId: row.channel_id,
message: row.message
});
}
);
});
router.post("/bot/save-goodbye-config", express.json(), (req, res) => {
const { guildId, channelId, goodbyeEnabled, goodbyeMessage } = req.body;
if (!req.session.guilds) {
return res.status(401).json({ success: false });
}
const isAdmin = req.session.guilds.find(
g => g.id === guildId && (BigInt(g.permissions) & 0x8n) === 0x8n
);
if (!isAdmin) {
return res.status(403).json({ success: false });
}
db.run(
`
INSERT INTO goodbye_config (guild_id, channel_id, enabled, message)
VALUES (?, ?, ?, ?)
ON CONFLICT(guild_id)
DO UPDATE SET channel_id = ?, enabled = ?, message = ?
`,
[
guildId,
channelId,
goodbyeEnabled ? 1 : 0,
goodbyeMessage,
channelId,
goodbyeEnabled ? 1 : 0,
goodbyeMessage
],
err => {
if (err) {
console.error(err);
return res.status(500).json({ success: false });
}
res.json({ success: true });
}
);
});
router.get("/bot/get-goodbye-config/:guildId", (req, res) => {
const { guildId } = req.params;
db.get(
"SELECT enabled, channel_id, message FROM goodbye_config WHERE guild_id = ?",
[guildId],
(err, row) => {
if (err || !row) {
return res.json({ enabled: false, channelId: null, message: "" });
}
res.json({
enabled: !!row.enabled,
channelId: row.channel_id,
message: row.message
});
}
);
});
router.post("/bot/save-autorole-newuser-config", express.json(), (req, res) => {
const { guildId, roleId, enabled } = req.body;
console.log("Received autorole-newuser config:", { guildId, roleId, enabled });
if (!req.session.guilds) {
return res.status(401).json({ success: false });
}
const isAdmin = req.session.guilds.find(
g => g.id === guildId && (BigInt(g.permissions) & 0x8n) === 0x8n
);
if (!isAdmin) {
return res.status(403).json({ success: false });
}
db.run(
`
INSERT INTO autorole_newuser_config (guild_id, role_id, enabled)
VALUES (?, ?, ?)
ON CONFLICT(guild_id)
DO UPDATE SET role_id = ?, enabled = ?
`,
[
guildId,
roleId,
enabled ? 1 : 0,
roleId,
enabled ? 1 : 0
],
err => {
if (err) {
console.error(err);
return res.status(500).json({ success: false });
}
res.json({ success: true });
}
);
});
router.get("/bot/get-autorole-newuser-config/:guildId", (req, res) => {
const { guildId } = req.params;
db.get(
"SELECT enabled, role_id FROM autorole_newuser_config WHERE guild_id = ?",
[guildId],
(err, row) => {
if (err || !row) {
return res.json({ enabled: false, roleId: null });
}
res.json({
enabled: !!row.enabled,
roleId: row.role_id
});
}
);
});
router.post("/bot/save-autorole-vocal-config", express.json(), (req, res) => {
const { guildId, roleId, excludeChannelId, enabled } = req.body;
if (!req.session.guilds) {
return res.status(401).json({ success: false });
}
const isAdmin = req.session.guilds.find(
g => g.id === guildId && (BigInt(g.permissions) & 0x8n) === 0x8n
);
if (!isAdmin) {
return res.status(403).json({ success: false });
}
const excludeChannelIdArray = Array.isArray(excludeChannelId) ? excludeChannelId : [excludeChannelId];
db.run(
`
INSERT INTO autorole_vocal_config (guild_id, role_id, exclude_channel_ids, enabled)
VALUES (?, ?, ?, ?)
ON CONFLICT(guild_id)
DO UPDATE SET role_id = ?, exclude_channel_ids = ?, enabled = ?
`,
[
guildId,
roleId,
JSON.stringify(excludeChannelIdArray),
enabled ? 1 : 0,
roleId,
JSON.stringify(excludeChannelIdArray),
enabled ? 1 : 0
],
err => {
if (err) {
console.error(err);
return res.status(500).json({ success: false });
}
res.json({ success: true });
}
);
});
router.get("/bot/get-autorole-vocal-config/:guildId", (req, res) => {
const { guildId } = req.params;
db.get(
"SELECT enabled, role_id, exclude_channel_ids FROM autorole_vocal_config WHERE guild_id = ?",
[guildId],
(err, row) => {
if (err || !row) {
return res.json({ enabled: false, roleId: null });
}
res.json({
enabled: !!row.enabled,
roleId: row.role_id,
excludeChannelIds: JSON.parse(row.exclude_channel_ids),
});
}
);
});
router.get("/bot/get-text-channels/:guildId", (req, res) => {
const { guildId } = req.params;
const guild = client.guilds.cache.get(guildId);
if (!guild) {
return res.status(404).json({ error: "Serveur non trouvé" });
}
const channels = guild.channels.cache
.filter(channel => channel.isTextBased())
.map(channel => ({
id: channel.id,
name: channel.name
}));
res.json(channels);
});
router.get("/bot/get-voice-channels/:guildId", (req, res) => {
const { guildId } = req.params;
const guild = client.guilds.cache.get(guildId);
if (!guild) {
return res.status(404).json({ error: "Serveur non trouvé" });
}
const channels = guild.channels.cache
.filter(channel => channel.isVoiceBased())
.map(channel => ({
id: channel.id,
name: channel.name
}));
res.json(channels);
});
router.get("/bot/get-roles/:guildId", (req, res) => {
const { guildId } = req.params;
const guild = client.guilds.cache.get(guildId);
if (!guild) {
return res.status(404).json({ error: "Serveur non trouvé" });
}
const botMember = guild.members.cache.get(client.user.id);
if (!botMember) return res.status(500).json({ error: "Bot non trouvé dans ce serveur" });
const botRolePos = botMember.roles.highest.position;
// On filtre :
// - rôle sous le plus haut rôle du bot
// - pas @everyone
// - pas managed (roles de bot/intégrations)
const roles = guild.roles.cache
.filter(role =>
role.position < botRolePos &&
role.name !== "@everyone" &&
role.managed === false
)
.map(role => ({
id: role.id,
name: role.name
}));
res.json(roles);
});
app.use("/api", router);
};
+65
View File
@@ -0,0 +1,65 @@
const express = require("express");
const fetch = require("cross-fetch");
const router = express.Router();
const path = require("path");
const CLIENT_ID = process.env.CLIENT_ID;
const CLIENT_SECRET = process.env.CLIENT_SECRET;
const REDIRECT_URI = process.env.REDIRECT_URI;
module.exports = (app, db, client) => {
// --- Connexion Discord ---
router.get("/discord", (req, res) => {
const url = `https://discord.com/api/oauth2/authorize?client_id=${CLIENT_ID}&redirect_uri=${encodeURIComponent(REDIRECT_URI)}&response_type=code&scope=identify%20guilds`;
res.redirect(url);
});
router.get("/discord/callback", async (req, res) => {
const code = req.query.code;
if (!code) return res.send("Pas de code OAuth reçu !");
try {
const data = new URLSearchParams();
data.append("client_id", CLIENT_ID);
data.append("client_secret", CLIENT_SECRET);
data.append("grant_type", "authorization_code");
data.append("code", code);
data.append("redirect_uri", REDIRECT_URI);
data.append("scope", "identify");
const tokenResponse = await fetch("https://discord.com/api/oauth2/token", {
method: "POST",
body: data,
headers: { "Content-Type": "application/x-www-form-urlencoded" },
});
const tokenJson = await tokenResponse.json();
const accessToken = tokenJson.access_token;
const userResponse = await fetch("https://discord.com/api/users/@me", {
headers: { Authorization: `Bearer ${accessToken}` },
});
const user = await userResponse.json();
const guildsResponse = await fetch("https://discord.com/api/users/@me/guilds", {
headers: { Authorization: `Bearer ${accessToken}` },
});
const guilds = await guildsResponse.json();
req.session.user = user;
req.session.guilds = guilds;
res.redirect("/dashboard");
} catch (err) {
console.error(err);
res.send("Erreur lors de la connexion Discord !");
}
});
router.get("/logout", (req, res) => {
req.session.destroy();
res.redirect("/");
});
app.use("/auth", router);
};
+4 -234
View File
@@ -31,94 +31,9 @@ app.use(session({
// --- Servir le dossier public ---
app.use(express.static(path.join(__dirname, "public")));
// --- Route pour démarrer la connexion Discord ---
app.get("/auth/discord", (req, res) => {
const url = `https://discord.com/api/oauth2/authorize?client_id=${CLIENT_ID}&redirect_uri=${encodeURIComponent(REDIRECT_URI)}&response_type=code&scope=identify%20guilds`;
res.redirect(url);
});
// --- Callback après connexion Discord ---
app.get("/auth/discord/callback", async (req, res) => {
const code = req.query.code;
if (!code) return res.send("Pas de code OAuth reçu !");
try {
// Échange du code contre access token
const data = new URLSearchParams();
data.append("client_id", CLIENT_ID);
data.append("client_secret", CLIENT_SECRET);
data.append("grant_type", "authorization_code");
data.append("code", code);
data.append("redirect_uri", REDIRECT_URI);
data.append("scope", "identify");
const tokenResponse = await fetch("https://discord.com/api/oauth2/token", {
method: "POST",
body: data,
headers: { "Content-Type": "application/x-www-form-urlencoded" },
});
const tokenJson = await tokenResponse.json();
const accessToken = tokenJson.access_token;
// Récupération des infos utilisateur
const userResponse = await fetch("https://discord.com/api/users/@me", {
headers: { Authorization: `Bearer ${accessToken}` },
});
const user = await userResponse.json();
// Récupérer la liste des guilds
const guildsResponse = await fetch("https://discord.com/api/users/@me/guilds", {
headers: { Authorization: `Bearer ${accessToken}` },
});
const guilds = await guildsResponse.json();
// Stocker l'utilisateur dans la session
req.session.user = user;
req.session.guilds = guilds;
// Rediriger vers la page HTML
res.redirect("/dashboard");
} catch (err) {
console.error(err);
res.send("Erreur lors de la connexion Discord !");
}
});
app.get("/logout", (req, res) => {
req.session.destroy();
res.redirect("/");
});
// --- API pour récupérer l'objet user côté front ---
app.get("/api/user", (req, res) => {
if (req.session.user) {
res.json(req.session.user);
} else {
res.status(401).json({ error: "Utilisateur non connecté" });
}
});
app.get("/api/guilds", (req, res) => {
const userGuilds = req.session.guilds; // toutes les guilds de l'utilisateur
if (!userGuilds) return res.status(401).json({ error: "Utilisateur non connecté" });
// Liste des guilds où le bot est présent
const botGuildIds = client.guilds.cache.map(g => g.id);
// Filtrer : bot présent + admin
const validGuilds = userGuilds.filter(g => {
const hasAdmin = (g.permissions & 0x8) === 0x8; // flag admin
const botHere = botGuildIds.includes(g.id);
return hasAdmin && botHere;
});
res.json(validGuilds);
});
// --- Routes ---
require("./routes/auth")(app, db, client);
require("./routes/api")(app, db, client);
app.get("/invite-bot", (req, res) => {
const permissions = 8; // Permissions administrateur
@@ -142,7 +57,6 @@ app.get("/invite-bot", (req, res) => {
res.json({ url });
});
// Servir le dashboard par serveur
app.get("/guild/:guildId", (req, res) => {
const guildId = req.params.guildId;
@@ -159,150 +73,6 @@ app.get("/guild/:guildId", (req, res) => {
res.sendFile(path.join(__dirname, "public", "guild.html"));
});
// API pour sauvegarder la configuration de bienvenue
app.post("/api/bot/save-welcome-config", express.json(), (req, res) => {
const { guildId, channelId, welcomeEnabled, welcomeMessage } = req.body;
if (!req.session.guilds) {
return res.status(401).json({ success: false });
}
const isAdmin = req.session.guilds.find(
g => g.id === guildId && (BigInt(g.permissions) & 0x8n) === 0x8n
);
if (!isAdmin) {
return res.status(403).json({ success: false });
}
db.run(
`
INSERT INTO welcome_config (guild_id, channel_id, enabled, message)
VALUES (?, ?, ?, ?)
ON CONFLICT(guild_id)
DO UPDATE SET channel_id = ?, enabled = ?, message = ?
`,
[
guildId,
channelId,
welcomeEnabled ? 1 : 0,
welcomeMessage,
channelId,
welcomeEnabled ? 1 : 0,
welcomeMessage
],
err => {
if (err) {
console.error(err);
return res.status(500).json({ success: false });
}
res.json({ success: true });
}
);
});
app.get("/api/bot/get-welcome-config/:guildId", (req, res) => {
const { guildId } = req.params;
db.get(
"SELECT enabled, channel_id, message FROM welcome_config WHERE guild_id = ?",
[guildId],
(err, row) => {
if (err || !row) {
return res.json({ enabled: false, channelId: null, message: "" });
}
res.json({
enabled: !!row.enabled,
channelId: row.channel_id,
message: row.message
});
}
);
});
app.post("/api/bot/save-goodbye-config", express.json(), (req, res) => {
const { guildId, channelId, goodbyeEnabled, goodbyeMessage } = req.body;
if (!req.session.guilds) {
return res.status(401).json({ success: false });
}
const isAdmin = req.session.guilds.find(
g => g.id === guildId && (BigInt(g.permissions) & 0x8n) === 0x8n
);
if (!isAdmin) {
return res.status(403).json({ success: false });
}
db.run(
`
INSERT INTO goodbye_config (guild_id, channel_id, enabled, message)
VALUES (?, ?, ?, ?)
ON CONFLICT(guild_id)
DO UPDATE SET channel_id = ?, enabled = ?, message = ?
`,
[
guildId,
channelId,
goodbyeEnabled ? 1 : 0,
goodbyeMessage,
channelId,
goodbyeEnabled ? 1 : 0,
goodbyeMessage
],
err => {
if (err) {
console.error(err);
return res.status(500).json({ success: false });
}
res.json({ success: true });
}
);
});
app.get("/api/bot/get-goodbye-config/:guildId", (req, res) => {
const { guildId } = req.params;
db.get(
"SELECT enabled, channel_id, message FROM goodbye_config WHERE guild_id = ?",
[guildId],
(err, row) => {
if (err || !row) {
return res.json({ enabled: false, channelId: null, message: "" });
}
res.json({
enabled: !!row.enabled,
channelId: row.channel_id,
message: row.message
});
}
);
});
app.get("/api/bot/get-text-channels/:guildId", (req, res) => {
const { guildId } = req.params;
const guild = client.guilds.cache.get(guildId);
if (!guild) {
return res.status(404).json({ error: "Serveur non trouvé" });
}
const channels = guild.channels.cache
.filter(channel => channel.isTextBased())
.map(channel => ({
id: channel.id,
name: channel.name
}));
res.json(channels);
});
app.get("/dashboard", (req, res) => {
if (!req.session.user) {
return res.redirect("/auth/discord");
@@ -313,4 +83,4 @@ app.get("/dashboard", (req, res) => {
// --- Lancement du serveur ---
app.listen(PORT, () => console.log(`Serveur lancé sur http://localhost:${PORT}`));
app.listen(PORT, () => console.log(`Serveur lancé sur http://localhost:${PORT}`));