diff --git a/README.md b/README.md index 2e945e2..c825caa 100644 --- a/README.md +++ b/README.md @@ -449,3 +449,25 @@ dropienie, walki itd > każda komenda w tym foldeże jest dostępna tylko dla osób z subem > komendy testowe będą na prefix + usówanie linków do serwerów dc + + + +# in progres - reaction role +/reaction-role-add <> + +handler -> event add emoji -> check server.reaction-role.msg_id.emoji_id/name.data = {addedBy, addedTime, addRole_id, addEmoji, status} -> addRole_id.addToUser(userId) +handler -> event remove emoji -> ... + + +server.reaction_role.channel_id.msg_id.emoji_id/name.data + +# reaction role web - V1 +napisanie wiadomości w przeglądarce, wybranie kanału i send ++ lista emoji + rola +i wszystko się samo zrobi + + +# todo +opcje wrzucenia linku na dc i po zalogowaniu user może zareagować na role w przeglądarce + +!!! login -> przenośić userna do /login \ No newline at end of file diff --git a/api/app.js b/api/app.js index 0c6d2b8..1511d33 100644 --- a/api/app.js +++ b/api/app.js @@ -12,6 +12,10 @@ const full_load = require("./endpoints/full_load") const actions = require("./endpoints/actions") const admin = require("./endpoints/admin") const full_mod_load = require("./endpoints/full_mod_logs_load") +const reaction_role_api = require("./endpoints/reactionrole_settings") + +app.use(bodyParser.json()); +app.use(bodyParser.urlencoded({ extended: true })); // index file serving app.get("/", (req, res) => { @@ -26,6 +30,12 @@ app.get("/partners", (req, res) => { return res.sendFile(process.cwd() + "/api/webpanel/partners.html") }) +app.use("/api_reactionrole", reaction_role_api) + +app.get("/reactionrole_settings/:id", (req, res) => { + return res.sendFile(process.cwd() + "/api/webpanel/reaction_role_settings.html") +}) + app.get("/admin", (req, res) => { return res.sendFile(process.cwd() + "/api/webpanel/admin.html") }) @@ -85,7 +95,6 @@ app.use("/modlogs", mod_logs) app.use("/actions", actions) app.use("/admin", admin) app.use("/mod_logs", full_mod_load) -app.use(bodyParser.json()); // AUDIO TEST API ================================================== const { DataStore } = require("../handlers/audio/api") diff --git a/api/endpoints/reactionrole_settings.js b/api/endpoints/reactionrole_settings.js new file mode 100644 index 0000000..2c1de10 --- /dev/null +++ b/api/endpoints/reactionrole_settings.js @@ -0,0 +1,291 @@ +const express = require('express'); +const router = express.Router(); + +const Database = require("../../db/database") +const db = new Database(__dirname + "/../../db/files/servers.json") + +const { Auth, AuthV2 } = require("../handlers/auth") +const authV2 = AuthV2.getInstance(); + +const checkServerExists = require("../handlers/checkServerExists") + +const config = require("../config.json") +const mod_logs_list = config.api.mod_logs_list + +const BotLogs = require("../../handlers/bot_logs_handler") +const BotLogsHandler = BotLogs.getInstance() + +// /reactionrole/... + +/* +creating and deleting data by managing on bot web-page +*/ + +// add reaction-role to message by id +router.post("/save_reaction_by_id/:guildId", async (req, res) => { + // get data + if (!req.body) { + return res.status(400).json({ error: "No data provided" }) + } + const tokenType = req.body.tokenType + const token = req.body.token + const server_id = req.params.guildId + const channel_id = req.body.channel_id + const message_id = req.body.message_id + const role_id = req.body.role_id + const emoji = req.body.emoji + const status = req.body.status + const name = req.body.name // name to display on web + + let { client } = require("../../main"); + if (!client) { + console.error("Client is undefind") + return res.status(401).json({ error: "client is offline" }) + } + + if (!tokenType || !token || !server_id) { + return res.status(400).json({ error: "one or more body argument is undefined" }) + } + + if (!channel_id || !emoji) { + return res.status(400).json({ error: "one or more body argumen's is undefined" }) + } + + const is_authV2 = await authV2.verification(tokenType, token, server_id) + + if (!is_authV2) { + return res.status(400).json({ error: "Not auth" }) + } + + const is_server = await checkServerExists(server_id) + if (!is_server) { + return res.status(400).json({ error: "server_id is invalid" }) + } + + const save_data = { + emoji: emoji, + status: status, + role_id: role_id, + name: name, + } + db.init(); + db.addToList(`${server_id}.reaction_role.${channel_id}.${message_id}`, save_data) + + BotLogsHandler.SendLog(server_id, `Reaction role set on bot website\n channel_id: ${channel_id}\n message_id: ${message_id}`) + + return res.status(200).json({ status: "ok" }); +}) + +// delete reaction-role to message by id +router.post("/remove_reaction_by_id/:guildId", async (req, res) => { + console.log(req.body) + // get data + if (!req.body) { + return res.status(400).json({ error: "No data provided" }) + } + const tokenType = req.body.tokenType + const token = req.body.token + const server_id = req.params.guildId + const message_id = req.body.message_id + const emoji = req.body.emoji + + let { client } = require("../../main"); + if (!client) { + console.error("Client is undefind") + return res.status(401).json({ error: "client is offline" }) + } + + if (!tokenType || !token || !server_id) { + return res.status(400).json({ error: "one or more body argument is undefined" }) + } + + if (!emoji) { + return res.status(400).json({ error: "one or more body argumen's is undefined" }) + } + + const is_authV2 = await authV2.verification(tokenType, token, server_id) + + if (!is_authV2) { + return res.status(400).json({ error: "Not auth" }) + } + + const is_server = await checkServerExists(server_id) + if (!is_server) { + return res.status(400).json({ error: "server_id is invalid" }) + } + + db.init(); + const data = await db.read(`${server_id}.reaction_role`) + + // przejsc po wszystkich i matchowac messageId oraz emoji + // console.log('data') + // console.log(data) + + // console.log("db") + // // console.log(data.emoji, data.status, data.role_id, data.name) + + // console.log("to delete") + // console.log(emoji) + // console.log(message_id) + // console.log(server_id) + + Object.keys(data).forEach(channel_id => { + console.log(`channel id: ${channel_id}`); + + // Sprawdź, czy `data[channel_id][message_id]` istnieje i jest tablicą + const messageData = data[channel_id][message_id]; + if (Array.isArray(messageData)) { + messageData.forEach((obj, index) => { + if (obj.emoji === emoji && obj.status === true) { + // Zmień status w pamięci + obj.status = false; + + // Zapisz zmiany w bazie danych + const dbKey = `${server_id}.reaction_role.${channel_id}.${message_id}`; + const existingData = db.read(dbKey); // Pobierz aktualne dane + if (Array.isArray(existingData)) { + // Znajdź odpowiedni obiekt w bazie danych + const targetIndex = existingData.findIndex( + item => item.emoji === emoji + ); + + if (targetIndex !== -1) { + existingData[targetIndex].status = false; // Aktualizuj status + db.write(dbKey, existingData); // Zapisz zmiany w bazie + BotLogsHandler.SendLog( + server_id, + `Reaction role deleted on bot website\nchannel_id: ${channel_id}\nmessage_id: ${message_id}` + ); + + } else { + console.warn(`Object with emoji ${emoji} not found in DB`); + } + } else { + console.warn(`Data at ${dbKey} is not an array`); + } + } + }); + } else { + console.warn( + `Message data for channel_id: ${channel_id} and message_id: ${message_id} is not an array` + ); + } + }); + + + return res.status(200).json({ status: "ok" }); +}) + +// create re_ro message and autocomplete re_ro data +router.get("/create_reaction_role_message", async (req, res) => { + +}) + +// delete re_ro message and autocomplete re_ro data +router.get("/delete_reaction_role_message", async (req, res) => { + +}) + +/* +reaction-role-api +for webside loading / displaying data +*/ + +// get all user objects to display +router.get("/get_all_users_reaction_roles", async (req, res) => { + +}) + +// load all data neede to display stuf on website +router.post("/load_all", async (req, res) => { + // get data + if (!req.body) { + return res.status(400).json({ error: "No data provided" }) + } + const tokenType = req.body.tokenType + const token = req.body.token + const server_id = req.body.server_id + + let { client } = require("../../main"); + if (!client) { + console.error("Client is undefind") + return res.status(401).json({ error: "client is offline" }) + } + + if (!tokenType || !token || !server_id) { + return res.status(400).json({ error: "one or more body argument is undefined" }) + } + + const is_authV2 = await authV2.verification(tokenType, token, server_id) + + if (!is_authV2) { + return res.status(400).json({ error: "Not auth" }) + } + + const is_server = await checkServerExists(server_id) + if (!is_server) { + return res.status(400).json({ error: "server_id is invalid" }) + } + + // loading aplication data + const server = client.guilds.cache.get(server_id); + if (!server) { + return res.status(400).json({ error: "invalid serverId" }) + } + + db.init(); + let data = await db.read(`${server_id}.reaction_role`); + if (data) { + for (const guildKey in data) { + if (data.hasOwnProperty(guildKey)) { + for (const messageKey in data[guildKey]) { + if (data[guildKey].hasOwnProperty(messageKey)) { + const messageData = data[guildKey][messageKey]; + + if (Array.isArray(messageData)) { + data[guildKey][messageKey] = messageData.filter( + element => element.status === true + ); + } else { + console.warn(`Warning: data[${guildKey}][${messageKey}] is not an array`); + } + } + } + } + } + } + + // if (!data) { + // return res.status(400).json({error: "server reaction role not found"}) + // } + + const channels = server.channels.cache;//dont send + const server_channels_list = channels.map(channel => ({ + id: channel.id, + name: channel.name + })); + + const roles = server.roles.cache;//dont send + const server_roles_list = roles.map(role => ({ + id: role.id, + name: role.name + })); + + return res.status(200).json({ + reaction_role_data: data, + channels: server_channels_list, + roles: server_roles_list + }) +}) + +// api for future website to display guild reaction roles for not admin users +// to be able to get role from page without need to do that on discord. +router.get("/get_all_guild_reaction_roles", async (req, res) => { + +}) + +function checkToken() { + +} + +module.exports = router; \ No newline at end of file diff --git a/api/webpanel/reaction_role_settings.html b/api/webpanel/reaction_role_settings.html new file mode 100644 index 0000000..bce1115 --- /dev/null +++ b/api/webpanel/reaction_role_settings.html @@ -0,0 +1,170 @@ + + + + + + Reaction Role Settings + + + + + +
+

