From a9666385094256244b9dcb23e01136eb8da16ab3 Mon Sep 17 00:00:00 2001 From: space2lim Date: Sat, 23 Mar 2024 23:19:01 +0900 Subject: [PATCH] Add feature to change user roles based on color reactions --- .dockerignore | 1 + Dockerfile | 6 +++ app.js | 108 +++++++++++++++++++++++++++++++++++++++++++------- 3 files changed, 100 insertions(+), 15 deletions(-) create mode 100644 .dockerignore create mode 100644 Dockerfile diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..b512c09 --- /dev/null +++ b/.dockerignore @@ -0,0 +1 @@ +node_modules \ No newline at end of file diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..7bd9591 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,6 @@ +FROM node:lts-alpine +WORKDIR /app +COPY package*.json ./ +RUN npm install +COPY . . +CMD [ "node", "app.js" ] \ No newline at end of file diff --git a/app.js b/app.js index ed37c57..b5789d9 100644 --- a/app.js +++ b/app.js @@ -1,7 +1,9 @@ import dotenv from 'dotenv'; -import * as util from './utils.js' +import * as util from './utils.js' import { REST, Routes } from 'discord.js'; -import { Client, GatewayIntentBits, EmbedBuilder } from 'discord.js'; +import { Client, GatewayIntentBits } from 'discord.js'; +import { EmbedBuilder } from 'discord.js'; +import { ActionRowBuilder, ButtonBuilder, ButtonStyle } from 'discord.js'; dotenv.config(); const TOKEN = process.env.TOKEN; @@ -26,14 +28,29 @@ const CLIENT_ID = process.env.CLI_ID; // console.error(error); // } -const intents = [ - GatewayIntentBits.Guilds, - GatewayIntentBits.GuildMessages, - GatewayIntentBits.MessageContent, -]; -const client = new Client({ intents: intents }); +const roles = { + '❀️': '1221079597962104872', + '🧑': '1221091257665720360', + 'πŸ’›': '1221091363475423374', + 'πŸ’š': '1221080091371765812', + '🩡': '1221091149796610088', + 'πŸ’™': '1221080047469858826', + 'πŸ’œ': '1221095844288270387', + 'πŸ”': 'reset', +}; +let botMessageId = ''; +const client = new Client({ + intents: [ + GatewayIntentBits.Guilds, + GatewayIntentBits.GuildMessages, + GatewayIntentBits.MessageContent, + GatewayIntentBits.GuildMessageReactions, + GatewayIntentBits.GuildMembers, // 역할을 λΆ€μ—¬ν•˜κΈ° μœ„ν•΄ ν•„μš” + ] +}); + client.on('ready', () => { console.log(`Logged in as ${client.user.tag}!`); }); @@ -56,13 +73,13 @@ client.on('messageCreate', async message => { const metaData = await util.getMetaData(urls[0]); // 첫 번째 URL의 메타데이터λ₯Ό μΆ”μΆœν•©λ‹ˆλ‹€. const embed = new EmbedBuilder() - .setColor(0x0099FF) - .setTitle(metaData.title) - .setURL(urls[0]) - // .setAuthor({ name: 'Some name', iconURL: 'https://i.imgur.com/AfFp7pu.png', url: 'https://discord.js.org' }) - .setDescription(metaData.description) - .setImage(metaData.image) - .setThumbnail(metaData.image) + .setColor(0x0099FF) + .setTitle(metaData.title) + .setURL(urls[0]) + // .setAuthor({ name: 'Some name', iconURL: 'https://i.imgur.com/AfFp7pu.png', url: 'https://discord.js.org' }) + .setDescription(metaData.description) + .setImage(metaData.image) + .setThumbnail(metaData.image) // .setThumbnail('https://i.imgur.com/AfFp7pu.png') // .addFields( // { name: 'Regular field title', value: 'Some value here' }, @@ -83,4 +100,65 @@ client.on('messageCreate', async message => { } }); +client.on('messageCreate', async message => { + const badLang = ['κΆŒνƒœμ›…', 'νƒœμ›…', 'μ›…νƒœ']; + + if (badLang.some(word => message.content.includes(word))) { + const str = `μ–΄ν—ˆ λ‚˜μœλ§ μ“°μ§€ λ§ˆμ„Έμš”`; + message.channel.send(str); + } +}); + + +// 'send-reactions' μ»€λ§¨λ“œλ₯Ό λ°›μ•˜μ„ λ•Œ λ¦¬μ•‘μ…˜μ΄ ν¬ν•¨λœ λ©”μ‹œμ§€λ₯Ό 보냄 +client.on('messageCreate', async message => { + if (message.content === '!색상') { + const sentMessage = await message.channel.send('색상을 μ„ νƒν•˜μ„Έμš”.'); + botMessageId = sentMessage.id; // λ©”μ‹œμ§€ ID μ €μž₯ + + // 'roles' κ°μ²΄μ—μ„œ 이λͺ¨μ§€ 킀듀을 μΆ”μΆœν•˜κ³ , 각 이λͺ¨μ§€μ— λŒ€ν•΄ λ¦¬μ•‘μ…˜ μΆ”κ°€ + Object.keys(roles).forEach(async emoji => { + if (emoji !== 'πŸ”') { // '리셋' 이λͺ¨μ§€λŠ” λ§ˆμ§€λ§‰μ— μΆ”κ°€ν•˜κΈ° μœ„ν•΄ μ—¬κΈ°μ„œλŠ” μ œμ™Έ + await sentMessage.react(emoji); + } + }); + await sentMessage.react('πŸ”'); + } +}); + +// λ¦¬μ•‘μ…˜ μΆ”κ°€ 이벀트 처리 +client.on('messageReactionAdd', async (reaction, user) => { + if (reaction.message.partial) await reaction.message.fetch(); + if (reaction.partial) await reaction.fetch(); + if (user.bot) return; // λ΄‡μ˜ λ¦¬μ•‘μ…˜ λ¬΄μ‹œ + + // if (reaction.message.id === botMessageId) { + if (reaction.message.author.bot) { + await reaction.users.remove(user.id); // λ¦¬μ•‘μ…˜ λ°”λ‘œ 원볡 + + const { emoji } = reaction; + const member = reaction.message.guild.members.cache.get(user.id); + + const roleId = roles[emoji.name]; + + if (roleId === 'reset') { + // λͺ¨λ“  색상 μ—­ν•  제거λ₯Ό λ³‘λ ¬λ‘œ 처리 + const removeRolesPromises = Object.values(roles).filter(id => id !== 'reset' && member.roles.cache.has(id)).map(id => member.roles.remove(id)); + await Promise.all(removeRolesPromises); + } else if (roleId) { + // λ¨Όμ € λͺ¨λ“  색상 μ—­ν•  제거 ν›„ μ„ νƒν•œ μ—­ν•  μΆ”κ°€ + const allRoleIds = Object.values(roles).filter(id => id !== 'reset'); + const removeRolesPromises = allRoleIds.filter(id => member.roles.cache.has(id)).map(id => member.roles.remove(id)); + await Promise.all(removeRolesPromises); + + const role = reaction.message.guild.roles.cache.get(roleId); + if (role) { + await member.roles.add(role); + console.log(`${user.username}μ—κ²Œ ${role.name}역할이 λΆ€μ—¬λ˜μ—ˆμŠ΅λ‹ˆλ‹€.`); + } + } + } +}); + + client.login(TOKEN); \ No newline at end of file