diff options
-rw-r--r-- | .gitignore | 4 | ||||
-rw-r--r-- | app.js | 79 | ||||
-rw-r--r-- | commands.js | 81 | ||||
-rw-r--r-- | package-lock.json | 341 | ||||
-rw-r--r-- | package.json | 4 | ||||
-rw-r--r-- | utils.js | 47 |
6 files changed, 455 insertions, 101 deletions
diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..1012323 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +/.env +.env +jobs.json +/node_modules/ @@ -6,44 +6,89 @@ import { InteractionResponseType, verifyKeyMiddleware, } from 'discord-interactions'; +import { Client, GatewayIntentBits } from 'discord.js'; +import fs from 'node:fs'; +import { v4 as uuidv4 } from 'uuid'; + +const client = new Client ({ intents: [GatewayIntentBits.Guilds] }); +var jobs = {}; +const job_crons = {}; +client.on('ready', () => { + console.log(`Logged in as ${client.user.tag}!`); + fs.readFile('jobs.json', 'utf8', (err,data) => { + jobs = err ? {} : JSON.parse(data); + + Object.keys(jobs).forEach((job) => { + job_crons[job] = cron.schedule(jobs[job].crontab, () => { + client.channels.cache.get(jobs[job].channel_id).send(jobs[job].message); + }); + }); + }); +}); + +client.login(process.env.DISCORD_TOKEN); -// Create an express app const app = express(); -// Get port, or default to 3000 const PORT = process.env.PORT || 3000; -/** - * Interactions endpoint URL where Discord will send HTTP requests - * Parse request body and verifies incoming requests using discord-interactions package - */ app.post('/', verifyKeyMiddleware(process.env.PUBLIC_KEY), async function (req, res) { - // Interaction type and data const { type, data } = req.body; - /** - * Handle verification requests - */ if (type === InteractionType.PING) { return res.send({ type: InteractionResponseType.PONG }); } - /** - * Handle slash command requests - * See https://discord.com/developers/docs/interactions/application-commands#slash-commands - */ if (type === InteractionType.APPLICATION_COMMAND) { - const { name, options } = data; + const { name, options, guild_id } = data; if (name === 'schedule_message') { const message = options[0].value; const crontab = options[1].value; const valid = cron.validate(crontab); + const id = uuidv4(); - const content = valid ? 'registered message "' + message + '" with cron "' + crontab + '"' : 'invalid cron'; + const content = valid ? `registered message: "${message}" with cron: "${crontab}" and id: "${id}"` : 'invalid cron'; if (valid) { + jobs[id] = { + message: message, + crontab: crontab, + channel_id: req.body.channel_id, + }; + job_crons[id] = cron.schedule(crontab, () => { + client.channels.cache.get(req.body.channel_id).send(message); + }); + + const json = JSON.stringify(jobs); + fs.writeFile('jobs.json', json, 'utf8', err => { + if (err) { + console.error(err); + } + }); + cron.schedule(crontab, () => { - console.log(message); + client.channels.cache.get(req.body.channel_id).send(message) + }); + } + + return res.send({ + type: InteractionResponseType.CHANNEL_MESSAGE_WITH_SOURCE, + data: { + content: content, + }, + }); + } else if (name === 'unschedule_message') { + const id = options[0].value; + const content = id in jobs ? `stopped job ${id}` : `no such job ${id}`; + if (id in jobs) { + delete jobs[id] + delete job_crons[id]; + + const json = JSON.stringify(jobs); + fs.writeFile('jobs.json', json, 'utf8', err => { + if (err) { + console.error(err); + } }); } diff --git a/commands.js b/commands.js index 7df2f8c..2af766a 100644 --- a/commands.js +++ b/commands.js @@ -1,35 +1,54 @@ import 'dotenv/config'; -import {InstallGlobalCommands} from './utils.js'; -const SCHEDULE_MESSAGE = { - name: 'schedule_message', - description: 'Register a message to be sent at a specific time', - type: 1, - options: [ - { - type: 3, - name: 'message', - description: 'the message to send', - required: true, - }, - { - type: 3, - name: 'crontab_string', - description: 'the time the message should be sent at in crontab format', - required: true, - }, - { - type: 4, - name: 'repeat', - description: 'how many times should the message be repeated? (0 is infinite and the default)', - required: false, - min_value: 0, - }, - ], - integration_types: [0, 1], - contexts: [0, 1, 2], -}; +import { REST, Routes } from 'discord.js'; -const ALL_COMMANDS = [SCHEDULE_MESSAGE]; +const commands = [ + { + name: 'schedule_message', + description: 'Register a message to run as a cron job', + type: 1, + options: [ + { + type: 3, + name: 'message', + description: 'the message to send', + required: true, + }, + { + type: 3, + name: 'crontab', + description: 'the schedule for the message', + required: true, + }, + ], + integration_types: [0], + contexts: [0], + }, + { + name: 'unschedule_message', + description: 'Stop sending a scheduled message', + type: 1, + options: [ + { + type: 3, + name: 'id', + description: 'the id of the message to stop', + required: true, + }, + ], + integration_types: [0], + contexts: [0], + }, +]; -InstallGlobalCommands(process.env.APP_ID, ALL_COMMANDS); +const rest = new REST({ version: '10' }).setToken(process.env.DISCORD_TOKEN); + +try { + console.log('Started refreshing application commands.'); + + await rest.put(Routes.applicationCommands(process.env.APP_ID), { body: commands }); + + console.log('Successfully reloaded application commands.'); +} catch (error) { + console.error(error); +} diff --git a/package-lock.json b/package-lock.json index 42d52cb..256eba1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,9 +10,11 @@ "license": "MIT", "dependencies": { "discord-interactions": "^4.0.0", + "discord.js": "^14.16.3", "dotenv": "^16.0.3", "express": "^4.18.2", - "node-cron": "^3.0.3" + "node-cron": "^3.0.3", + "uuid": "^11.0.3" }, "devDependencies": { "nodemon": "^3.0.0" @@ -21,6 +23,218 @@ "node": ">=18.x" } }, + "node_modules/@discordjs/builders": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@discordjs/builders/-/builders-1.9.0.tgz", + "integrity": "sha512-0zx8DePNVvQibh5ly5kCEei5wtPBIUbSoE9n+91Rlladz4tgtFbJ36PZMxxZrTEOQ7AHMZ/b0crT/0fCy6FTKg==", + "license": "Apache-2.0", + "dependencies": { + "@discordjs/formatters": "^0.5.0", + "@discordjs/util": "^1.1.1", + "@sapphire/shapeshift": "^4.0.0", + "discord-api-types": "0.37.97", + "fast-deep-equal": "^3.1.3", + "ts-mixer": "^6.0.4", + "tslib": "^2.6.3" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/discordjs/discord.js?sponsor" + } + }, + "node_modules/@discordjs/builders/node_modules/discord-api-types": { + "version": "0.37.97", + "resolved": "https://registry.npmjs.org/discord-api-types/-/discord-api-types-0.37.97.tgz", + "integrity": "sha512-No1BXPcVkyVD4ZVmbNgDKaBoqgeQ+FJpzZ8wqHkfmBnTZig1FcH3iPPersiK1TUIAzgClh2IvOuVUYfcWLQAOA==", + "license": "MIT" + }, + "node_modules/@discordjs/collection": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/@discordjs/collection/-/collection-1.5.3.tgz", + "integrity": "sha512-SVb428OMd3WO1paV3rm6tSjM4wC+Kecaa1EUGX7vc6/fddvw/6lg90z4QtCqm21zvVe92vMMDt9+DkIvjXImQQ==", + "license": "Apache-2.0", + "engines": { + "node": ">=16.11.0" + } + }, + "node_modules/@discordjs/formatters": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/@discordjs/formatters/-/formatters-0.5.0.tgz", + "integrity": "sha512-98b3i+Y19RFq1Xke4NkVY46x8KjJQjldHUuEbCqMvp1F5Iq9HgnGpu91jOi/Ufazhty32eRsKnnzS8n4c+L93g==", + "license": "Apache-2.0", + "dependencies": { + "discord-api-types": "0.37.97" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/discordjs/discord.js?sponsor" + } + }, + "node_modules/@discordjs/formatters/node_modules/discord-api-types": { + "version": "0.37.97", + "resolved": "https://registry.npmjs.org/discord-api-types/-/discord-api-types-0.37.97.tgz", + "integrity": "sha512-No1BXPcVkyVD4ZVmbNgDKaBoqgeQ+FJpzZ8wqHkfmBnTZig1FcH3iPPersiK1TUIAzgClh2IvOuVUYfcWLQAOA==", + "license": "MIT" + }, + "node_modules/@discordjs/rest": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/@discordjs/rest/-/rest-2.4.0.tgz", + "integrity": "sha512-Xb2irDqNcq+O8F0/k/NaDp7+t091p+acb51iA4bCKfIn+WFWd6HrNvcsSbMMxIR9NjcMZS6NReTKygqiQN+ntw==", + "license": "Apache-2.0", + "dependencies": { + "@discordjs/collection": "^2.1.1", + "@discordjs/util": "^1.1.1", + "@sapphire/async-queue": "^1.5.3", + "@sapphire/snowflake": "^3.5.3", + "@vladfrangu/async_event_emitter": "^2.4.6", + "discord-api-types": "0.37.97", + "magic-bytes.js": "^1.10.0", + "tslib": "^2.6.3", + "undici": "6.19.8" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/discordjs/discord.js?sponsor" + } + }, + "node_modules/@discordjs/rest/node_modules/@discordjs/collection": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@discordjs/collection/-/collection-2.1.1.tgz", + "integrity": "sha512-LiSusze9Tc7qF03sLCujF5iZp7K+vRNEDBZ86FT9aQAv3vxMLihUvKvpsCWiQ2DJq1tVckopKm1rxomgNUc9hg==", + "license": "Apache-2.0", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/discordjs/discord.js?sponsor" + } + }, + "node_modules/@discordjs/rest/node_modules/discord-api-types": { + "version": "0.37.97", + "resolved": "https://registry.npmjs.org/discord-api-types/-/discord-api-types-0.37.97.tgz", + "integrity": "sha512-No1BXPcVkyVD4ZVmbNgDKaBoqgeQ+FJpzZ8wqHkfmBnTZig1FcH3iPPersiK1TUIAzgClh2IvOuVUYfcWLQAOA==", + "license": "MIT" + }, + "node_modules/@discordjs/util": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@discordjs/util/-/util-1.1.1.tgz", + "integrity": "sha512-eddz6UnOBEB1oITPinyrB2Pttej49M9FZQY8NxgEvc3tq6ZICZ19m70RsmzRdDHk80O9NoYN/25AqJl8vPVf/g==", + "license": "Apache-2.0", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/discordjs/discord.js?sponsor" + } + }, + "node_modules/@discordjs/ws": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@discordjs/ws/-/ws-1.1.1.tgz", + "integrity": "sha512-PZ+vLpxGCRtmr2RMkqh8Zp+BenUaJqlS6xhgWKEZcgC/vfHLEzpHtKkB0sl3nZWpwtcKk6YWy+pU3okL2I97FA==", + "license": "Apache-2.0", + "dependencies": { + "@discordjs/collection": "^2.1.0", + "@discordjs/rest": "^2.3.0", + "@discordjs/util": "^1.1.0", + "@sapphire/async-queue": "^1.5.2", + "@types/ws": "^8.5.10", + "@vladfrangu/async_event_emitter": "^2.2.4", + "discord-api-types": "0.37.83", + "tslib": "^2.6.2", + "ws": "^8.16.0" + }, + "engines": { + "node": ">=16.11.0" + }, + "funding": { + "url": "https://github.com/discordjs/discord.js?sponsor" + } + }, + "node_modules/@discordjs/ws/node_modules/@discordjs/collection": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@discordjs/collection/-/collection-2.1.1.tgz", + "integrity": "sha512-LiSusze9Tc7qF03sLCujF5iZp7K+vRNEDBZ86FT9aQAv3vxMLihUvKvpsCWiQ2DJq1tVckopKm1rxomgNUc9hg==", + "license": "Apache-2.0", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/discordjs/discord.js?sponsor" + } + }, + "node_modules/@discordjs/ws/node_modules/discord-api-types": { + "version": "0.37.83", + "resolved": "https://registry.npmjs.org/discord-api-types/-/discord-api-types-0.37.83.tgz", + "integrity": "sha512-urGGYeWtWNYMKnYlZnOnDHm8fVRffQs3U0SpE8RHeiuLKb/u92APS8HoQnPTFbnXmY1vVnXjXO4dOxcAn3J+DA==", + "license": "MIT" + }, + "node_modules/@sapphire/async-queue": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@sapphire/async-queue/-/async-queue-1.5.5.tgz", + "integrity": "sha512-cvGzxbba6sav2zZkH8GPf2oGk9yYoD5qrNWdu9fRehifgnFZJMV+nuy2nON2roRO4yQQ+v7MK/Pktl/HgfsUXg==", + "license": "MIT", + "engines": { + "node": ">=v14.0.0", + "npm": ">=7.0.0" + } + }, + "node_modules/@sapphire/shapeshift": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@sapphire/shapeshift/-/shapeshift-4.0.0.tgz", + "integrity": "sha512-d9dUmWVA7MMiKobL3VpLF8P2aeanRTu6ypG2OIaEv/ZHH/SUQ2iHOVyi5wAPjQ+HmnMuL0whK9ez8I/raWbtIg==", + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.3", + "lodash": "^4.17.21" + }, + "engines": { + "node": ">=v16" + } + }, + "node_modules/@sapphire/snowflake": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/@sapphire/snowflake/-/snowflake-3.5.3.tgz", + "integrity": "sha512-jjmJywLAFoWeBi1W7994zZyiNWPIiqRRNAmSERxyg93xRGzNYvGjlZ0gR6x0F4gPRi2+0O6S71kOZYyr3cxaIQ==", + "license": "MIT", + "engines": { + "node": ">=v14.0.0", + "npm": ">=7.0.0" + } + }, + "node_modules/@types/node": { + "version": "22.10.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.10.1.tgz", + "integrity": "sha512-qKgsUwfHZV2WCWLAnVP1JqnpE6Im6h3Y0+fYgMTasNQ7V++CBX5OT1as0g0f+OyubbFqhf6XVNIsmN4IIhEgGQ==", + "license": "MIT", + "dependencies": { + "undici-types": "~6.20.0" + } + }, + "node_modules/@types/ws": { + "version": "8.5.13", + "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.13.tgz", + "integrity": "sha512-osM/gWBTPKgHV8XkTunnegTRIsvF6owmf5w+JtAfOw472dptdm0dlGv4xCt6GwQRcC2XVOvvRE/0bAoQcL2QkA==", + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@vladfrangu/async_event_emitter": { + "version": "2.4.6", + "resolved": "https://registry.npmjs.org/@vladfrangu/async_event_emitter/-/async_event_emitter-2.4.6.tgz", + "integrity": "sha512-RaI5qZo6D2CVS6sTHFKg1v5Ohq/+Bo2LZ5gzUEwZ/WkHhwtGTCB/sVLw8ijOkAUxasZ+WshN/Rzj4ywsABJ5ZA==", + "license": "MIT", + "engines": { + "node": ">=v14.0.0", + "npm": ">=7.0.0" + } + }, "node_modules/accepts": { "version": "1.3.8", "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", @@ -275,6 +489,12 @@ "npm": "1.2.8000 || >= 1.4.16" } }, + "node_modules/discord-api-types": { + "version": "0.37.100", + "resolved": "https://registry.npmjs.org/discord-api-types/-/discord-api-types-0.37.100.tgz", + "integrity": "sha512-a8zvUI0GYYwDtScfRd/TtaNBDTXwP5DiDVX7K5OmE+DRT57gBqKnwtOC5Ol8z0mRW8KQfETIgiB8U0YZ9NXiCA==", + "license": "MIT" + }, "node_modules/discord-interactions": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/discord-interactions/-/discord-interactions-4.1.0.tgz", @@ -284,6 +504,32 @@ "node": ">=18.4.0" } }, + "node_modules/discord.js": { + "version": "14.16.3", + "resolved": "https://registry.npmjs.org/discord.js/-/discord.js-14.16.3.tgz", + "integrity": "sha512-EPCWE9OkA9DnFFNrO7Kl1WHHDYFXu3CNVFJg63bfU7hVtjZGyhShwZtSBImINQRWxWP2tgo2XI+QhdXx28r0aA==", + "license": "Apache-2.0", + "dependencies": { + "@discordjs/builders": "^1.9.0", + "@discordjs/collection": "1.5.3", + "@discordjs/formatters": "^0.5.0", + "@discordjs/rest": "^2.4.0", + "@discordjs/util": "^1.1.1", + "@discordjs/ws": "1.1.1", + "@sapphire/snowflake": "3.5.3", + "discord-api-types": "0.37.100", + "fast-deep-equal": "3.1.3", + "lodash.snakecase": "4.1.1", + "tslib": "^2.6.3", + "undici": "6.19.8" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/discordjs/discord.js?sponsor" + } + }, "node_modules/dotenv": { "version": "16.4.7", "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.7.tgz", @@ -404,6 +650,12 @@ "url": "https://opencollective.com/express" } }, + "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==", + "license": "MIT" + }, "node_modules/fill-range": { "version": "7.1.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", @@ -666,6 +918,24 @@ "node": ">=0.12.0" } }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "license": "MIT" + }, + "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==", + "license": "MIT" + }, + "node_modules/magic-bytes.js": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/magic-bytes.js/-/magic-bytes.js-1.10.0.tgz", + "integrity": "sha512-/k20Lg2q8LE5xiaaSkMXk4sfvI+9EGEykFS4b0CHHGWqDYU0bGUFSwchNOMA56D7TCs9GwVTkqe9als1/ns8UQ==", + "license": "MIT" + }, "node_modules/media-typer": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", @@ -766,6 +1036,15 @@ "node": ">=6.0.0" } }, + "node_modules/node-cron/node_modules/uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "license": "MIT", + "bin": { + "uuid": "dist/bin/uuid" + } + }, "node_modules/nodemon": { "version": "3.1.7", "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-3.1.7.tgz", @@ -1155,6 +1434,18 @@ "nodetouch": "bin/nodetouch.js" } }, + "node_modules/ts-mixer": { + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/ts-mixer/-/ts-mixer-6.0.4.tgz", + "integrity": "sha512-ufKpbmrugz5Aou4wcr5Wc1UUFWOLhq+Fm6qa6P0w0K5Qw2yhaUoiWszhCVuNQyNwrlGiscHOmqYoAox1PtvgjA==", + "license": "MIT" + }, + "node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD" + }, "node_modules/type-is": { "version": "1.6.18", "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", @@ -1175,6 +1466,21 @@ "dev": true, "license": "MIT" }, + "node_modules/undici": { + "version": "6.19.8", + "resolved": "https://registry.npmjs.org/undici/-/undici-6.19.8.tgz", + "integrity": "sha512-U8uCCl2x9TK3WANvmBavymRzxbfFYG+tAu+fgx3zxQy3qdagQqBLwJVrdyO1TBfUXvfKveMKJZhpvUYoOjM+4g==", + "license": "MIT", + "engines": { + "node": ">=18.17" + } + }, + "node_modules/undici-types": { + "version": "6.20.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.20.0.tgz", + "integrity": "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==", + "license": "MIT" + }, "node_modules/unpipe": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", @@ -1194,12 +1500,16 @@ } }, "node_modules/uuid": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", - "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "version": "11.0.3", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-11.0.3.tgz", + "integrity": "sha512-d0z310fCWv5dJwnX1Y/MncBAqGMKEzlBb1AOf7z9K8ALnd0utBX/msg/fA0+sbyN1ihbMsLhrBlnl1ak7Wa0rg==", + "funding": [ + "https://github.com/sponsors/broofa", + "https://github.com/sponsors/ctavan" + ], "license": "MIT", "bin": { - "uuid": "dist/bin/uuid" + "uuid": "dist/esm/bin/uuid" } }, "node_modules/vary": { @@ -1210,6 +1520,27 @@ "engines": { "node": ">= 0.8" } + }, + "node_modules/ws": { + "version": "8.18.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz", + "integrity": "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==", + "license": "MIT", + "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 + } + } } } } diff --git a/package.json b/package.json index dbcd515..6872a5c 100644 --- a/package.json +++ b/package.json @@ -17,9 +17,11 @@ "license": "MIT", "dependencies": { "discord-interactions": "^4.0.0", + "discord.js": "^14.16.3", "dotenv": "^16.0.3", "express": "^4.18.2", - "node-cron": "^3.0.3" + "node-cron": "^3.0.3", + "uuid": "^11.0.3" }, "devDependencies": { "nodemon": "^3.0.0" diff --git a/utils.js b/utils.js deleted file mode 100644 index 506aea6..0000000 --- a/utils.js +++ /dev/null @@ -1,47 +0,0 @@ -import 'dotenv/config'; - -export async function DiscordRequest(endpoint, options) { - // append endpoint to root API URL - const url = 'https://discord.com/api/v10/' + endpoint; - // Stringify payloads - if (options.body) options.body = JSON.stringify(options.body); - // Use fetch to make requests - const res = await fetch(url, { - headers: { - Authorization: `Bot ${process.env.DISCORD_TOKEN}`, - 'Content-Type': 'application/json; charset=UTF-8', - 'User-Agent': 'DiscordBot (https://github.com/discord/discord-example-app, 1.0.0)', - }, - ...options - }); - // throw API errors - if (!res.ok) { - const data = await res.json(); - console.log(res.status); - throw new Error(JSON.stringify(data)); - } - // return original response - return res; -} - -export async function InstallGlobalCommands(appId, commands) { - // API endpoint to overwrite global commands - const endpoint = `applications/${appId}/commands`; - - try { - // This is calling the bulk overwrite endpoint: https://discord.com/developers/docs/interactions/application-commands#bulk-overwrite-global-application-commands - await DiscordRequest(endpoint, { method: 'PUT', body: commands }); - } catch (err) { - console.error(err); - } -} - -// Simple method that returns a random emoji from list -export function getRandomEmoji() { - const emojiList = ['π','π','π','π€','π','π€','π€','πΆβπ«οΈ','π','πΈ','πΏ','π','π','β¨']; - return emojiList[Math.floor(Math.random() * emojiList.length)]; -} - -export function capitalize(str) { - return str.charAt(0).toUpperCase() + str.slice(1); -} |