Reaction Role Settings

+
+ + + +
+ + + + + + + + + diff --git a/api/webpanel/src/main.ts b/api/webpanel/src/main.ts index 5f713db..3880496 100644 --- a/api/webpanel/src/main.ts +++ b/api/webpanel/src/main.ts @@ -20,6 +20,7 @@ function initial() { return; } + // TODO navbarStyle is not working on localhost! navbarStyle(); if (String(config.MainURL) === "http://localhost:3000") { document.getElementById("test-banner")?.classList.remove("d-none") @@ -181,6 +182,10 @@ async function handleServerClick(clickedServerId: string) { let link = `${config.MainURL}/modlogs/${clickedServerId}` genButtonElement(settings_parent, "Open Mod Logs", "mod_logs", "sdsd", link); + //reactionRole + let reactionRoleUrl = `${config.MainURL}/reactionrole_settings/${clickedServerId}` + genButtonElement(settings_parent, "Open Reaction role settings", "reaction_role", "sdsd", reactionRoleUrl); + //autorole let autorole = genSettings(settings_parent, "Autorole", true); diff --git a/api/webpanel/src/reaction_role_settings.ts b/api/webpanel/src/reaction_role_settings.ts new file mode 100644 index 0000000..6dc2041 --- /dev/null +++ b/api/webpanel/src/reaction_role_settings.ts @@ -0,0 +1,416 @@ +declare var bootstrap: any; + +interface ReactionRole { + emoji: string; + name: string; + role_id: string; + status: boolean; +} + +interface ReactionRoleData { + [serverId: string]: { + [messageId: string]: ReactionRole[]; + }; +} + +class ReactionRoleSettings { + private reactionRoles: ReactionRoleData = {}; + private channels: { id: string; name: string }[] = []; + private roles: { id: string; name: string }[] = []; + private editModal: any; + private isLoggedIn: boolean = false; + private loginButton: HTMLButtonElement | null; + private logoutButton: HTMLButtonElement | null; + private emojiPicker: HTMLDivElement | null = null; + private isAddingWithMessage: boolean = false; + private serverId: string; + + constructor() { + this.loginButton = document.getElementById('loginButton') as HTMLButtonElement | null; + this.logoutButton = document.getElementById('logoutButton') as HTMLButtonElement | null; + this.serverId = this.getServerIdFromUrl(); + this.initializeEventListeners(); + this.checkLoginStatus(); + this.editModal = new bootstrap.Modal(document.getElementById('reactionRoleModal')); + } + + private getServerIdFromUrl(): string { + const pathSegments = window.location.pathname.split('/'); + return pathSegments[pathSegments.length - 1]; + } + + private checkLoginStatus() { + const token = localStorage.getItem('token'); + const token_type = localStorage.getItem('token_type'); + if (token && token_type) { + this.isLoggedIn = true; + this.loadReactionRoles(); + } else { + this.isLoggedIn = false; + } + this.updateLoginState(); + } + + private initializeEventListeners() { + const addButton = document.getElementById('addReactionRole'); + const addWithMessageButton = document.getElementById('addReactionRoleAndMessage'); + const saveButton = document.getElementById('saveReactionRole'); + const emojiPicker = document.getElementById('emojiPicker'); + const deleteButton = document.getElementById('deleteReactionRole'); + + if (addButton) addButton.addEventListener('click', () => this.openEditModal()); + if (addWithMessageButton) addWithMessageButton.addEventListener('click', () => this.openEditModal(undefined, undefined, undefined, true)); + if (saveButton) saveButton.addEventListener('click', () => this.saveReactionRole()); + if (emojiPicker) emojiPicker.addEventListener('click', (e) => { + e.stopPropagation(); + this.toggleEmojiPicker(); + }); + if (this.loginButton) this.loginButton.addEventListener('click', () => this.login()); + if (this.logoutButton) this.logoutButton.addEventListener('click', () => this.logout()); + if (deleteButton) deleteButton.addEventListener('click', () => this.deleteReactionRole()); + + document.addEventListener('click', (e) => { + if (this.emojiPicker && !this.emojiPicker.contains(e.target as Node)) { + this.closeEmojiPicker(); + } + }); + } + + private async loadReactionRoles() { + if (this.isLoggedIn) { + try { + console.log('Attempting to load reaction roles...'); + const token = localStorage.getItem('token'); + const token_type = localStorage.getItem('token_type'); + const response = await fetch('/api_reactionrole/load_all', { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify({ + tokenType: token_type, + token, + server_id: this.serverId + }) + }); + console.log('Response status:', response.status); + const data = await response.json(); + console.log('Response data:', data); + + if (response.ok) { + this.reactionRoles = data.reaction_role_data; + this.channels = data.channels; + this.roles = data.roles; + this.renderReactionRoleList(); + this.populateDropdowns(); + } else { + console.error('Error:', data.error); + } + } catch (error) { + console.error('Error loading reaction roles:', error); + } + } + } + + private renderReactionRoleList() { + const container = document.getElementById('reactionRoleList')!; + container.innerHTML = ''; + if (!this.isLoggedIn) { + container.innerHTML = '

