112 lines
3.4 KiB
JavaScript
112 lines
3.4 KiB
JavaScript
import { Client, GatewayIntentBits } from "discord.js";
|
||
import fetch from "node-fetch";
|
||
|
||
const DISCORD_TOKEN = process.env.DISCORD_TOKEN;
|
||
const N8N_WEBHOOK = process.env.N8N_WEBHOOK;
|
||
|
||
if (!DISCORD_TOKEN) {
|
||
console.error("❌ DISCORD_TOKEN is missing. Set the env var DISCORD_TOKEN.");
|
||
process.exit(1);
|
||
}
|
||
if (!N8N_WEBHOOK) {
|
||
console.error("❌ N8N_WEBHOOK is missing. Set the env var N8N_WEBHOOK.");
|
||
process.exit(1);
|
||
}
|
||
|
||
const client = new Client({
|
||
intents: [
|
||
GatewayIntentBits.Guilds,
|
||
GatewayIntentBits.GuildMessages,
|
||
GatewayIntentBits.MessageContent
|
||
]
|
||
});
|
||
|
||
client.once("ready", () => {
|
||
console.log(`✅ Ready! Logged in as ${client.user.tag}`);
|
||
});
|
||
|
||
client.on("messageCreate", async (message) => {
|
||
try {
|
||
if (message.author.bot) return;
|
||
console.log(`📩 Message from ${message.author.tag} in ${message.guild ? message.guild.name : "DM"}: ${message.content}`);
|
||
|
||
// envoi vers n8n
|
||
const res = await fetch(N8N_WEBHOOK, {
|
||
method: "POST",
|
||
headers: { "Content-Type": "application/json" },
|
||
body: JSON.stringify({ text: message.content, user: message.author.username })
|
||
});
|
||
|
||
const rawText = await res.text(); // récup brut
|
||
console.log("↩️ n8n response raw:", rawText);
|
||
|
||
let data;
|
||
try {
|
||
// cas 1 : réponse directement en JSON
|
||
data = JSON.parse(rawText);
|
||
} catch {
|
||
// cas 2 : n8n a renvoyé du texte avec JSON dedans
|
||
const jsonMatch = rawText.match(/```json([\s\S]*?)```/i) || rawText.match(/{[\s\S]*}/);
|
||
if (jsonMatch) {
|
||
try {
|
||
data = JSON.parse(jsonMatch[1] || jsonMatch[0]);
|
||
} catch (e) {
|
||
console.warn("⚠️ Impossible de parser le JSON extrait :", e);
|
||
}
|
||
}
|
||
}
|
||
|
||
// fallback si rien de parsé
|
||
if (!data) {
|
||
data = { reply: rawText.trim() }; // au moins répondre avec le texte brut
|
||
}
|
||
|
||
// nettoyer le champ reply si présent
|
||
if (data.reply) {
|
||
data.reply = data.reply
|
||
.replace(/```[\s\S]*?```/g, "") // supprime blocs de code
|
||
.replace(/\\n/g, "\n") // normalise retours ligne
|
||
.trim();
|
||
}
|
||
|
||
// === Envoi de la réponse ===
|
||
if (data.reply) {
|
||
await message.reply(data.reply);
|
||
} else {
|
||
await message.reply("⚠️ Sire, je n’ai point reçu de réponse de l’oracle n8n !");
|
||
}
|
||
|
||
// === Si action clear_channel demandée ===
|
||
if (data.action === "clear_channel" && data.channel_id && Array.isArray(data.messages_to_delete)) {
|
||
const channel = await client.channels.fetch(data.channel_id);
|
||
if (channel && channel.isTextBased()) {
|
||
for (const msgId of data.messages_to_delete) {
|
||
try {
|
||
const msg = await channel.messages.fetch(msgId);
|
||
if (msg) await msg.delete();
|
||
} catch (err) {
|
||
console.error(`❌ Failed to delete message ${msgId}:`, err);
|
||
}
|
||
}
|
||
console.log(`✅ Deleted ${data.messages_to_delete.length} messages in ${channel.id}`);
|
||
}
|
||
}
|
||
} catch (err) {
|
||
console.error("🔴 Error in message handler:", err);
|
||
await message.reply("⚠️ Sire, une erreur est survenue lors de ma consultation de n8n !");
|
||
}
|
||
});
|
||
|
||
process.on("unhandledRejection", (r) => {
|
||
console.error("UnhandledRejection:", r);
|
||
});
|
||
process.on("uncaughtException", (err) => {
|
||
console.error("UncaughtException:", err);
|
||
process.exit(1);
|
||
});
|
||
|
||
client.login(DISCORD_TOKEN).catch(err => {
|
||
console.error("Failed to login to Discord:", err);
|
||
process.exit(1);
|
||
});
|