Spaces:
Sleeping
Sleeping
Merge branch 'main' into backend-setup
Browse files
index.js
CHANGED
|
@@ -8,7 +8,8 @@ import {
|
|
| 8 |
ModalBuilder,
|
| 9 |
TextInputBuilder,
|
| 10 |
TextInputStyle,
|
| 11 |
-
ActionRowBuilder
|
|
|
|
| 12 |
} from "discord.js";
|
| 13 |
|
| 14 |
const client = new Client({
|
|
@@ -19,6 +20,8 @@ const client = new Client({
|
|
| 19 |
],
|
| 20 |
});
|
| 21 |
|
|
|
|
|
|
|
| 22 |
client.once(Events.ClientReady, async () => {
|
| 23 |
console.log(`Bot ready: ${client.user.tag}`);
|
| 24 |
|
|
@@ -26,7 +29,7 @@ client.once(Events.ClientReady, async () => {
|
|
| 26 |
await client.application.commands.set([
|
| 27 |
{
|
| 28 |
name: "detect",
|
| 29 |
-
description: "Otwiera okienko do wklejenia linku lub tekstu",
|
| 30 |
},
|
| 31 |
]);
|
| 32 |
console.log("Pomyślnie zarejestrowano komendę /detect");
|
|
@@ -35,21 +38,63 @@ client.once(Events.ClientReady, async () => {
|
|
| 35 |
}
|
| 36 |
});
|
| 37 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 38 |
client.on(Events.InteractionCreate, async (interaction) => {
|
| 39 |
-
|
| 40 |
if (interaction.isChatInputCommand()) {
|
| 41 |
if (interaction.commandName === "detect") {
|
| 42 |
-
|
| 43 |
const modal = new ModalBuilder()
|
| 44 |
.setCustomId("detectModal")
|
| 45 |
-
.setTitle("Detektor
|
| 46 |
|
| 47 |
const textInput = new TextInputBuilder()
|
| 48 |
.setCustomId("detectInput")
|
| 49 |
-
.setLabel("Wklej tutaj
|
| 50 |
-
.setStyle(TextInputStyle.Paragraph)
|
| 51 |
.setPlaceholder("Wklej zawartość...")
|
| 52 |
.setRequired(true);
|
|
|
|
| 53 |
const actionRow = new ActionRowBuilder().addComponents(textInput);
|
| 54 |
modal.addComponents(actionRow);
|
| 55 |
|
|
@@ -61,12 +106,61 @@ client.on(Events.InteractionCreate, async (interaction) => {
|
|
| 61 |
if (interaction.customId === "detectModal") {
|
| 62 |
const userContent = interaction.fields.getTextInputValue("detectInput");
|
| 63 |
|
| 64 |
-
await interaction.
|
| 65 |
-
|
| 66 |
-
|
| 67 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 68 |
|
| 69 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 70 |
}
|
| 71 |
}
|
| 72 |
});
|
|
|
|
| 8 |
ModalBuilder,
|
| 9 |
TextInputBuilder,
|
| 10 |
TextInputStyle,
|
| 11 |
+
ActionRowBuilder,
|
| 12 |
+
MessageFlags
|
| 13 |
} from "discord.js";
|
| 14 |
|
| 15 |
const client = new Client({
|
|
|
|
| 20 |
],
|
| 21 |
});
|
| 22 |
|
| 23 |
+
const API_URL = process.env.API_URL || "http://127.0.0.1:8000";
|
| 24 |
+
|
| 25 |
client.once(Events.ClientReady, async () => {
|
| 26 |
console.log(`Bot ready: ${client.user.tag}`);
|
| 27 |
|
|
|
|
| 29 |
await client.application.commands.set([
|
| 30 |
{
|
| 31 |
name: "detect",
|
| 32 |
+
description: "Otwiera okienko do wklejenia linku lub tekstu do analizy",
|
| 33 |
},
|
| 34 |
]);
|
| 35 |
console.log("Pomyślnie zarejestrowano komendę /detect");
|
|
|
|
| 38 |
}
|
| 39 |
});
|
| 40 |
|
| 41 |
+
function preparePayload(input) {
|
| 42 |
+
const trimmed = input.trim();
|
| 43 |
+
const isUrl = trimmed.startsWith("http://") || trimmed.startsWith("https://");
|
| 44 |
+
|
| 45 |
+
if (isUrl) {
|
| 46 |
+
const lowerUrl = trimmed.toLowerCase();
|
| 47 |
+
|
| 48 |
+
if (lowerUrl.endsWith(".png") || lowerUrl.endsWith(".jpg") || lowerUrl.endsWith(".jpeg") || lowerUrl.endsWith(".webp") || lowerUrl.endsWith(".gif")) {
|
| 49 |
+
return {
|
| 50 |
+
type: "image",
|
| 51 |
+
payload: {
|
| 52 |
+
image_url: trimmed,
|
| 53 |
+
content_type: "image"
|
| 54 |
+
}
|
| 55 |
+
};
|
| 56 |
+
} else if (lowerUrl.endsWith(".mp4") || lowerUrl.endsWith(".webm") || lowerUrl.endsWith(".mov") || lowerUrl.endsWith(".avi")) {
|
| 57 |
+
return {
|
| 58 |
+
type: "video",
|
| 59 |
+
payload: {
|
| 60 |
+
video_url: trimmed,
|
| 61 |
+
content_type: "video"
|
| 62 |
+
}
|
| 63 |
+
};
|
| 64 |
+
} else {
|
| 65 |
+
return {
|
| 66 |
+
type: "file",
|
| 67 |
+
payload: {
|
| 68 |
+
file_url: trimmed,
|
| 69 |
+
content_type: "file"
|
| 70 |
+
}
|
| 71 |
+
};
|
| 72 |
+
}
|
| 73 |
+
}
|
| 74 |
+
|
| 75 |
+
return {
|
| 76 |
+
type: "text",
|
| 77 |
+
payload: {
|
| 78 |
+
text: trimmed,
|
| 79 |
+
content_type: "text"
|
| 80 |
+
}
|
| 81 |
+
};
|
| 82 |
+
}
|
| 83 |
+
|
| 84 |
client.on(Events.InteractionCreate, async (interaction) => {
|
|
|
|
| 85 |
if (interaction.isChatInputCommand()) {
|
| 86 |
if (interaction.commandName === "detect") {
|
|
|
|
| 87 |
const modal = new ModalBuilder()
|
| 88 |
.setCustomId("detectModal")
|
| 89 |
+
.setTitle("Detektor Deepfake");
|
| 90 |
|
| 91 |
const textInput = new TextInputBuilder()
|
| 92 |
.setCustomId("detectInput")
|
| 93 |
+
.setLabel("Wklej tutaj tekst lub link (obraz/wideo):")
|
| 94 |
+
.setStyle(TextInputStyle.Paragraph)
|
| 95 |
.setPlaceholder("Wklej zawartość...")
|
| 96 |
.setRequired(true);
|
| 97 |
+
|
| 98 |
const actionRow = new ActionRowBuilder().addComponents(textInput);
|
| 99 |
modal.addComponents(actionRow);
|
| 100 |
|
|
|
|
| 106 |
if (interaction.customId === "detectModal") {
|
| 107 |
const userContent = interaction.fields.getTextInputValue("detectInput");
|
| 108 |
|
| 109 |
+
await interaction.deferReply({ flags: [MessageFlags.Ephemeral] });
|
| 110 |
+
|
| 111 |
+
try {
|
| 112 |
+
const { type, payload } = preparePayload(userContent);
|
| 113 |
+
|
| 114 |
+
console.log(`Wysyłanie zapytania typu: ${type} do API...`);
|
| 115 |
+
|
| 116 |
+
const response = await fetch(`${API_URL}/analyze`, {
|
| 117 |
+
method: "POST",
|
| 118 |
+
headers: {
|
| 119 |
+
"Content-Type": "application/json",
|
| 120 |
+
},
|
| 121 |
+
body: JSON.stringify(payload),
|
| 122 |
+
});
|
| 123 |
+
|
| 124 |
+
if (!response.ok) {
|
| 125 |
+
const errorData = await response.json().catch(() => ({}));
|
| 126 |
+
console.error("Szczegóły błędu z FastAPI:", JSON.stringify(errorData, null, 2));
|
| 127 |
+
|
| 128 |
+
let errorMsg = `Błąd serwera API (Status ${response.status})`;
|
| 129 |
+
if (errorData.detail) {
|
| 130 |
+
if (Array.isArray(errorData.detail)) {
|
| 131 |
+
errorMsg = errorData.detail
|
| 132 |
+
.map(err => `• Pole \`${err.loc.join(".")}\`: ${err.msg}`)
|
| 133 |
+
.join("\n");
|
| 134 |
+
} else {
|
| 135 |
+
errorMsg = errorData.detail;
|
| 136 |
+
}
|
| 137 |
+
}
|
| 138 |
+
throw new Error(errorMsg);
|
| 139 |
+
}
|
| 140 |
+
|
| 141 |
+
const data = await response.json();
|
| 142 |
+
|
| 143 |
+
const statusEmoji = data.is_deepfake ? "⚠️ **Wykryto potencjalny Deepfake!**" : "✅ **Zawartość wydaje się oryginalna**";
|
| 144 |
+
const confidencePercent = (data.confidence * 100).toFixed(2);
|
| 145 |
+
const timeSec = data.analysis_time.toFixed(3);
|
| 146 |
+
|
| 147 |
+
const replyMessage =
|
| 148 |
+
`### Wyniki Analizy (${data.content_type.toUpperCase()})\n` +
|
| 149 |
+
`${statusEmoji}\n\n` +
|
| 150 |
+
`* **Pewność modelu:** \`${confidencePercent}%\`\n` +
|
| 151 |
+
`* **Użyty model:** \`${data.model_used}\`\n` +
|
| 152 |
+
`* **Czas przetwarzania:** \`${timeSec} sekund\`\n`;
|
| 153 |
+
|
| 154 |
+
await interaction.editReply({
|
| 155 |
+
content: replyMessage,
|
| 156 |
+
});
|
| 157 |
|
| 158 |
+
} catch (error) {
|
| 159 |
+
console.error("Błąd podczas analizy:", error);
|
| 160 |
+
await interaction.editReply({
|
| 161 |
+
content: `❌ Nie udało się przeprowadzić analizy.\n\n**Szczegóły błędu:**\n${error.message}`,
|
| 162 |
+
});
|
| 163 |
+
}
|
| 164 |
}
|
| 165 |
}
|
| 166 |
});
|