Please log in to view reaction roles.

'; + return; + } + + for (const serverId in this.reactionRoles) { + for (const messageId in this.reactionRoles[serverId]) { + this.reactionRoles[serverId][messageId].forEach((rr, index) => { + const element = document.createElement('div'); + element.className = 'col-md-4 mb-3'; + element.innerHTML = ` +
+
+
${rr.name}
+

Role: ${this.getRoleName(rr.role_id)}

+

Emoji: ${rr.emoji}

+

Message ID: ${messageId}

+

Status: ${rr.status ? 'Active' : 'Inactive'}

+
+
+ `; + element.addEventListener('click', () => this.openEditModal(serverId, messageId, index)); + container.appendChild(element); + }); + } + } + } + + private getRoleName(roleId: string): string { + return this.roles.find(r => r.id === roleId)?.name || 'Unknown'; + } + + private populateDropdowns() { + const channelSelect = document.getElementById('channel') as HTMLSelectElement; + const roleSelect = document.getElementById('role') as HTMLSelectElement; + + channelSelect.innerHTML = ''; + roleSelect.innerHTML = ''; + + this.channels.forEach(channel => { + const option = document.createElement('option'); + option.value = channel.id; + option.textContent = channel.name; + channelSelect.appendChild(option); + }); + + this.roles.forEach(role => { + const option = document.createElement('option'); + option.value = role.id; + option.textContent = role.name; + roleSelect.appendChild(option); + }); + } + + private openEditModal(serverId?: string, messageId?: string, index?: number, addWithMessage: boolean = false) { + const form = document.getElementById('reactionRoleForm') as HTMLFormElement; + const messageIdInput = document.getElementById('messageId') as HTMLInputElement; + const messageContentInput = document.getElementById('messageContent') as HTMLTextAreaElement; + const deleteButton = document.getElementById('deleteReactionRole') as HTMLButtonElement; + + form.reset(); + this.populateDropdowns(); + + if (serverId && messageId && index !== undefined) { + const rr = this.reactionRoles[serverId][messageId][index]; + (document.getElementById('name') as HTMLInputElement).value = rr.name; + (document.getElementById('role') as HTMLSelectElement).value = rr.role_id; + (document.getElementById('emojiName') as HTMLInputElement).value = rr.emoji; + messageIdInput.value = messageId; + deleteButton.style.display = 'inline-block'; + deleteButton.setAttribute('data-server-id', serverId); + deleteButton.setAttribute('data-message-id', messageId); + deleteButton.setAttribute('data-index', index.toString()); + messageIdInput.parentElement!.style.display = 'block'; + messageContentInput.parentElement!.style.display = 'none'; + } else { + deleteButton.style.display = 'none'; + deleteButton.removeAttribute('data-server-id'); + deleteButton.removeAttribute('data-message-id'); + deleteButton.removeAttribute('data-index'); + if (addWithMessage) { + messageIdInput.parentElement!.style.display = 'none'; + messageContentInput.parentElement!.style.display = 'block'; + } else { + messageIdInput.parentElement!.style.display = 'block'; + messageContentInput.parentElement!.style.display = 'none'; + } + } + + this.editModal.show(); + } + + private async saveReactionRole() { + const form = document.getElementById('reactionRoleForm') as HTMLFormElement; + if (form.checkValidity()) { + const name = (document.getElementById('name') as HTMLInputElement).value; + const channelId = (document.getElementById('channel') as HTMLSelectElement).value; + const roleId = (document.getElementById('role') as HTMLSelectElement).value; + const emoji = (document.getElementById('emojiName') as HTMLInputElement).value; + const messageId = (document.getElementById('messageId') as HTMLInputElement).value; + + const token_type = localStorage.getItem('token_type'); + const token = localStorage.getItem('token'); + + if (!token_type || !token) { + console.error('Authentication tokens not found'); + return; + } + + try { + const response = await fetch(`/api_reactionrole/save_reaction_by_id/${this.serverId}`, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify({ + tokenType: token_type, + token, + server_id: this.serverId, + channel_id: channelId, + message_id: messageId, + role_id: roleId, + emoji, + status: true, + name + }) + }); + + if (response.ok) { + const data = await response.json(); + if (data.status === 'ok') { + console.log('Reaction role saved successfully'); + if (!this.reactionRoles[this.serverId]) { + this.reactionRoles[this.serverId] = {}; + } + if (!this.reactionRoles[this.serverId][messageId]) { + this.reactionRoles[this.serverId][messageId] = []; + } + this.reactionRoles[this.serverId][messageId].push({ + name, + role_id: roleId, + emoji, + status: true + }); + this.renderReactionRoleList(); + this.editModal.hide(); + } else { + console.error('Failed to save reaction role'); + } + } else { + console.error('Server returned an error', response.status); + } + } catch (error) { + console.error('Error saving reaction role:', error); + } + } else { + form.reportValidity(); + } + } + + private toggleEmojiPicker() { + if (this.emojiPicker) { + this.closeEmojiPicker(); + } else { + this.openEmojiPicker(); + } + } + + private openEmojiPicker() { + if (this.emojiPicker) return; + + const emojis = ['😀', '😂', '🎉', '❤️', '🎮', '🎨', '🎵', '📚']; + this.emojiPicker = document.createElement('div'); + this.emojiPicker.className = 'emoji-picker'; + emojis.forEach(emoji => { + const button = document.createElement('button'); + button.textContent = emoji; + button.addEventListener('click', (e) => { + e.stopPropagation(); + (document.getElementById('emojiName') as HTMLInputElement).value = emoji; + this.closeEmojiPicker(); + }); + this.emojiPicker!.appendChild(button); + }); + document.body.appendChild(this.emojiPicker); + } + + private closeEmojiPicker() { + if (this.emojiPicker) { + this.emojiPicker.remove(); + this.emojiPicker = null; + } + } + + private updateLoginState() { + if (this.isLoggedIn) { + this.loginButton!.classList.add('d-none'); + this.logoutButton!.classList.remove('d-none'); + document.getElementById('addReactionRole')!.classList.remove('d-none'); + document.getElementById('addReactionRoleAndMessage')!.classList.remove('d-none'); + } else { + this.loginButton!.classList.remove('d-none'); + this.logoutButton!.classList.add('d-none'); + document.getElementById('addReactionRole')!.classList.add('d-none'); + document.getElementById('addReactionRoleAndMessage')!.classList.add('d-none'); + } + } + + private login() { + localStorage.setItem('token', 'fake_token'); + localStorage.setItem('token_type', 'Bearer'); + this.isLoggedIn = true; + this.updateLoginState(); + this.loadReactionRoles(); + } + + private logout() { + localStorage.removeItem('token'); + localStorage.removeItem('token_type'); + this.isLoggedIn = false; + this.updateLoginState(); + this.reactionRoles = {}; + this.renderReactionRoleList(); + } + // api_reactionrole + private async deleteReactionRole() { + // const deleteButton = document.getElementById('deleteReactionRole') as HTMLButtonElement; + // Pobieranie elementów + const messageIdElement = document.getElementById("messageId") as HTMLInputElement; + const emojiElement = document.getElementById("emojiName") as HTMLInputElement; + + const messageId = messageIdElement.value; // Odczytujemy wartość z elementu + const emoji = emojiElement.value; + + if (messageId && emoji) { + const tokenType = localStorage.getItem('token_type'); + const token = localStorage.getItem('token'); + + if (!tokenType || !token) { + console.error('Authentication tokens not found'); + return; + } + + try { + const response = await fetch(`/api_reactionrole/remove_reaction_by_id/${this.serverId}`, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify({ + tokenType, + token, + message_id: messageId, + emoji + }) + }); + + if (response.ok) { + console.log('Reaction role deleted successfully'); + // Remove the reaction role from the local data structure + for (const channelId in this.reactionRoles) { + if (this.reactionRoles[channelId][messageId]) { + this.reactionRoles[channelId][messageId] = this.reactionRoles[channelId][messageId].filter(rr => rr.emoji !== emoji); + if (this.reactionRoles[channelId][messageId].length === 0) { + delete this.reactionRoles[channelId][messageId]; + } + if (Object.keys(this.reactionRoles[channelId]).length === 0) { + delete this.reactionRoles[channelId]; + } + break; + } + } + this.renderReactionRoleList(); + this.editModal.hide(); + } else { + console.error('Server returned an error', response.status); + } + } catch (error) { + console.error('Error deleting reaction role:', error); + } + } else { + console.error('Missing message ID or emoji for deletion'); + } + } + + // private getChannelIdForMessage(messageId: string): string { + // for (const channelId in this.reactionRoles) { + // if (this.reactionRoles[channelId] && this.reactionRoles[channelId][messageId]) { + // return channelId; + // } + // } + // return ''; + // } +} + +document.addEventListener('DOMContentLoaded', () => { + new ReactionRoleSettings(); +}); + diff --git a/api/webpanel/src/settings.ts b/api/webpanel/src/settings.ts index e3d13ad..5d7958c 100644 --- a/api/webpanel/src/settings.ts +++ b/api/webpanel/src/settings.ts @@ -211,6 +211,16 @@ export function genCheckBox(parent: HTMLDivElement, title: string = "TextBox", c // Zwracamy checkbox, aby można było go użyć później }; } + +/** + * + * @param parent + * @param value + * @param buttonId + * @param buttonClass + * @param url + * @returns + */ export function genButtonElement(parent: HTMLElement, value: string, buttonId: string, buttonClass: string, url: string): HTMLButtonElement { // Tworzenie głównego kontenera dla przycisku const container = document.createElement("div"); diff --git a/handlers/emoji_handler.js b/handlers/emoji_handler.js new file mode 100644 index 0000000..d656f50 --- /dev/null +++ b/handlers/emoji_handler.js @@ -0,0 +1,141 @@ +const { use } = require("../api/app"); +const Database = require("../db/database") +const db = new Database(process.cwd() + "/db/files/servers.json") + +async function addEmoji(client, reaction, user) { + if (reaction.partial) { + try { + await reaction.fetch(); + } catch (error) { + console.error('Nie udało się pobrać wiadomości:', error); + return; + } + } + + // Wyciągnięcie informacji + const guildId = reaction.message.guild?.id || 'Brak serwera'; // Jeśli to wiadomość prywatna + const channelId = reaction.message.channel.id; + const messageId = reaction.message.id; + const userId = user.id; + const emoji = reaction.emoji; + + if (!guildId || !channelId || !messageId || !userId || !emoji) { + return //console.log("emoji_handler error - no data") + } + + // db actions + db.init() + const data = await db.read(`${guildId}.reaction_role.${channelId}.${messageId}`); + if (!data) return; + + for (const element of data) { + if (element.emoji === emoji.name && element.status === true) { + // console.log("Dodawanie roli użytkownikowi:"); + // console.log(element.role_id); + + try { + const guild = client.guilds.cache.get(guildId); // Pobranie serwera + const member = guild ? await guild.members.fetch(userId) : null; // Pobranie członka serwera, jeśli istnieje + if (!member) { + console.error('Nie znaleziono członka na serwerze.'); + continue; + } + + // Próba dodania roli + await member.roles.add(element.role_id); + // console.log(`Rola ${element.role_id} została dodana użytkownikowi ${member.user.tag}.`); + } catch (err) { + console.error('Błąd podczas dodawania roli - emoji_handler:', err); + + if (err.message.includes('Missing Permissions')) { + try { + // Pobranie kanału na podstawie client.channels + const channel = client.channels.cache.get(channelId); // Pobranie kanału + if (channel && channel.isTextBased()) { + await channel.send( + `Your bot on server "${guild.name}" does not have sufficient permissions to add role: ${element.role_id}. Please make sure the bot has "Manage Roles" permissions.` + ); + } else { + console.error('Nie znaleziono kanału lub kanał nie obsługuje wiadomości tekstowych.'); + } + } catch (channelErr) { + console.error('Nie udało się wysłać wiadomości na kanał:', channelErr); + } + } + } + } + } + + + + + + + + + +} + +async function removeEmoji(client, reaction, user) { + if (reaction.partial) { + try { + await reaction.fetch(); + } catch (error) { + console.error('Nie udało się pobrać wiadomości:', error); + return; + } + } + + // Wyciągnięcie informacji + const guildId = reaction.message.guild?.id || 'Brak serwera'; // Jeśli to wiadomość prywatna + const channelId = reaction.message.channel.id; + const messageId = reaction.message.id; + const userId = user.id; + const emoji = reaction.emoji; + + // db actions + db.init() + const data = await db.read(`${guildId}.reaction_role.${channelId}.${messageId}`); + if (!data) return; + + for (const element of data) { + if (element.emoji === emoji.name && element.status === true) { + console.log("Usuwanie roli użytkownika:"); + console.log(element.role_id); + + try { + const guild = client.guilds.cache.get(guildId); // Pobranie serwera + const member = guild ? await guild.members.fetch(userId) : null; // Pobranie członka serwera, jeśli istnieje + if (!member) { + console.error('Nie znaleziono członka na serwerze.'); + continue; + } + + // Próba zabrania roli + await member.roles.remove(element.role_id); + console.log(`Rola ${element.role_id} została usunięta użytkownikowi ${member.user.tag}.`); + } catch (err) { + console.error('Błąd podczas usuwania roli - emoji_handler:', err); + + if (err.message.includes('Missing Permissions')) { + try { + // Pobranie kanału na podstawie client.channels + const channel = client.channels.cache.get(channelId); // Pobranie kanału + if (channel && channel.isTextBased()) { + await channel.send( + `Your bot on server "${guild.name}" does not have sufficient permissions to add role: ${element.role_id}. Please make sure the bot has "Manage Roles" permissions.".` + ); + } else { + console.error('Nie znaleziono kanału lub kanał nie obsługuje wiadomości tekstowych.'); + } + } catch (channelErr) { + console.error('Nie udało się wysłać wiadomości na kanał:', channelErr); + } + } + } + } + } + +} + +module.exports = { addEmoji, removeEmoji } \ No newline at end of file diff --git a/main.js b/main.js index a077884..37ebbc7 100644 --- a/main.js +++ b/main.js @@ -7,7 +7,7 @@ const rsc_config = config.register_slash_commands require('dotenv').config(); let token; if (is_test) { - token = process.env.ELLIE; + token = process.env.TOKEN_TEST; } else { token = process.env.TOKEN; } @@ -38,7 +38,7 @@ console.log({ "Test mode: ": is_test, }) -const { Client, GatewayIntentBits } = require("discord.js") +const { Client, GatewayIntentBits, Events, Partials } = require("discord.js") const client = new Client({ intents: [ GatewayIntentBits.Guilds, @@ -47,8 +47,14 @@ const client = new Client({ GatewayIntentBits.GuildMembers, GatewayIntentBits.GuildVoiceStates, GatewayIntentBits.GuildPresences, - GatewayIntentBits.GuildInvites - ] + GatewayIntentBits.GuildInvites, + GatewayIntentBits.GuildMessageReactions + ], + partials: [ + Partials.Message, + Partials.Channel, + Partials.Reaction + ], }); const LoadModLogsGuilds = require("./handlers/modlogsMessages_handler") @@ -82,6 +88,7 @@ const BotLogsHandler = BotLogs.getInstance(); const InviteTracker = require("./handlers/invite_tracker") const { AudioDataStore } = require("./handlers/audio/cache") const AudioStore = AudioDataStore.getInstance() +const {addEmoji, removeEmoji} = require("./handlers/emoji_handler") // "/test" handlers require("./test/handlers/handler")(client) @@ -174,6 +181,15 @@ client.on('interactionCreate', async interaction => { } }); +// emoji's +client.on(Events.MessageReactionAdd, async (reaction, user) => { + addEmoji(client, reaction, user) +}); + +client.on(Events.MessageReactionRemove, async (reaction, user) => { + removeEmoji(client, reaction, user) +}); + // Dodanie event handlera do przycisków // client.on("interactionCreate", async (interaction) => { // if (interaction.isButton()) {