├── LICENSE ├── README.md ├── config.js ├── config.json ├── id.json ├── index.js └── package.json /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 xTEAMXx 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ระบบ DISCORD WHITELIST FOR FIVEM 2 | + [ วิธีตั้งค่า EMBED เบื้องต้นง่ายๆ ] 3 | + [ติดต่อ](https://discord.gg/EB9CFWjcFh) 4 | 5 | ### วิธีการติดตั้งและรัน 6 | + Req: [NodeJS](https://nodejs.org/en/download) 7 | + Req: [VSCODE](https://code.visualstudio.com/download) 8 | + Req: [TOKENBOT](https://discord.com/developers/) 9 | 10 | 11 | ```js 12 | npm install && npm i 13 | 14 | node index.js && node . 15 | ``` 16 | 17 | ```js 18 | const { ButtonStyle } = require('discord.js'); 19 | 20 | module.exports = { 21 | // ตั้งค่าโทเคนและข้อมูลเซิร์ฟเวอร์ 22 | token: "", // โทเคนของบอท 23 | roleAdmin: "", // ไอดียศแอดมิน 24 | guild: [""], // ไอดีเซิร์ฟเวอร์ 25 | WhitelistRole: "", // ไอดียศไวท์ลิสต์ 26 | channelId: "", // ไอดีห้องกดรับยศ 27 | channelId_Log: "", // ไอดีห้องบันทึกข้อมูล 28 | 29 | // ตั้งค่าหน้าข้อความและปุ่มหลัก 30 | main: { 31 | title: "test", // ชื่อหัวข้อข้อความ 32 | iconURL: "https://cdn.discordapp.com/attachments/988800716212674570/1082762974520946758/logo.png", // ไอคอนหัวข้อ 33 | Description: "**FF \n\n กรุณากรอกข้อมูลให้ครบ [มิเช่นนั้น] ทางเราจะไม่รับเรื่องดังที่สมัครเข้ามา**", 34 | colors: "#ff0003", // สีของข้อความ 35 | image: "https://cdn.discordapp.com/attachments/988800716212674570/1082762974520946758/logo.png", // รูปภาพหลัก 36 | 37 | button_msg: "กดปุ่มเพื่อลงทะเบียนไวท์ลิสต์", // ข้อความปุ่ม 38 | button_emoji: "✅", // อิโมจิปุ่ม 39 | button_style: ButtonStyle.Danger, // สีปุ่ม (Primary น้ำเงิน, Secondary เทา, Success เขียว, Danger แดง) 40 | }, 41 | 42 | // ตั้งค่าหน้ากรอกข้อมูล 43 | modals: { 44 | title: "test" // ชื่อหัวข้อหน้ากรอกข้อมูล 45 | }, 46 | 47 | // ข้อความตอบกลับผู้ใช้หลังกรอกข้อมูล 48 | reply_submit: { 49 | title: "test", // ชื่อหัวข้อข้อความตอบกลับ 50 | iconURL: "https://cdn.discordapp.com/attachments/988800716212674570/1082762974520946758/logo.png", // ไอคอนหัวข้อ 51 | colors: "#41ff00", // สีข้อความ 52 | Description: "**คุณได้ทำการยืนยันเป็นที่เรียบร้อย รอทางแอดมินตรวจสอบ**" 53 | }, 54 | 55 | // ข้อความแจ้งเตือนไปยังแอดมิน 56 | reply_admin: { 57 | title: "test", // ชื่อหัวข้อข้อความแจ้งแอดมิน 58 | iconURL: "https://cdn.discordapp.com/attachments/988800716212674570/1082762974520946758/logo.png" // ไอคอนหัวข้อ 59 | } 60 | }; 61 | 62 | ``` 63 | 64 | 65 | ผู้แก้ไขข้อมูล **BALLZAZA#4481** 66 | ผู้แก้ไขข้อมูล **st4rsation_** 67 | -------------------------------------------------------------------------------- /config.js: -------------------------------------------------------------------------------- 1 | const { ButtonStyle } = require('discord.js'); 2 | 3 | module.exports = { 4 | // ตั้งค่าโทเคนและข้อมูลเซิร์ฟเวอร์ 5 | token: "", // โทเคนของบอท 6 | roleAdmin: "", // ไอดียศแอดมิน 7 | guild: [""], // ไอดีเซิร์ฟเวอร์ 8 | WhitelistRole: "", // ไอดียศไวท์ลิสต์ 9 | channelId: "", // ไอดีห้องกดรับยศ 10 | channelId_Log: "", // ไอดีห้องบันทึกข้อมูล 11 | 12 | // ตั้งค่าหน้าข้อความและปุ่มหลัก 13 | main: { 14 | title: "test", // ชื่อหัวข้อข้อความ 15 | iconURL: "https://cdn.discordapp.com/attachments/988800716212674570/1082762974520946758/logo.png", // ไอคอนหัวข้อ 16 | Description: "**FF \n\n กรุณากรอกข้อมูลให้ครบ [มิเช่นนั้น] ทางเราจะไม่รับเรื่องดังที่สมัครเข้ามา**", 17 | colors: "#ff0003", // สีของข้อความ 18 | image: "https://cdn.discordapp.com/attachments/988800716212674570/1082762974520946758/logo.png", // รูปภาพหลัก 19 | 20 | button_msg: "กดปุ่มเพื่อลงทะเบียนไวท์ลิสต์", // ข้อความปุ่ม 21 | button_emoji: "✅", // อิโมจิปุ่ม 22 | button_style: ButtonStyle.Danger, // สีปุ่ม (Primary น้ำเงิน, Secondary เทา, Success เขียว, Danger แดง) 23 | }, 24 | 25 | // ตั้งค่าหน้ากรอกข้อมูล 26 | modals: { 27 | title: "test" // ชื่อหัวข้อหน้ากรอกข้อมูล 28 | }, 29 | 30 | // ข้อความตอบกลับผู้ใช้หลังกรอกข้อมูล 31 | reply_submit: { 32 | title: "test", // ชื่อหัวข้อข้อความตอบกลับ 33 | iconURL: "https://cdn.discordapp.com/attachments/988800716212674570/1082762974520946758/logo.png", // ไอคอนหัวข้อ 34 | colors: "#41ff00", // สีข้อความ 35 | Description: "**คุณได้ทำการยืนยันเป็นที่เรียบร้อย รอทางแอดมินตรวจสอบ**" 36 | }, 37 | 38 | // ข้อความแจ้งเตือนไปยังแอดมิน 39 | reply_admin: { 40 | title: "test", // ชื่อหัวข้อข้อความแจ้งแอดมิน 41 | iconURL: "https://cdn.discordapp.com/attachments/988800716212674570/1082762974520946758/logo.png" // ไอคอนหัวข้อ 42 | } 43 | }; 44 | -------------------------------------------------------------------------------- /config.json: -------------------------------------------------------------------------------- 1 | { 2 | "data": [ 3 | ] 4 | } -------------------------------------------------------------------------------- /id.json: -------------------------------------------------------------------------------- 1 | {"messageID":""} -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | const { Client, EmbedBuilder, ButtonBuilder, ActionRowBuilder, ButtonStyle, ModalBuilder, TextInputBuilder, TextInputStyle } = require("discord.js"); 2 | const editJsonFile = require("edit-json-file"); 3 | const config = require("./config"); 4 | const fs = require("fs"); 5 | 6 | const client = new Client({ intents: ["Guilds", "GuildMembers"] }); 7 | 8 | client.on("ready", setupInitialMessage); 9 | client.on("interactionCreate", handleInteraction); 10 | 11 | async function setupInitialMessage() { 12 | console.log("✅ BOT IS ONLINE"); 13 | const channel = client.channels.cache.get(config.channelId); 14 | 15 | const embed = new EmbedBuilder() 16 | .setAuthor({ name: config.main.title, iconURL: config.main.iconURL }) 17 | .setDescription(config.main.Description) 18 | .setColor("Red") 19 | .setImage(config.main.image) 20 | .setFooter({ text: "BROKEN BOT", iconURL: config.main.footerIcon }); 21 | 22 | const verifyButton = new ButtonBuilder() 23 | .setCustomId("buttonVerify") 24 | .setLabel(config.main.button_msg) 25 | .setEmoji(config.main.button_emoji) 26 | .setStyle(config.main.button_style); 27 | 28 | const actionRow = new ActionRowBuilder().addComponents(verifyButton); 29 | 30 | let messageData = JSON.parse(fs.readFileSync("id.json")); 31 | 32 | try { 33 | const existingMessage = await channel.messages.fetch(messageData.messageID); 34 | existingMessage.edit({ embeds: [embed], components: [actionRow] }); 35 | } catch (error) { 36 | const newMessage = await channel.send({ embeds: [embed], components: [actionRow] }); 37 | messageData.messageID = newMessage.id; 38 | fs.writeFileSync("id.json", JSON.stringify(messageData)); 39 | } 40 | } 41 | 42 | async function handleInteraction(interaction) { 43 | if (interaction.isButton()) return handleButtonInteraction(interaction); 44 | if (interaction.isModalSubmit()) return handleModalSubmission(interaction); 45 | } 46 | 47 | async function handleButtonInteraction(interaction) { 48 | switch (interaction.customId) { 49 | case "buttonVerify": 50 | return showVerifyModal(interaction); 51 | case "addRoles": 52 | return confirmRoles(interaction); 53 | case "Cancel": 54 | return cancelInteraction(interaction); 55 | } 56 | } 57 | 58 | async function showVerifyModal(interaction) { 59 | const modal = new ModalBuilder().setTitle(config.modals.title).setCustomId("model_function"); 60 | 61 | modal.addComponents( 62 | createTextInput("steam_link", "ลิงค์สตรีม", true), 63 | createTextInput("username_oc", "ชื่อ OC"), 64 | createTextInput("username_ic", "ชื่อ IC"), 65 | createTextInput("age_oc", "อายุ OC IC"), 66 | createTextInput("facebook_ic", "เฟส IC") 67 | ); 68 | 69 | await interaction.showModal(modal); 70 | } 71 | 72 | function createTextInput(customId, label, required = false) { 73 | return new ActionRowBuilder().addComponents( 74 | new TextInputBuilder().setCustomId(customId).setLabel(label).setStyle(TextInputStyle.Short).setRequired(required) 75 | ); 76 | } 77 | 78 | async function confirmRoles(interaction) { 79 | await interaction.deferUpdate(); 80 | const member = interaction.message?.mentions.members.first(); 81 | if (member) member.roles.add(config.WhitelistRole); 82 | 83 | updateInteractionButtons(interaction, true); 84 | } 85 | 86 | async function cancelInteraction(interaction) { 87 | updateInteractionButtons(interaction, false, true); 88 | } 89 | 90 | function updateInteractionButtons(interaction, disableConfirm = false, remove = false) { 91 | if (remove) return interaction.message.edit({ components: [] }); 92 | 93 | const confirmButton = new ButtonBuilder() 94 | .setCustomId("addRoles") 95 | .setLabel("✅ ยืนยัน") 96 | .setStyle(ButtonStyle.Primary) 97 | .setDisabled(disableConfirm); 98 | 99 | const cancelButton = new ButtonBuilder() 100 | .setCustomId("Cancel") 101 | .setLabel("❌ ยกเลิก") 102 | .setStyle(ButtonStyle.Danger) 103 | .setDisabled(disableConfirm); 104 | 105 | const row = new ActionRowBuilder().addComponents(confirmButton, cancelButton); 106 | 107 | interaction.message.edit({ components: [row] }); 108 | } 109 | 110 | async function handleModalSubmission(interaction) { 111 | const submissionData = extractSubmissionData(interaction); 112 | saveSubmissionData(submissionData); 113 | 114 | await interaction.reply({ 115 | embeds: [createUserReplyEmbed()], 116 | ephemeral: true, 117 | }); 118 | 119 | sendAdminLog(interaction, submissionData); 120 | } 121 | 122 | function extractSubmissionData(interaction) { 123 | const fields = interaction.fields; 124 | return { 125 | ชื่อดิสคอร์ด: `${interaction.member.user.username}#${interaction.member.user.discriminator}`, 126 | สตรีมลิงค์: fields.getTextInputValue("steam_link"), 127 | "ชื่อ OC": fields.getTextInputValue("username_oc"), 128 | "ชื่อ IC": fields.getTextInputValue("username_ic"), 129 | "อายุ OC IC": fields.getTextInputValue("age_oc"), 130 | "เฟส IC": fields.getTextInputValue("facebook_ic"), 131 | }; 132 | } 133 | 134 | function saveSubmissionData(data) { 135 | let file = editJsonFile("config.json"); 136 | let existingData = file.get("data") || []; 137 | existingData.push(data); 138 | file.set("data", existingData).save(); 139 | } 140 | 141 | function createUserReplyEmbed() { 142 | return new EmbedBuilder() 143 | .setAuthor({ name: config.reply_submit.title, iconURL: config.reply_submit.iconURL }) 144 | .setDescription(`${config.reply_submit.Description} <@&${config.roleAdmin}>`) 145 | .setColor(config.reply_submit.colors) 146 | .setTimestamp(); 147 | } 148 | 149 | function sendAdminLog(interaction, submissionData) { 150 | const logChannel = interaction.guild.channels.cache.get(config.channelId_Log); 151 | logChannel.send({ 152 | content: `ส่งข้อมูลโดย: <@${interaction.member?.id}>`, 153 | embeds: [new EmbedBuilder() 154 | .setAuthor({ name: config.reply_admin.title, iconURL: config.reply_admin.iconURL }) 155 | .setDescription(`**ข้อมูลผู้ส่ง:** <@${interaction.member?.id}>\n**ลิงค์สตรีม:** ${submissionData.สตรีมลิงค์}\n**ชื่อ OC & IC:** ${submissionData["ชื่อ OC"]} & ${submissionData["ชื่อ IC"]}\n**อายุ:** ${submissionData["อายุ OC IC"]}\n**เฟส IC:** [Link](${submissionData["เฟส IC"]})`) 156 | .setColor("Green") 157 | .setTimestamp() 158 | ], 159 | components: [new ActionRowBuilder().addComponents( 160 | new ButtonBuilder().setCustomId("addRoles").setLabel("✅ ยืนยัน").setStyle(ButtonStyle.Primary), 161 | new ButtonBuilder().setCustomId("Cancel").setLabel("❌ ยกเลิก").setStyle(ButtonStyle.Danger) 162 | )] 163 | }); 164 | } 165 | 166 | client.login(config.token); 167 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "dc_whitelist", 3 | "description": "Discord Whitelist", 4 | "version": "1.0.0", 5 | "main": "index.js", 6 | "scripts": { 7 | "start": "node index.js" 8 | }, 9 | "keywords": [ 10 | "whitelist" 11 | ], 12 | "author": "HELLO JJ#2631", 13 | "license": "MIT" 14 | } 15 | --------------------------------------------------------------------------------