update Oauth discord & add good bye message

This commit is contained in:
Arthur Puechberty
2026-01-15 20:23:06 +01:00
parent 12fde58b93
commit 87e339c75b
6 changed files with 370 additions and 160 deletions
+22
View File
@@ -45,6 +45,28 @@ client.on(Events.GuildMemberAdd, member => {
}); });
client.on(Events.GuildMemberRemove, member => {
db.get(
"SELECT enabled, channel_id, message FROM goodbye_config WHERE guild_id = ?",
[member.guild.id],
(err, row) => {
if (err || !row || !row.enabled) return;
let msg = row.message;
msg = msg
.replace("{user}", member.user.username)
.replace("{server}", member.guild.name);
const channel = member.guild.channels.cache.get(row.channel_id);
if (channel) {
channel.send(msg);
}
}
);
});
client.login(process.env.BOT_TOKEN); client.login(process.env.BOT_TOKEN);
module.exports = client; module.exports = client;
+9 -2
View File
@@ -10,13 +10,20 @@ const db = new sqlite3.Database(
); );
// Création de la table si elle n'existe pas // Création de la table si elle n'existe pas
db.run(` db.exec(`
CREATE TABLE IF NOT EXISTS welcome_config ( CREATE TABLE IF NOT EXISTS welcome_config (
guild_id TEXT PRIMARY KEY, guild_id TEXT PRIMARY KEY,
channel_id TEXT, channel_id TEXT,
enabled INTEGER NOT NULL, enabled INTEGER NOT NULL,
message TEXT NOT NULL message TEXT NOT NULL
) );
CREATE TABLE IF NOT EXISTS goodbye_config (
guild_id TEXT PRIMARY KEY,
channel_id TEXT,
enabled INTEGER NOT NULL,
message TEXT NOT NULL
);
`); `);
module.exports = db; module.exports = db;
@@ -1,9 +1,13 @@
<!DOCTYPE html> <!DOCTYPE html>
<html> <html>
<head> <head>
<title>Bienvenue</title> <title>Tableau de bord</title>
</head> </head>
<body> <body>
<nav>
<a href="/">Accueil</a>
</nav>
<h1 id="greeting">Chargement...</h1> <h1 id="greeting">Chargement...</h1>
<img id="avatar" src="" alt="Avatar"> <img id="avatar" src="" alt="Avatar">
@@ -24,6 +28,7 @@
document.getElementById("greeting").textContent = "Utilisateur non connecté."; document.getElementById("greeting").textContent = "Utilisateur non connecté.";
}); });
// --- Affichage des guilds de l'utilisateur --- // --- Affichage des guilds de l'utilisateur ---
fetch("/api/guilds") fetch("/api/guilds")
.then(res => res.json()) .then(res => res.json())
@@ -51,6 +56,7 @@
document.getElementById("guilds-list").innerHTML = "<li>Impossible de récupérer les guilds.</li>"; document.getElementById("guilds-list").innerHTML = "<li>Impossible de récupérer les guilds.</li>";
}); });
fetch("/invite-bot") fetch("/invite-bot")
.then(res => res.json()) .then(res => res.json())
.then(data => { .then(data => {
+120 -45
View File
@@ -4,16 +4,20 @@
<title>Dashboard du serveur</title> <title>Dashboard du serveur</title>
</head> </head>
<body> <body>
<nav>
<a href="/">Accueil</a>
<a href="/dashboard">Tableau de bord</a>
</nav>
<h1 id="guild-name">Chargement...</h1> <h1 id="guild-name">Chargement...</h1>
<form id="welcome-form"> <form id="welcome-form">
<label> <label>
<input type="checkbox" id="welcome-enabled" /> <input type="checkbox" id="welcome-enabled" />
Activer le message de bienvenue Activer le message de bienvenue
</label> </label>
<br /><br />
<label> <label>
Canal de bienvenue : Canal de bienvenue :
<br /> <br />
@@ -21,8 +25,6 @@
</select> </select>
</label> </label>
<br /><br />
<label> <label>
Message : Message :
<br /> <br />
@@ -34,8 +36,6 @@
></textarea> ></textarea>
</label> </label>
<br /><br />
<small> <small>
Variables disponibles : Variables disponibles :
<ul> <ul>
@@ -46,9 +46,46 @@
</small> </small>
<button type="submit">Sauvegarder</button> <button type="submit">Sauvegarder</button>
<div id="status-welcome-form"></div>
</form>
<form id="goodbye-form">
<label>
<input type="checkbox" id="goodbye-enabled" />
Activer le message d'au revoir
</label>
<label>
Canal d'au revoir :
<br />
<select id="goodbye-channel">
</select>
</label>
<label>
Message :
<br />
<textarea
id="goodbye-message"
rows="4"
cols="50"
placeholder="Ex : Au revoir {user}, on espère te revoir sur {server} 👋"
></textarea>
</label>
<small>
Variables disponibles :
<ul>
<li><code>{user}</code> → nom de l'utilisateur</li>
<li><code>{server}</code> → nom du serveur</li>
</ul>
</small>
<button type="submit">Sauvegarder</button>
<div id="status-goodbye-form"></div>
</form> </form>
<div id="status"></div>
<script> <script>
const guildId = window.location.pathname.split("/")[2]; // récupère l'ID du serveur const guildId = window.location.pathname.split("/")[2]; // récupère l'ID du serveur
@@ -69,49 +106,87 @@
}); });
const welcomeForm = document.getElementById("welcome-form"); const welcomeForm = document.getElementById("welcome-form");
welcomeForm.addEventListener("submit", async (e) => { welcomeForm.addEventListener("submit", async (e) => {
e.preventDefault(); e.preventDefault();
const enabled = document.getElementById("welcome-enabled").checked; const enabled = document.getElementById("welcome-enabled").checked;
const channelId = document.getElementById("welcome-channel").value; const channelId = document.getElementById("welcome-channel").value;
const message = document.getElementById("welcome-message").value; const message = document.getElementById("welcome-message").value;
const res = await fetch("/api/bot/save-welcome-config", { const res = await fetch("/api/bot/save-welcome-config", {
method: "POST", method: "POST",
headers: { "Content-Type": "application/json" }, headers: { "Content-Type": "application/json" },
body: JSON.stringify({ body: JSON.stringify({
guildId, guildId,
channelId, channelId,
welcomeMessage: message, welcomeMessage: message,
welcomeEnabled: enabled, welcomeEnabled: enabled,
}), }),
});
const data = await res.json();
document.getElementById("status").textContent = data.success
? "Config de bienvenue sauvegardée ✅"
: "Erreur ❌";
}); });
fetch(`/api/bot/get-text-channels/${guildId}`) const data = await res.json();
.then(res => res.json()) document.getElementById("status-welcome-form").textContent = data.success
.then(channels => { ? "Config de bienvenue sauvegardée ✅"
const select = document.getElementById("welcome-channel"); : "Erreur ❌";
channels.forEach(channel => { });
const option = document.createElement("option");
option.value = channel.id;
option.textContent = `#${channel.name}`;
select.appendChild(option);
});
});
fetch(`/api/bot/get-welcome-config/${guildId}`)
.then(res => res.json()) const goodbyeForm = document.getElementById("goodbye-form");
.then(cfg => { goodbyeForm.addEventListener("submit", async (e) => {
document.getElementById("welcome-enabled").checked = cfg.enabled; e.preventDefault();
document.getElementById("welcome-channel").value = cfg.channelId; const enabled = document.getElementById("goodbye-enabled").checked;
document.getElementById("welcome-message").value = cfg.message; const channelId = document.getElementById("goodbye-channel").value;
const message = document.getElementById("goodbye-message").value;
const res = await fetch("/api/bot/save-goodbye-config", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
guildId,
channelId,
goodbyeMessage: message,
goodbyeEnabled: enabled,
}),
});
const data = await res.json();
document.getElementById("status-goodbye-form").textContent = data.success
? "Config d'au revoir sauvegardée ✅"
: "Erreur ❌";
});
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));
}); });
});
fetch(`/api/bot/get-welcome-config/${guildId}`)
.then(res => res.json())
.then(cfg => {
document.getElementById("welcome-enabled").checked = cfg.enabled;
document.getElementById("welcome-channel").value = cfg.channelId;
document.getElementById("welcome-message").value = cfg.message;
});
fetch(`/api/bot/get-goodbye-config/${guildId}`)
.then(res => res.json())
.then(cfg => {
document.getElementById("goodbye-enabled").checked = cfg.enabled;
document.getElementById("goodbye-channel").value = cfg.channelId;
document.getElementById("goodbye-message").value = cfg.message;
});
</script> </script>
</body> </body>
</html> </html>
+18 -5
View File
@@ -1,12 +1,25 @@
<!DOCTYPE html> <!DOCTYPE html>
<html> <html>
<head> <head>
<title>Connexion Discord</title> <title>LazyBot - Bot Discord</title>
</head> </head>
<body> <body>
<h1>Bienvenue !</h1> <nav>
<a href="/auth/discord"> <a href="/">Accueil</a>
<button>Se connecter avec Discord</button> <a href="/dashboard">Tableau de bord</a>
</a> </nav>
<h1>LazyBot</h1>
<a id="invite-link" href="#">Ajouter à Discord</a>
</body> </body>
<script>
fetch("/invite-bot")
.then(res => res.json())
.then(data => {
const link = document.getElementById("invite-link");
link.href = data.url; // met le lien dynamique
})
.catch(() => {
console.log("Impossible de récupérer le lien du bot.");
});
</script>
</html> </html>
+194 -107
View File
@@ -75,7 +75,7 @@ app.get("/auth/discord/callback", async (req, res) => {
req.session.guilds = guilds; req.session.guilds = guilds;
// Rediriger vers la page HTML // Rediriger vers la page HTML
res.redirect("/welcome.html"); res.redirect("/dashboard");
} catch (err) { } catch (err) {
console.error(err); console.error(err);
res.send("Erreur lors de la connexion Discord !"); res.send("Erreur lors de la connexion Discord !");
@@ -91,6 +91,7 @@ app.get("/api/user", (req, res) => {
} }
}); });
app.get("/api/guilds", (req, res) => { app.get("/api/guilds", (req, res) => {
const userGuilds = req.session.guilds; // toutes les guilds de l'utilisateur const userGuilds = req.session.guilds; // toutes les guilds de l'utilisateur
if (!userGuilds) return res.status(401).json({ error: "Utilisateur non connecté" }); if (!userGuilds) return res.status(401).json({ error: "Utilisateur non connecté" });
@@ -105,115 +106,201 @@ app.get("/api/guilds", (req, res) => {
return hasAdmin && botHere; return hasAdmin && botHere;
}); });
app.get("/invite-bot", (req, res) => {
const clientId = process.env.CLIENT_ID;
const redirectUri = encodeURIComponent(process.env.REDIRECT_URI);
const permissions = 8; // Permissions administrateur
const scope = encodeURIComponent("bot guilds applications.commands");
const url = `https://discord.com/oauth2/authorize?client_id=${clientId}&permissions=${permissions}&scope=${scope}&redirect_uri=${redirectUri}&response_type=code`;
// Tu peux juste renvoyer le lien
res.json({ url });
});
// Servir le dashboard par serveur
app.get("/guild/:guildId", (req, res) => {
const guildId = req.params.guildId;
const userGuilds = req.session.guilds;
// Vérifie que l'utilisateur est connecté et a admin sur ce serveur
if (!userGuilds) return res.redirect("/"); // ou une page de connexion
const guildValid = userGuilds.find(
g => g.id === guildId && (BigInt(g.permissions) & 0x8n) === 0x8n
);
if (!guildValid) return res.send("Accès interdit : vous n'êtes pas admin sur ce serveur.");
// Redirige vers la page HTML statique du dashboard
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.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);
});
res.json(validGuilds); res.json(validGuilds);
}); });
app.get("/invite-bot", (req, res) => {
const permissions = 8; // Permissions administrateur
const scopes = [
"bot",
"applications.commands",
"identify",
"guilds"
].join(" ");
const url =
"https://discord.com/oauth2/authorize" +
`?client_id=${CLIENT_ID}` +
`&redirect_uri=${encodeURIComponent(REDIRECT_URI)}` +
"&response_type=code" +
`&scope=${encodeURIComponent(scopes)}` +
`&permissions=${permissions}`;
// Tu peux juste renvoyer le lien
res.json({ url });
});
// Servir le dashboard par serveur
app.get("/guild/:guildId", (req, res) => {
const guildId = req.params.guildId;
const userGuilds = req.session.guilds;
// Vérifie que l'utilisateur est connecté et a admin sur ce serveur
if (!userGuilds) return res.redirect("/auth/discord"); // ou une page de connexion
const guildValid = userGuilds.find(
g => g.id === guildId && (BigInt(g.permissions) & 0x8n) === 0x8n
);
if (!guildValid) return res.send("Accès interdit : vous n'êtes pas admin sur ce serveur.");
// Redirige vers la page HTML statique du dashboard
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");
}
res.sendFile(path.join(__dirname, "public", "dashboard.html"));
});
// --- Lancement du serveur --- // --- 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}`));