From 126ae1bc38041a8f8ecf9ae5e8b5c7f49c7bf682 Mon Sep 17 00:00:00 2001 From: Nathan Steel Date: Mon, 1 Aug 2022 10:26:59 -0400 Subject: [PATCH 1/3] Add basic functionality Add basic commands --- .gitignore | 1 + README.md | 39 +++ app.js | 64 +++++ commands/ping.js | 11 + commands/server.js | 11 + commands/user.js | 11 + config.json | 6 + deploy-commands.js | 37 +++ destroy-commands.js | 21 ++ events/interactionCreate.js | 7 + events/ready.js | 9 + package-lock.json | 539 ++++++++++++++++++++++++++++++++++++ package.json | 17 ++ 13 files changed, 773 insertions(+) create mode 100644 .gitignore create mode 100644 README.md create mode 100644 app.js create mode 100644 commands/ping.js create mode 100644 commands/server.js create mode 100644 commands/user.js create mode 100644 config.json create mode 100644 deploy-commands.js create mode 100644 destroy-commands.js create mode 100644 events/interactionCreate.js create mode 100644 events/ready.js create mode 100644 package-lock.json create mode 100644 package.json diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..2ccbe46 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/node_modules/ diff --git a/README.md b/README.md new file mode 100644 index 0000000..16aacc1 --- /dev/null +++ b/README.md @@ -0,0 +1,39 @@ +# aBot - aNetwork's own lil' fella + +aBot is the Discord bot written for aNetwork. It is built on discord.js, +and as such uses node/js as its primary language. + +The main functionality includes: +- Self-assigning roles +- (TODO) A report system +- (TODO) Integration w/ aNetwork specific sites/programs + +## Requirements + +- NodeJs + +## Setup + +- Download nodejs +- Download this with `git clone .` +- Enter directory with `cd aBot` +- Download required packages with `npm install` +- Run with `node app.js` + +## Add/Remove Commands + +### Add +- Add the command in ./commands +- run `node deploy-commands.js` + +### Remove +- Run `node destroy-commands.js` + +## Run the bot + +`node app.js` + +### Using pm2 + +`pm2 start app.js` + diff --git a/app.js b/app.js new file mode 100644 index 0000000..bc73a38 --- /dev/null +++ b/app.js @@ -0,0 +1,64 @@ +// https://gist.github.com/himanshuxd/3855d2699ed795279bba534e4ddc52f5 +// https://discord.js.org/#/docs/discord.js/main/general/welcome + +// Fundementals built follow the v13 guide, while on v14 +// https://discordjs.guide/creating-your-bot/#creating-the-main-file + +// For commands in different files +const fs = require('node:fs'); +const path = require('node:path'); + +// Require the necessary discord.js classes +const { Client, GatewayIntentBits, Partials, InteractionType } = require('discord.js'); +// Create a new client instance +const client = new Client({ intents: [GatewayIntentBits.Guilds], partials: [Partials.Channel] }); +// Add config file +const config = require('./config.json'); + +// Commands in seperate files +client.commands = new Map(); + +const commandsPath = path.join(__dirname, 'commands'); +const commandFiles = fs.readdirSync(commandsPath).filter(file => file.endsWith('.js')); + +for (const file of commandFiles) { + const filePath = path.join(commandsPath, file); + const command = require(filePath); + // Set a new item in the Collection + // With the key as the command name and the value as the exported module + client.commands.set(command.data.name, command); +} + +// Events in seperate files +const eventsPath = path.join(__dirname, 'events'); +const eventFiles = fs.readdirSync(eventsPath).filter(file => file.endsWith('.js')); + +for (const file of eventFiles) { + const filePath = path.join(eventsPath, file); + const event = require(filePath); + if (event.once) { + client.once(event.name, (...args) => event.execute(...args)); + } else { + client.on(event.name, (...args) => event.execute(...args)); + } +} + +// Interactions +client.on('interactionCreate', async interaction => { + + if (!interaction.type === InteractionType.ApplicationCommand) return; + + const command = client.commands.get(interaction.commandName); if (!command) return; + + try { + await command.execute(interaction); + } catch (error) { + console.error(error); + await interaction.reply({ content: 'There was an error while executing this command!', ephemeral: true }); + } + +}); + +// Login to Discord with your client's token +client.login(config.token); + diff --git a/commands/ping.js b/commands/ping.js new file mode 100644 index 0000000..abe9ce4 --- /dev/null +++ b/commands/ping.js @@ -0,0 +1,11 @@ +const { SlashCommandBuilder } = require('@discordjs/builders'); + +module.exports = { + data: new SlashCommandBuilder() + .setName('ping') + .setDescription('Replies with Pong!'), + async execute(interaction) { + await interaction.reply('Pong!'); + }, +}; + diff --git a/commands/server.js b/commands/server.js new file mode 100644 index 0000000..e0feca5 --- /dev/null +++ b/commands/server.js @@ -0,0 +1,11 @@ +const { SlashCommandBuilder } = require('@discordjs/builders'); + +module.exports = { + data: new SlashCommandBuilder() + .setName('server') + .setDescription('Server info'), + async execute(interaction) { + await interaction.reply(`Server name: ${interaction.guild.name}\nTotal members: ${interaction.guild.memberCount}`); + }, +}; + diff --git a/commands/user.js b/commands/user.js new file mode 100644 index 0000000..5093742 --- /dev/null +++ b/commands/user.js @@ -0,0 +1,11 @@ +const { SlashCommandBuilder } = require('@discordjs/builders'); + +module.exports = { + data: new SlashCommandBuilder() + .setName('user') + .setDescription('User info'), + async execute(interaction) { + await interaction.reply(`Your tag: ${interaction.user.tag}\nYour id: ${interaction.user.id}`); + }, +}; + diff --git a/config.json b/config.json new file mode 100644 index 0000000..be1d541 --- /dev/null +++ b/config.json @@ -0,0 +1,6 @@ +{ + "clientId": "999653490248921189", + "guildId": "802255255822925835", + "token": "OTk5NjUzNDkwMjQ4OTIxMTg5.GBiiXE.cgZJkghVhHjYViUwLChJ0HjxB0wR6VEy-zR62I" +} + diff --git a/deploy-commands.js b/deploy-commands.js new file mode 100644 index 0000000..767804b --- /dev/null +++ b/deploy-commands.js @@ -0,0 +1,37 @@ +// new +// In order to get your application's client id, go to Discord Developer Portal and choose your application. Find the id under "Application ID" in General Information subpage. To get guild id, open Discord and go to your settings. On the "Advanced" page, turn on "Developer Mode". This will enable a "Copy ID" button in the context menu when you right-click on a server icon, a user's profile, etc. + +//node deploy-commands.js when adding/editing commands + +const fs = require('node:fs'); +const path = require('node:path'); + +const { SlashCommandBuilder } = require('@discordjs/builders'); +const { REST } = require('@discordjs/rest'); +const { Routes } = require('discord-api-types/v9'); +const config = require('./config.json'); + + +const commands = []; +const commandsPath = path.join(__dirname, 'commands'); +const commandFiles = fs.readdirSync(commandsPath).filter(file => file.endsWith('.js')); + +for (const file of commandFiles) { + const filePath = path.join(commandsPath, file); + const command = require(filePath); + commands.push(command.data.toJSON()); +} + +//const commands = [ + //new SlashCommandBuilder().setName('ping').setDescription('Replies with pong!'), + //new SlashCommandBuilder().setName('server').setDescription('Replies with server info!'), + //new SlashCommandBuilder().setName('user').setDescription('Replies with user info!'), +//] + //.map(command => command.toJSON()); + +const rest = new REST({ version: '9' }).setToken(config.token); + +rest.put(Routes.applicationGuildCommands(config.clientId, config.guildId), { body: commands }) + .then(() => console.log('Successfully registered application commands.')) + .catch(console.error); + diff --git a/destroy-commands.js b/destroy-commands.js new file mode 100644 index 0000000..ec6b752 --- /dev/null +++ b/destroy-commands.js @@ -0,0 +1,21 @@ +const { REST } = require('@discordjs/rest'); +const { Routes } = require('discord-api-types/v9'); +const { clientId, guildId, token } = require('./config.json'); + +const rest = new REST({ version: '9' }).setToken(token); + +// Need to get the commandID from the server for these +// Developer Mode | Server Settings -> Integrations -> Bots and Apps + +// To delete ALL, replace command ID w/ { body: [] } + +// for guild-based commands +rest.delete(Routes.applicationGuildCommand(clientId, guildId, { body: [] })) + .then(() => console.log('Successfully deleted guild command')) + .catch(console.error); + +// for global commands +rest.delete(Routes.applicationCommand(clientId, { body: [] })) + .then(() => console.log('Successfully deleted application command')) + .catch(console.error); + diff --git a/events/interactionCreate.js b/events/interactionCreate.js new file mode 100644 index 0000000..c8e18a3 --- /dev/null +++ b/events/interactionCreate.js @@ -0,0 +1,7 @@ +module.exports = { + name: 'interactionCreate', + execute(interaction) { + console.log(`${interaction.user.tag} in #${interaction.channel.name} triggered an interaction.`); + }, +}; + diff --git a/events/ready.js b/events/ready.js new file mode 100644 index 0000000..16d1f1b --- /dev/null +++ b/events/ready.js @@ -0,0 +1,9 @@ +module.exports = { + name: 'ready', + once: true, + execute(client) { + console.log(`Ready! Logged in as ${client.user.tag}`); + client.user.setActivity('Sneaky snake simulator, sss'); + }, +}; + diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..328b7c1 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,539 @@ +{ + "name": "discord-bot", + "version": "1.0.0", + "lockfileVersion": 2, + "requires": true, + "packages": { + "": { + "name": "discord-bot", + "version": "1.0.0", + "license": "ISC", + "dependencies": { + "@discordjs/builders": "^1.0.0", + "@discordjs/rest": "^1.0.0", + "discord-api-types": "^0.36.3", + "discord.js": "^14.0.3" + } + }, + "node_modules/@discordjs/builders": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@discordjs/builders/-/builders-1.0.0.tgz", + "integrity": "sha512-8y91ZfpOHubiGJu5tVyGI9tQCEyHZDTeqUWVcJd0dq7B96xIf84S0L4fwmD1k9zTe1eqEFSk0gc7BpY+FKn7Ww==", + "dependencies": { + "@sapphire/shapeshift": "^3.5.1", + "discord-api-types": "^0.36.2", + "fast-deep-equal": "^3.1.3", + "ts-mixer": "^6.0.1", + "tslib": "^2.4.0" + }, + "engines": { + "node": ">=16.9.0" + } + }, + "node_modules/@discordjs/collection": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@discordjs/collection/-/collection-1.0.0.tgz", + "integrity": "sha512-nAxDQYE5dNAzEGQ7HU20sujDsG5vLowUKCEqZkKUIlrXERZFTt/60zKUj/g4+AVCGeq+pXC5hivMaNtiC+PY5Q==", + "engines": { + "node": ">=16.9.0" + } + }, + "node_modules/@discordjs/rest": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@discordjs/rest/-/rest-1.0.0.tgz", + "integrity": "sha512-uDAvnE0P2a8axMdD4C51EGjvCRQ2HZk2Yxf6vHWZgIqG87D8DGKMPwmquIxrrB07MjV+rwci2ObU+mGhGP+bJg==", + "dependencies": { + "@discordjs/collection": "^1.0.0", + "@sapphire/async-queue": "^1.3.2", + "@sapphire/snowflake": "^3.2.2", + "discord-api-types": "^0.36.2", + "file-type": "^17.1.2", + "tslib": "^2.4.0", + "undici": "^5.7.0" + }, + "engines": { + "node": ">=16.9.0" + } + }, + "node_modules/@sapphire/async-queue": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/@sapphire/async-queue/-/async-queue-1.3.2.tgz", + "integrity": "sha512-rUpMLATsoAMnlN3gecAcr9Ecnw1vG7zi5Xr+IX22YzRzi1k9PF9vKzoT8RuEJbiIszjcimu3rveqUnvwDopz8g==", + "engines": { + "node": ">=v14.0.0", + "npm": ">=7.0.0" + } + }, + "node_modules/@sapphire/shapeshift": { + "version": "3.5.1", + "resolved": "https://registry.npmjs.org/@sapphire/shapeshift/-/shapeshift-3.5.1.tgz", + "integrity": "sha512-7JFsW5IglyOIUQI1eE0g6h06D/Far6HqpcowRScgCiLSqTf3hhkPWCWotVTtVycnDCMYIwPeaw6IEPBomKC8pA==", + "dependencies": { + "fast-deep-equal": "^3.1.3", + "lodash.uniqwith": "^4.5.0" + }, + "engines": { + "node": ">=v14.0.0", + "npm": ">=7.0.0" + } + }, + "node_modules/@sapphire/snowflake": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/@sapphire/snowflake/-/snowflake-3.2.2.tgz", + "integrity": "sha512-ula2O0kpSZtX9rKXNeQMrHwNd7E4jPDJYUXmEGTFdMRfyfMw+FPyh04oKMjAiDuOi64bYgVkOV3MjK+loImFhQ==", + "engines": { + "node": ">=v14.0.0", + "npm": ">=7.0.0" + } + }, + "node_modules/@tokenizer/token": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/@tokenizer/token/-/token-0.3.0.tgz", + "integrity": "sha512-OvjF+z51L3ov0OyAU0duzsYuvO01PH7x4t6DJx+guahgTnBHkhJdG7soQeTSFLWN3efnHyibZ4Z8l2EuWwJN3A==" + }, + "node_modules/@types/node": { + "version": "18.0.6", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.0.6.tgz", + "integrity": "sha512-/xUq6H2aQm261exT6iZTMifUySEt4GR5KX8eYyY+C4MSNPqSh9oNIP7tz2GLKTlFaiBbgZNxffoR3CVRG+cljw==" + }, + "node_modules/@types/ws": { + "version": "8.5.3", + "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.3.tgz", + "integrity": "sha512-6YOoWjruKj1uLf3INHH7D3qTXwFfEsg1kf3c0uDdSBJwfa/llkwIjrAGV7j7mVgGNbzTQ3HiHKKDXl6bJPD97w==", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/discord-api-types": { + "version": "0.36.3", + "resolved": "https://registry.npmjs.org/discord-api-types/-/discord-api-types-0.36.3.tgz", + "integrity": "sha512-bz/NDyG0KBo/tY14vSkrwQ/n3HKPf87a0WFW/1M9+tXYK+vp5Z5EksawfCWo2zkAc6o7CClc0eff1Pjrqznlwg==" + }, + "node_modules/discord.js": { + "version": "14.0.3", + "resolved": "https://registry.npmjs.org/discord.js/-/discord.js-14.0.3.tgz", + "integrity": "sha512-wH/VQl4CqN8/+dcXEtYis1iurqxGlDpEe0O4CqH5FGqZGIjVpTdtK0STXXx7bVNX8MT/0GvLZLkmO/5gLDWZVg==", + "dependencies": { + "@discordjs/builders": "^1.0.0", + "@discordjs/collection": "^1.0.0", + "@discordjs/rest": "^1.0.0", + "@sapphire/snowflake": "^3.2.2", + "@types/ws": "^8.5.3", + "discord-api-types": "^0.36.2", + "fast-deep-equal": "^3.1.3", + "lodash.snakecase": "^4.1.1", + "tslib": "^2.4.0", + "undici": "^5.8.0", + "ws": "^8.8.1" + }, + "engines": { + "node": ">=16.9.0" + } + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" + }, + "node_modules/file-type": { + "version": "17.1.2", + "resolved": "https://registry.npmjs.org/file-type/-/file-type-17.1.2.tgz", + "integrity": "sha512-3thBUSfa9YEUEGO/NAAiQGvjujZxZiJTF6xNwyDn6kB0NcEtwMn5ttkGG9jGwm/Nt/t8U1bpBNqyBNZCz4F4ig==", + "dependencies": { + "readable-web-to-node-stream": "^3.0.2", + "strtok3": "^7.0.0-alpha.7", + "token-types": "^5.0.0-alpha.2" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sindresorhus/file-type?sponsor=1" + } + }, + "node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "node_modules/lodash.snakecase": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lodash.snakecase/-/lodash.snakecase-4.1.1.tgz", + "integrity": "sha512-QZ1d4xoBHYUeuouhEq3lk3Uq7ldgyFXGBhg04+oRLnIz8o9T65Eh+8YdroUwn846zchkA9yDsDl5CVVaV2nqYw==" + }, + "node_modules/lodash.uniqwith": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.uniqwith/-/lodash.uniqwith-4.5.0.tgz", + "integrity": "sha512-7lYL8bLopMoy4CTICbxygAUq6CdRJ36vFc80DucPueUee+d5NBRxz3FdT9Pes/HEx5mPoT9jwnsEJWz1N7uq7Q==" + }, + "node_modules/peek-readable": { + "version": "5.0.0-alpha.5", + "resolved": "https://registry.npmjs.org/peek-readable/-/peek-readable-5.0.0-alpha.5.tgz", + "integrity": "sha512-pJohF/tDwV3ntnT5+EkUo4E700q/j/OCDuPxtM+5/kFGjyOai/sK4/We4Cy1MB2OiTQliWU5DxPvYIKQAdPqAA==", + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Borewit" + } + }, + "node_modules/readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/readable-web-to-node-stream": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/readable-web-to-node-stream/-/readable-web-to-node-stream-3.0.2.tgz", + "integrity": "sha512-ePeK6cc1EcKLEhJFt/AebMCLL+GgSKhuygrZ/GLaKZYEecIgIECf4UaUuaByiGtzckwR4ain9VzUh95T1exYGw==", + "dependencies": { + "readable-stream": "^3.6.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Borewit" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/strtok3": { + "version": "7.0.0-alpha.8", + "resolved": "https://registry.npmjs.org/strtok3/-/strtok3-7.0.0-alpha.8.tgz", + "integrity": "sha512-u+k19v+rTxBjGYxncRQjGvZYwYvEd0uP3D+uHKe/s4WB1eXS5ZwpZsTlBu5xSS4zEd89mTXECXg6WW3FSeV8cA==", + "dependencies": { + "@tokenizer/token": "^0.3.0", + "peek-readable": "^5.0.0-alpha.5" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Borewit" + } + }, + "node_modules/token-types": { + "version": "5.0.0-alpha.2", + "resolved": "https://registry.npmjs.org/token-types/-/token-types-5.0.0-alpha.2.tgz", + "integrity": "sha512-EsG9UxAW4M6VATrEEjhPFTKEUi1OiJqTUMIZOGBN49fGxYjZB36k0p7to3HZSmWRoHm1QfZgrg3e02fpqAt5fQ==", + "dependencies": { + "@tokenizer/token": "^0.3.0", + "ieee754": "^1.2.1" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Borewit" + } + }, + "node_modules/ts-mixer": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ts-mixer/-/ts-mixer-6.0.1.tgz", + "integrity": "sha512-hvE+ZYXuINrx6Ei6D6hz+PTim0Uf++dYbK9FFifLNwQj+RwKquhQpn868yZsCtJYiclZF1u8l6WZxxKi+vv7Rg==" + }, + "node_modules/tslib": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz", + "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==" + }, + "node_modules/undici": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/undici/-/undici-5.8.0.tgz", + "integrity": "sha512-1F7Vtcez5w/LwH2G2tGnFIihuWUlc58YidwLiCv+jR2Z50x0tNXpRRw7eOIJ+GvqCqIkg9SB7NWAJ/T9TLfv8Q==", + "engines": { + "node": ">=12.18" + } + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" + }, + "node_modules/ws": { + "version": "8.8.1", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.8.1.tgz", + "integrity": "sha512-bGy2JzvzkPowEJV++hF07hAD6niYSr0JzBNo/J29WsB57A2r7Wlc1UFcTR9IzrPvuNVO4B8LGqF8qcpsVOhJCA==", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + } + }, + "dependencies": { + "@discordjs/builders": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@discordjs/builders/-/builders-1.0.0.tgz", + "integrity": "sha512-8y91ZfpOHubiGJu5tVyGI9tQCEyHZDTeqUWVcJd0dq7B96xIf84S0L4fwmD1k9zTe1eqEFSk0gc7BpY+FKn7Ww==", + "requires": { + "@sapphire/shapeshift": "^3.5.1", + "discord-api-types": "^0.36.2", + "fast-deep-equal": "^3.1.3", + "ts-mixer": "^6.0.1", + "tslib": "^2.4.0" + } + }, + "@discordjs/collection": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@discordjs/collection/-/collection-1.0.0.tgz", + "integrity": "sha512-nAxDQYE5dNAzEGQ7HU20sujDsG5vLowUKCEqZkKUIlrXERZFTt/60zKUj/g4+AVCGeq+pXC5hivMaNtiC+PY5Q==" + }, + "@discordjs/rest": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@discordjs/rest/-/rest-1.0.0.tgz", + "integrity": "sha512-uDAvnE0P2a8axMdD4C51EGjvCRQ2HZk2Yxf6vHWZgIqG87D8DGKMPwmquIxrrB07MjV+rwci2ObU+mGhGP+bJg==", + "requires": { + "@discordjs/collection": "^1.0.0", + "@sapphire/async-queue": "^1.3.2", + "@sapphire/snowflake": "^3.2.2", + "discord-api-types": "^0.36.2", + "file-type": "^17.1.2", + "tslib": "^2.4.0", + "undici": "^5.7.0" + } + }, + "@sapphire/async-queue": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/@sapphire/async-queue/-/async-queue-1.3.2.tgz", + "integrity": "sha512-rUpMLATsoAMnlN3gecAcr9Ecnw1vG7zi5Xr+IX22YzRzi1k9PF9vKzoT8RuEJbiIszjcimu3rveqUnvwDopz8g==" + }, + "@sapphire/shapeshift": { + "version": "3.5.1", + "resolved": "https://registry.npmjs.org/@sapphire/shapeshift/-/shapeshift-3.5.1.tgz", + "integrity": "sha512-7JFsW5IglyOIUQI1eE0g6h06D/Far6HqpcowRScgCiLSqTf3hhkPWCWotVTtVycnDCMYIwPeaw6IEPBomKC8pA==", + "requires": { + "fast-deep-equal": "^3.1.3", + "lodash.uniqwith": "^4.5.0" + } + }, + "@sapphire/snowflake": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/@sapphire/snowflake/-/snowflake-3.2.2.tgz", + "integrity": "sha512-ula2O0kpSZtX9rKXNeQMrHwNd7E4jPDJYUXmEGTFdMRfyfMw+FPyh04oKMjAiDuOi64bYgVkOV3MjK+loImFhQ==" + }, + "@tokenizer/token": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/@tokenizer/token/-/token-0.3.0.tgz", + "integrity": "sha512-OvjF+z51L3ov0OyAU0duzsYuvO01PH7x4t6DJx+guahgTnBHkhJdG7soQeTSFLWN3efnHyibZ4Z8l2EuWwJN3A==" + }, + "@types/node": { + "version": "18.0.6", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.0.6.tgz", + "integrity": "sha512-/xUq6H2aQm261exT6iZTMifUySEt4GR5KX8eYyY+C4MSNPqSh9oNIP7tz2GLKTlFaiBbgZNxffoR3CVRG+cljw==" + }, + "@types/ws": { + "version": "8.5.3", + "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.3.tgz", + "integrity": "sha512-6YOoWjruKj1uLf3INHH7D3qTXwFfEsg1kf3c0uDdSBJwfa/llkwIjrAGV7j7mVgGNbzTQ3HiHKKDXl6bJPD97w==", + "requires": { + "@types/node": "*" + } + }, + "discord-api-types": { + "version": "0.36.3", + "resolved": "https://registry.npmjs.org/discord-api-types/-/discord-api-types-0.36.3.tgz", + "integrity": "sha512-bz/NDyG0KBo/tY14vSkrwQ/n3HKPf87a0WFW/1M9+tXYK+vp5Z5EksawfCWo2zkAc6o7CClc0eff1Pjrqznlwg==" + }, + "discord.js": { + "version": "14.0.3", + "resolved": "https://registry.npmjs.org/discord.js/-/discord.js-14.0.3.tgz", + "integrity": "sha512-wH/VQl4CqN8/+dcXEtYis1iurqxGlDpEe0O4CqH5FGqZGIjVpTdtK0STXXx7bVNX8MT/0GvLZLkmO/5gLDWZVg==", + "requires": { + "@discordjs/builders": "^1.0.0", + "@discordjs/collection": "^1.0.0", + "@discordjs/rest": "^1.0.0", + "@sapphire/snowflake": "^3.2.2", + "@types/ws": "^8.5.3", + "discord-api-types": "^0.36.2", + "fast-deep-equal": "^3.1.3", + "lodash.snakecase": "^4.1.1", + "tslib": "^2.4.0", + "undici": "^5.8.0", + "ws": "^8.8.1" + } + }, + "fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" + }, + "file-type": { + "version": "17.1.2", + "resolved": "https://registry.npmjs.org/file-type/-/file-type-17.1.2.tgz", + "integrity": "sha512-3thBUSfa9YEUEGO/NAAiQGvjujZxZiJTF6xNwyDn6kB0NcEtwMn5ttkGG9jGwm/Nt/t8U1bpBNqyBNZCz4F4ig==", + "requires": { + "readable-web-to-node-stream": "^3.0.2", + "strtok3": "^7.0.0-alpha.7", + "token-types": "^5.0.0-alpha.2" + } + }, + "ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==" + }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "lodash.snakecase": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lodash.snakecase/-/lodash.snakecase-4.1.1.tgz", + "integrity": "sha512-QZ1d4xoBHYUeuouhEq3lk3Uq7ldgyFXGBhg04+oRLnIz8o9T65Eh+8YdroUwn846zchkA9yDsDl5CVVaV2nqYw==" + }, + "lodash.uniqwith": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.uniqwith/-/lodash.uniqwith-4.5.0.tgz", + "integrity": "sha512-7lYL8bLopMoy4CTICbxygAUq6CdRJ36vFc80DucPueUee+d5NBRxz3FdT9Pes/HEx5mPoT9jwnsEJWz1N7uq7Q==" + }, + "peek-readable": { + "version": "5.0.0-alpha.5", + "resolved": "https://registry.npmjs.org/peek-readable/-/peek-readable-5.0.0-alpha.5.tgz", + "integrity": "sha512-pJohF/tDwV3ntnT5+EkUo4E700q/j/OCDuPxtM+5/kFGjyOai/sK4/We4Cy1MB2OiTQliWU5DxPvYIKQAdPqAA==" + }, + "readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + }, + "readable-web-to-node-stream": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/readable-web-to-node-stream/-/readable-web-to-node-stream-3.0.2.tgz", + "integrity": "sha512-ePeK6cc1EcKLEhJFt/AebMCLL+GgSKhuygrZ/GLaKZYEecIgIECf4UaUuaByiGtzckwR4ain9VzUh95T1exYGw==", + "requires": { + "readable-stream": "^3.6.0" + } + }, + "safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" + }, + "string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "requires": { + "safe-buffer": "~5.2.0" + } + }, + "strtok3": { + "version": "7.0.0-alpha.8", + "resolved": "https://registry.npmjs.org/strtok3/-/strtok3-7.0.0-alpha.8.tgz", + "integrity": "sha512-u+k19v+rTxBjGYxncRQjGvZYwYvEd0uP3D+uHKe/s4WB1eXS5ZwpZsTlBu5xSS4zEd89mTXECXg6WW3FSeV8cA==", + "requires": { + "@tokenizer/token": "^0.3.0", + "peek-readable": "^5.0.0-alpha.5" + } + }, + "token-types": { + "version": "5.0.0-alpha.2", + "resolved": "https://registry.npmjs.org/token-types/-/token-types-5.0.0-alpha.2.tgz", + "integrity": "sha512-EsG9UxAW4M6VATrEEjhPFTKEUi1OiJqTUMIZOGBN49fGxYjZB36k0p7to3HZSmWRoHm1QfZgrg3e02fpqAt5fQ==", + "requires": { + "@tokenizer/token": "^0.3.0", + "ieee754": "^1.2.1" + } + }, + "ts-mixer": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ts-mixer/-/ts-mixer-6.0.1.tgz", + "integrity": "sha512-hvE+ZYXuINrx6Ei6D6hz+PTim0Uf++dYbK9FFifLNwQj+RwKquhQpn868yZsCtJYiclZF1u8l6WZxxKi+vv7Rg==" + }, + "tslib": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz", + "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==" + }, + "undici": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/undici/-/undici-5.8.0.tgz", + "integrity": "sha512-1F7Vtcez5w/LwH2G2tGnFIihuWUlc58YidwLiCv+jR2Z50x0tNXpRRw7eOIJ+GvqCqIkg9SB7NWAJ/T9TLfv8Q==" + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" + }, + "ws": { + "version": "8.8.1", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.8.1.tgz", + "integrity": "sha512-bGy2JzvzkPowEJV++hF07hAD6niYSr0JzBNo/J29WsB57A2r7Wlc1UFcTR9IzrPvuNVO4B8LGqF8qcpsVOhJCA==", + "requires": {} + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..2ba124a --- /dev/null +++ b/package.json @@ -0,0 +1,17 @@ +{ + "name": "discord-bot", + "version": "0.1.0", + "description": "A discord bot for aNetwork.uk", + "main": "app.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "author": "Nathan 'Aney' Steel", + "license": "ISC", + "dependencies": { + "@discordjs/builders": "^1.0.0", + "@discordjs/rest": "^1.0.0", + "discord-api-types": "^0.36.3", + "discord.js": "^14.0.3" + } +} From 1864565977c8936a1d932e5bc2312777a8345ed2 Mon Sep 17 00:00:00 2001 From: Nathan Steel Date: Mon, 1 Aug 2022 10:27:48 -0400 Subject: [PATCH 2/3] Add command for self-role management --- commands/roles.js | 54 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) create mode 100644 commands/roles.js diff --git a/commands/roles.js b/commands/roles.js new file mode 100644 index 0000000..c089f65 --- /dev/null +++ b/commands/roles.js @@ -0,0 +1,54 @@ +const { SlashCommandBuilder } = require('@discordjs/builders'); + +module.exports = { + data: new SlashCommandBuilder() + .setName('role') + .setDescription('Apply a role to yourself, or remove yourself from it. Toggley') + .addStringOption(option => + option.setName("role") + .setDescription('The role you wish to join') + .setRequired(true) + .addChoices( + { name: 'Smite', value: '843092235016208404' }, + { name: 'Factorio', value: '995806023094894642' }, + { name: 'Minecraft', value: '854460008292286494' }, + )), + async execute(interaction) { + + // Get role id from the choice + let roleId = interaction.options.getString('role'); + // Then get the role itself + let role = interaction.guild.roles.cache.get(roleId); + + // If the role doesn't exist, then exit + if (!role){ + await interaction.reply('Role not found'); + console.log('Role not found ' + roleId); + return; + } + + // TODO: + // Check if the user is already in role. + // If they are we want to remove them + if (interaction.member.roles.cache.has(roleId)) { + console.log('in role already'); + var reply = 'You\'ve been removed from the role ' + interaction.options.getString('role'); + // Remove user from role + interaction.member.roles.remove(role); + } + else { + var reply = 'You\'ve been added to the role ' + interaction.options.getString('role'); + // Add user to role + interaction.member.roles.add(role); + } + + // Return message to the user in Discord channel + // Ephemeral only shows to the person that called the command + await interaction.reply({ + content: reply, + ephemeral: true + }); + + }, +}; + From 05514930f48953bada100571389f63c03184254b Mon Sep 17 00:00:00 2001 From: Nathan Steel Date: Fri, 18 Sep 2026 12:21:11 +0100 Subject: [PATCH 3/3] Remove public facing IDs, and add a roll die Picked up after a long while, cause spotted in my git repo --- commands/roles.js | 5 +++-- commands/roll.js | 13 +++++++++++++ commands/user.js | 6 +++++- package-lock.json | 4 ++-- 4 files changed, 23 insertions(+), 5 deletions(-) create mode 100644 commands/roll.js diff --git a/commands/roles.js b/commands/roles.js index c089f65..b53e959 100644 --- a/commands/roles.js +++ b/commands/roles.js @@ -32,12 +32,13 @@ module.exports = { // If they are we want to remove them if (interaction.member.roles.cache.has(roleId)) { console.log('in role already'); - var reply = 'You\'ve been removed from the role ' + interaction.options.getString('role'); + //var reply = 'You\'ve been removed from the role ' + interaction.options.getString('role'); + var reply = 'You\'ve been removed from the role ' + role.name; // Remove user from role interaction.member.roles.remove(role); } else { - var reply = 'You\'ve been added to the role ' + interaction.options.getString('role'); + var reply = 'You\'ve been added to the role ' + role.name; // Add user to role interaction.member.roles.add(role); } diff --git a/commands/roll.js b/commands/roll.js new file mode 100644 index 0000000..b58336f --- /dev/null +++ b/commands/roll.js @@ -0,0 +1,13 @@ +const { SlashCommandBuilder } = require('@discordjs/builders'); + +module.exports = { + data: new SlashCommandBuilder() + .setName('roll') + .setDescription('Rolls a die'), + async execute(interaction) { + let die_sides = 6; + let random_number = Math.floor(Math.random() * die_sides) + 1; + await interaction.reply(`${interaction.user.username} rolled a ${random_number}`); + }, +}; + diff --git a/commands/user.js b/commands/user.js index 5093742..385484a 100644 --- a/commands/user.js +++ b/commands/user.js @@ -5,7 +5,11 @@ module.exports = { .setName('user') .setDescription('User info'), async execute(interaction) { - await interaction.reply(`Your tag: ${interaction.user.tag}\nYour id: ${interaction.user.id}`); + await interaction.reply( + { + content:`Your tag: ${interaction.user.tag}\nYour id: ${interaction.user.id}` + ,ephemeral: true + }); }, }; diff --git a/package-lock.json b/package-lock.json index 328b7c1..e41b3f0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "discord-bot", - "version": "1.0.0", + "version": "0.1.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "discord-bot", - "version": "1.0.0", + "version": "0.1.0", "license": "ISC", "dependencies": { "@discordjs/builders": "^1.0.0",