# This is a combination of 12 commits.
# This is the 1st commit message: Initial commit # This is the commit message #2: added whole syswtem becuz i forgot to keep up with the github # This is the commit message #3: hihi hiha # This is the commit message #4: added startServer.sh # This is the commit message #5: hihi hiha # This is the commit message #6: fixed some packages # This is the commit message #7: fixed every bug with the stupid oop # This is the commit message #8: Revert "fixed every bug with the stupid oop" This reverts commit d2255863aa44e2504f9f2cec9e1ae5d1094cb9cd. # This is the commit message #9: added prevention of breaking the system by manually filling in the project id # This is the commit message #10: fixed bug when adding bot # This is the commit message #11: made user-id not just count up from 0 # This is the commit message #12: fixed the issue where if you load project page it woulnt show the commands until you refresh the page
This commit is contained in:
130
.gitignore
vendored
Executable file
130
.gitignore
vendored
Executable file
@@ -0,0 +1,130 @@
|
||||
# Logs
|
||||
logs
|
||||
*.log
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
lerna-debug.log*
|
||||
.pnpm-debug.log*
|
||||
|
||||
# Diagnostic reports (https://nodejs.org/api/report.html)
|
||||
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
|
||||
|
||||
# Runtime data
|
||||
pids
|
||||
*.pid
|
||||
*.seed
|
||||
*.pid.lock
|
||||
|
||||
# Directory for instrumented libs generated by jscoverage/JSCover
|
||||
lib-cov
|
||||
|
||||
# Coverage directory used by tools like istanbul
|
||||
coverage
|
||||
*.lcov
|
||||
|
||||
# nyc test coverage
|
||||
.nyc_output
|
||||
|
||||
# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
|
||||
.grunt
|
||||
|
||||
# Bower dependency directory (https://bower.io/)
|
||||
bower_components
|
||||
|
||||
# node-waf configuration
|
||||
.lock-wscript
|
||||
|
||||
# Compiled binary addons (https://nodejs.org/api/addons.html)
|
||||
build/Release
|
||||
|
||||
# Dependency directories
|
||||
node_modules/
|
||||
jspm_packages/
|
||||
|
||||
# Snowpack dependency directory (https://snowpack.dev/)
|
||||
web_modules/
|
||||
|
||||
# TypeScript cache
|
||||
*.tsbuildinfo
|
||||
|
||||
# Optional npm cache directory
|
||||
.npm
|
||||
|
||||
# Optional eslint cache
|
||||
.eslintcache
|
||||
|
||||
# Optional stylelint cache
|
||||
.stylelintcache
|
||||
|
||||
# Microbundle cache
|
||||
.rpt2_cache/
|
||||
.rts2_cache_cjs/
|
||||
.rts2_cache_es/
|
||||
.rts2_cache_umd/
|
||||
|
||||
# Optional REPL history
|
||||
.node_repl_history
|
||||
|
||||
# Output of 'npm pack'
|
||||
*.tgz
|
||||
|
||||
# Yarn Integrity file
|
||||
.yarn-integrity
|
||||
|
||||
# dotenv environment variable files
|
||||
.env
|
||||
.env.development.local
|
||||
.env.test.local
|
||||
.env.production.local
|
||||
.env.local
|
||||
|
||||
# parcel-bundler cache (https://parceljs.org/)
|
||||
.cache
|
||||
.parcel-cache
|
||||
|
||||
# Next.js build output
|
||||
.next
|
||||
out
|
||||
|
||||
# Nuxt.js build / generate output
|
||||
.nuxt
|
||||
dist
|
||||
|
||||
# Gatsby files
|
||||
.cache/
|
||||
# Comment in the public line in if your project uses Gatsby and not Next.js
|
||||
# https://nextjs.org/blog/next-9-1#public-directory-support
|
||||
# public
|
||||
|
||||
# vuepress build output
|
||||
.vuepress/dist
|
||||
|
||||
# vuepress v2.x temp and cache directory
|
||||
.temp
|
||||
.cache
|
||||
|
||||
# Docusaurus cache and generated files
|
||||
.docusaurus
|
||||
|
||||
# Serverless directories
|
||||
.serverless/
|
||||
|
||||
# FuseBox cache
|
||||
.fusebox/
|
||||
|
||||
# DynamoDB Local files
|
||||
.dynamodb/
|
||||
|
||||
# TernJS port file
|
||||
.tern-port
|
||||
|
||||
# Stores VSCode versions used for testing VSCode extensions
|
||||
.vscode-test
|
||||
|
||||
# yarn v2
|
||||
.yarn/cache
|
||||
.yarn/unplugged
|
||||
.yarn/build-state.yml
|
||||
.yarn/install-state.gz
|
||||
.pnp.*
|
||||
2
README.md
Executable file
2
README.md
Executable file
@@ -0,0 +1,2 @@
|
||||
# PS-Discord-BotBuilder
|
||||
a wesbite to make discord bots
|
||||
55
example_bot/bot.js
Executable file
55
example_bot/bot.js
Executable file
@@ -0,0 +1,55 @@
|
||||
const { Client, Collection, Events, GatewayIntentBits } = require('discord.js');
|
||||
const { updateCommands } = require("./updateCommands");
|
||||
const { token } = require('./config.json');
|
||||
const fs = require('node:fs');
|
||||
const path = require('node:path');
|
||||
|
||||
const client = new Client({ intents: [GatewayIntentBits.Guilds] });
|
||||
updateCommands();
|
||||
|
||||
|
||||
/** REGISTER COMMANDS **/
|
||||
client.commands = new Collection();
|
||||
const foldersPath = path.join(__dirname, 'commands');
|
||||
const commandFolders = fs.readdirSync(foldersPath);
|
||||
|
||||
for (const folder of commandFolders) {
|
||||
const commandsPath = path.join(foldersPath, folder);
|
||||
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);
|
||||
if ('data' in command && 'execute' in command) {
|
||||
client.commands.set(command.data.name, command);
|
||||
} else {
|
||||
console.log(`[WARNING] The command at ${filePath} is missing a required "data" or "execute" property.`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** SLASH COMMAND HANDLER **/
|
||||
client.on(Events.InteractionCreate, async interaction => {
|
||||
if (interaction.isChatInputCommand()) {
|
||||
const command = client.commands.get(interaction.commandName);
|
||||
if (command) {
|
||||
try {
|
||||
await command.execute(interaction);
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
|
||||
if (!(interaction.replied || interaction.deferred)) {
|
||||
await interaction.reply({ content: 'There was an error while executing this command!', ephemeral: true });
|
||||
}
|
||||
}
|
||||
} else {
|
||||
console.error(`No command matching ${interaction.commandName} was found.`);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
/** READY SEQUENCE **/
|
||||
client.once(Events.ClientReady, c => {
|
||||
console.log(`Ready! Logged in as ${c.user.tag}`);
|
||||
});
|
||||
|
||||
client.login(token);
|
||||
269
example_bot/package-lock.json
generated
Executable file
269
example_bot/package-lock.json
generated
Executable file
@@ -0,0 +1,269 @@
|
||||
{
|
||||
"name": "example_bot",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"dependencies": {
|
||||
"discord.js": "^14.14.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@discordjs/builders": {
|
||||
"version": "1.7.0",
|
||||
"resolved": "https://registry.npmjs.org/@discordjs/builders/-/builders-1.7.0.tgz",
|
||||
"integrity": "sha512-GDtbKMkg433cOZur8Dv6c25EHxduNIBsxeHrsRoIM8+AwmEZ8r0tEpckx/sHwTLwQPOF3e2JWloZh9ofCaMfAw==",
|
||||
"dependencies": {
|
||||
"@discordjs/formatters": "^0.3.3",
|
||||
"@discordjs/util": "^1.0.2",
|
||||
"@sapphire/shapeshift": "^3.9.3",
|
||||
"discord-api-types": "0.37.61",
|
||||
"fast-deep-equal": "^3.1.3",
|
||||
"ts-mixer": "^6.0.3",
|
||||
"tslib": "^2.6.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=16.11.0"
|
||||
}
|
||||
},
|
||||
"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==",
|
||||
"engines": {
|
||||
"node": ">=16.11.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@discordjs/formatters": {
|
||||
"version": "0.3.3",
|
||||
"resolved": "https://registry.npmjs.org/@discordjs/formatters/-/formatters-0.3.3.tgz",
|
||||
"integrity": "sha512-wTcI1Q5cps1eSGhl6+6AzzZkBBlVrBdc9IUhJbijRgVjCNIIIZPgqnUj3ntFODsHrdbGU8BEG9XmDQmgEEYn3w==",
|
||||
"dependencies": {
|
||||
"discord-api-types": "0.37.61"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=16.11.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@discordjs/rest": {
|
||||
"version": "2.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@discordjs/rest/-/rest-2.2.0.tgz",
|
||||
"integrity": "sha512-nXm9wT8oqrYFRMEqTXQx9DUTeEtXUDMmnUKIhZn6O2EeDY9VCdwj23XCPq7fkqMPKdF7ldAfeVKyxxFdbZl59A==",
|
||||
"dependencies": {
|
||||
"@discordjs/collection": "^2.0.0",
|
||||
"@discordjs/util": "^1.0.2",
|
||||
"@sapphire/async-queue": "^1.5.0",
|
||||
"@sapphire/snowflake": "^3.5.1",
|
||||
"@vladfrangu/async_event_emitter": "^2.2.2",
|
||||
"discord-api-types": "0.37.61",
|
||||
"magic-bytes.js": "^1.5.0",
|
||||
"tslib": "^2.6.2",
|
||||
"undici": "5.27.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=16.11.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@discordjs/rest/node_modules/@discordjs/collection": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@discordjs/collection/-/collection-2.0.0.tgz",
|
||||
"integrity": "sha512-YTWIXLrf5FsrLMycpMM9Q6vnZoR/lN2AWX23/Cuo8uOOtS8eHB2dyQaaGnaF8aZPYnttf2bkLMcXn/j6JUOi3w==",
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@discordjs/util": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/@discordjs/util/-/util-1.0.2.tgz",
|
||||
"integrity": "sha512-IRNbimrmfb75GMNEjyznqM1tkI7HrZOf14njX7tCAAUetyZM1Pr8hX/EK2lxBCOgWDRmigbp24fD1hdMfQK5lw==",
|
||||
"engines": {
|
||||
"node": ">=16.11.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@discordjs/ws": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/@discordjs/ws/-/ws-1.0.2.tgz",
|
||||
"integrity": "sha512-+XI82Rm2hKnFwAySXEep4A7Kfoowt6weO6381jgW+wVdTpMS/56qCvoXyFRY0slcv7c/U8My2PwIB2/wEaAh7Q==",
|
||||
"dependencies": {
|
||||
"@discordjs/collection": "^2.0.0",
|
||||
"@discordjs/rest": "^2.1.0",
|
||||
"@discordjs/util": "^1.0.2",
|
||||
"@sapphire/async-queue": "^1.5.0",
|
||||
"@types/ws": "^8.5.9",
|
||||
"@vladfrangu/async_event_emitter": "^2.2.2",
|
||||
"discord-api-types": "0.37.61",
|
||||
"tslib": "^2.6.2",
|
||||
"ws": "^8.14.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=16.11.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@discordjs/ws/node_modules/@discordjs/collection": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@discordjs/collection/-/collection-2.0.0.tgz",
|
||||
"integrity": "sha512-YTWIXLrf5FsrLMycpMM9Q6vnZoR/lN2AWX23/Cuo8uOOtS8eHB2dyQaaGnaF8aZPYnttf2bkLMcXn/j6JUOi3w==",
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@fastify/busboy": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@fastify/busboy/-/busboy-2.1.0.tgz",
|
||||
"integrity": "sha512-+KpH+QxZU7O4675t3mnkQKcZZg56u+K/Ct2K+N2AZYNVK8kyeo/bI18tI8aPm3tvNNRyTWfj6s5tnGNlcbQRsA==",
|
||||
"engines": {
|
||||
"node": ">=14"
|
||||
}
|
||||
},
|
||||
"node_modules/@sapphire/async-queue": {
|
||||
"version": "1.5.0",
|
||||
"resolved": "https://registry.npmjs.org/@sapphire/async-queue/-/async-queue-1.5.0.tgz",
|
||||
"integrity": "sha512-JkLdIsP8fPAdh9ZZjrbHWR/+mZj0wvKS5ICibcLrRI1j84UmLMshx5n9QmL8b95d4onJ2xxiyugTgSAX7AalmA==",
|
||||
"engines": {
|
||||
"node": ">=v14.0.0",
|
||||
"npm": ">=7.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@sapphire/shapeshift": {
|
||||
"version": "3.9.3",
|
||||
"resolved": "https://registry.npmjs.org/@sapphire/shapeshift/-/shapeshift-3.9.3.tgz",
|
||||
"integrity": "sha512-WzKJSwDYloSkHoBbE8rkRW8UNKJiSRJ/P8NqJ5iVq7U2Yr/kriIBx2hW+wj2Z5e5EnXL1hgYomgaFsdK6b+zqQ==",
|
||||
"dependencies": {
|
||||
"fast-deep-equal": "^3.1.3",
|
||||
"lodash": "^4.17.21"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=v14.0.0",
|
||||
"npm": ">=7.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@sapphire/snowflake": {
|
||||
"version": "3.5.1",
|
||||
"resolved": "https://registry.npmjs.org/@sapphire/snowflake/-/snowflake-3.5.1.tgz",
|
||||
"integrity": "sha512-BxcYGzgEsdlG0dKAyOm0ehLGm2CafIrfQTZGWgkfKYbj+pNNsorZ7EotuZukc2MT70E0UbppVbtpBrqpzVzjNA==",
|
||||
"engines": {
|
||||
"node": ">=v14.0.0",
|
||||
"npm": ">=7.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/node": {
|
||||
"version": "20.10.1",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.10.1.tgz",
|
||||
"integrity": "sha512-T2qwhjWwGH81vUEx4EXmBKsTJRXFXNZTL4v0gi01+zyBmCwzE6TyHszqX01m+QHTEq+EZNo13NeJIdEqf+Myrg==",
|
||||
"dependencies": {
|
||||
"undici-types": "~5.26.4"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/ws": {
|
||||
"version": "8.5.9",
|
||||
"resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.9.tgz",
|
||||
"integrity": "sha512-jbdrY0a8lxfdTp/+r7Z4CkycbOFN8WX+IOchLJr3juT/xzbJ8URyTVSJ/hvNdadTgM1mnedb47n+Y31GsFnQlg==",
|
||||
"dependencies": {
|
||||
"@types/node": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@vladfrangu/async_event_emitter": {
|
||||
"version": "2.2.2",
|
||||
"resolved": "https://registry.npmjs.org/@vladfrangu/async_event_emitter/-/async_event_emitter-2.2.2.tgz",
|
||||
"integrity": "sha512-HIzRG7sy88UZjBJamssEczH5q7t5+axva19UbZLO6u0ySbYPrwzWiXBcC0WuHyhKKoeCyneH+FvYzKQq/zTtkQ==",
|
||||
"engines": {
|
||||
"node": ">=v14.0.0",
|
||||
"npm": ">=7.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/discord-api-types": {
|
||||
"version": "0.37.61",
|
||||
"resolved": "https://registry.npmjs.org/discord-api-types/-/discord-api-types-0.37.61.tgz",
|
||||
"integrity": "sha512-o/dXNFfhBpYHpQFdT6FWzeO7pKc838QeeZ9d91CfVAtpr5XLK4B/zYxQbYgPdoMiTDvJfzcsLW5naXgmHGDNXw=="
|
||||
},
|
||||
"node_modules/discord.js": {
|
||||
"version": "14.14.1",
|
||||
"resolved": "https://registry.npmjs.org/discord.js/-/discord.js-14.14.1.tgz",
|
||||
"integrity": "sha512-/hUVzkIerxKHyRKopJy5xejp4MYKDPTszAnpYxzVVv4qJYf+Tkt+jnT2N29PIPschicaEEpXwF2ARrTYHYwQ5w==",
|
||||
"dependencies": {
|
||||
"@discordjs/builders": "^1.7.0",
|
||||
"@discordjs/collection": "1.5.3",
|
||||
"@discordjs/formatters": "^0.3.3",
|
||||
"@discordjs/rest": "^2.1.0",
|
||||
"@discordjs/util": "^1.0.2",
|
||||
"@discordjs/ws": "^1.0.2",
|
||||
"@sapphire/snowflake": "3.5.1",
|
||||
"@types/ws": "8.5.9",
|
||||
"discord-api-types": "0.37.61",
|
||||
"fast-deep-equal": "3.1.3",
|
||||
"lodash.snakecase": "4.1.1",
|
||||
"tslib": "2.6.2",
|
||||
"undici": "5.27.2",
|
||||
"ws": "8.14.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=16.11.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/lodash": {
|
||||
"version": "4.17.21",
|
||||
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
|
||||
"integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="
|
||||
},
|
||||
"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/magic-bytes.js": {
|
||||
"version": "1.5.0",
|
||||
"resolved": "https://registry.npmjs.org/magic-bytes.js/-/magic-bytes.js-1.5.0.tgz",
|
||||
"integrity": "sha512-wJkXvutRbNWcc37tt5j1HyOK1nosspdh3dj6LUYYAvF6JYNqs53IfRvK9oEpcwiDA1NdoIi64yAMfdivPeVAyw=="
|
||||
},
|
||||
"node_modules/ts-mixer": {
|
||||
"version": "6.0.3",
|
||||
"resolved": "https://registry.npmjs.org/ts-mixer/-/ts-mixer-6.0.3.tgz",
|
||||
"integrity": "sha512-k43M7uCG1AkTyxgnmI5MPwKoUvS/bRvLvUb7+Pgpdlmok8AoqmUaZxUUw8zKM5B1lqZrt41GjYgnvAi0fppqgQ=="
|
||||
},
|
||||
"node_modules/tslib": {
|
||||
"version": "2.6.2",
|
||||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz",
|
||||
"integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q=="
|
||||
},
|
||||
"node_modules/undici": {
|
||||
"version": "5.27.2",
|
||||
"resolved": "https://registry.npmjs.org/undici/-/undici-5.27.2.tgz",
|
||||
"integrity": "sha512-iS857PdOEy/y3wlM3yRp+6SNQQ6xU0mmZcwRSriqk+et/cwWAtwmIGf6WkoDN2EK/AMdCO/dfXzIwi+rFMrjjQ==",
|
||||
"dependencies": {
|
||||
"@fastify/busboy": "^2.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14.0"
|
||||
}
|
||||
},
|
||||
"node_modules/undici-types": {
|
||||
"version": "5.26.5",
|
||||
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz",
|
||||
"integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA=="
|
||||
},
|
||||
"node_modules/ws": {
|
||||
"version": "8.14.2",
|
||||
"resolved": "https://registry.npmjs.org/ws/-/ws-8.14.2.tgz",
|
||||
"integrity": "sha512-wEBG1ftX4jcglPxgFCMJmZ2PLtSbJ2Peg6TmpJFTbe9GZYOQCDPdMYu/Tm0/bGZkw8paZnJY45J4K2PZrLYq8g==",
|
||||
"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
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
5
example_bot/package.json
Executable file
5
example_bot/package.json
Executable file
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"dependencies": {
|
||||
"discord.js": "^14.14.1"
|
||||
}
|
||||
}
|
||||
82
example_bot/updateCommands.js
Executable file
82
example_bot/updateCommands.js
Executable file
@@ -0,0 +1,82 @@
|
||||
const { REST, Routes } = require('discord.js');
|
||||
const { clientId, token } = require('./config.json');
|
||||
const fs = require('node:fs');
|
||||
const path = require('node:path');
|
||||
|
||||
const generateCommandFile = (command) => {
|
||||
return `const { SlashCommandBuilder } = require('discord.js');
|
||||
|
||||
module.exports = {
|
||||
data: new SlashCommandBuilder()
|
||||
.setName('${command.name}')
|
||||
.setDescription('${command.description}'),
|
||||
async execute(interaction) {
|
||||
await interaction.reply('${command.response}');
|
||||
},
|
||||
};
|
||||
`;
|
||||
};
|
||||
|
||||
|
||||
|
||||
const updateCommands = () => {
|
||||
const commands = [];
|
||||
const foldersPath = path.join(__dirname, 'commands');
|
||||
const utilityFolderPath = path.join(foldersPath, 'utility');
|
||||
|
||||
// Delete all files from ./commands/utility/ before creating new ones
|
||||
fs.readdirSync(utilityFolderPath).forEach((file) => {
|
||||
const filePath = path.join(utilityFolderPath, file);
|
||||
fs.unlinkSync(filePath);
|
||||
console.log(`Deleted ${file}`);
|
||||
});
|
||||
|
||||
|
||||
// CREAYE ALL THE COMMAND FILES HERE (OVERWRITE THEM IF THEY ALREADY EXSIST)
|
||||
const { commands: jsonCommands } = require('./config.json');
|
||||
for (const command of jsonCommands) {
|
||||
const commandFileName = `${command.name}.js`;
|
||||
const commandFilePath = path.join(foldersPath, `utility/${commandFileName}`);
|
||||
|
||||
if (!fs.existsSync(commandFilePath)) {
|
||||
// If the command file doesn't exist, create it
|
||||
fs.writeFileSync(commandFilePath, generateCommandFile(command));
|
||||
console.log(`Created ${commandFileName}`);
|
||||
}
|
||||
}
|
||||
|
||||
for (const folder of fs.readdirSync(foldersPath)) {
|
||||
const commandsPath = path.join(foldersPath, folder);
|
||||
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);
|
||||
if ('data' in command && 'execute' in command) {
|
||||
commands.push(command.data.toJSON());
|
||||
} else {
|
||||
console.log(`[WARNING] The command at ${filePath} is missing a required "data" or "execute" property.`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const rest = new REST().setToken(token);
|
||||
|
||||
(async () => {
|
||||
try {
|
||||
console.log(`⚙️ Started refreshing ${commands.length} application (/) commands.`);
|
||||
|
||||
const data = await rest.put(
|
||||
Routes.applicationCommands(clientId),
|
||||
{ body: commands },
|
||||
);
|
||||
|
||||
console.log(`✅ Successfully reloaded ${data.length} application (/) commands.`);
|
||||
} catch (error) {
|
||||
console.error(`❌ ${error}`);
|
||||
}
|
||||
})();
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
updateCommands
|
||||
}
|
||||
13
hash.js
Executable file
13
hash.js
Executable file
@@ -0,0 +1,13 @@
|
||||
const bcrypt = require('bcrypt');
|
||||
|
||||
// Password to be hashed
|
||||
const passwordToHash = 'password_to_hash';
|
||||
|
||||
// Hashing the password with bcrypt
|
||||
bcrypt.hash(passwordToHash, 10, (err, hash) => {
|
||||
if (err) {
|
||||
console.error('Error hashing password:', err);
|
||||
} else {
|
||||
console.log('Hashed password:', hash);
|
||||
}
|
||||
});
|
||||
22
httpdocs/dashboard.html
Executable file
22
httpdocs/dashboard.html
Executable file
@@ -0,0 +1,22 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Dashboard</title>
|
||||
<link rel="stylesheet" href="/public.css">
|
||||
<link rel="stylesheet" href="/dashboard.css">
|
||||
<script src="https://cdn.jsdelivr.net/npm/sweetalert2@10"></script>
|
||||
<script src="bots.js" defer></script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="main">
|
||||
<div id="container">
|
||||
<h1>Choose the bot you want to edit</h1>
|
||||
<div id="grid" class="bot-list">
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
24
httpdocs/login.html
Executable file
24
httpdocs/login.html
Executable file
@@ -0,0 +1,24 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<link rel="stylesheet" href="/login.css">
|
||||
<link rel="stylesheet" href="/public.css">
|
||||
<title>Login</title>
|
||||
</head>
|
||||
<body>
|
||||
<div class="login-container">
|
||||
<h2>Login to DiscordBotBuilder</h2>
|
||||
<form action="/" method="POST">
|
||||
<label for="username">Username:</label>
|
||||
<input type="text" id="username" name="username" required>
|
||||
|
||||
<label for="password">Password:</label>
|
||||
<input type="password" id="password" name="password" required>
|
||||
|
||||
<button type="submit">Login</button>
|
||||
</form>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
26
httpdocs/project.html
Executable file
26
httpdocs/project.html
Executable file
@@ -0,0 +1,26 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Project</title>
|
||||
<link rel="stylesheet" href="/public.css">
|
||||
<link rel="stylesheet" href="/project.css">
|
||||
<script src="https://cdn.jsdelivr.net/npm/sweetalert2@10"></script>
|
||||
<script src="/project.js" defer></script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="main">
|
||||
<div id="container" onload="loadData()">
|
||||
<h1 id="title"></h1>
|
||||
<button id="editProjectName" onclick="editProjectName()">Edit Name</button>
|
||||
<button id="exportProject" onclick="exportProject()">Export Project</button>
|
||||
<h2 id="description"></h2><br>
|
||||
<h3 id="section-title">Commands:</h3>
|
||||
<div id="grid" class="bot-list">
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
2089
package-lock.json
generated
Executable file
2089
package-lock.json
generated
Executable file
File diff suppressed because it is too large
Load Diff
23
package.json
Executable file
23
package.json
Executable file
@@ -0,0 +1,23 @@
|
||||
{
|
||||
"name": "crud-nodejs",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"main": "server.js",
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1",
|
||||
"start": "node server.js"
|
||||
},
|
||||
"author": "",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"archiver": "^6.0.1",
|
||||
"bcrypt": "^5.1.1",
|
||||
"body-parser": "^1.20.2",
|
||||
"express": "^4.18.2",
|
||||
"express-session": "^1.17.3",
|
||||
"fs-extra": "^11.2.0",
|
||||
"mysql": "^2.18.1",
|
||||
"mysql2": "^3.6.5",
|
||||
"nodemon": "^3.0.1"
|
||||
}
|
||||
}
|
||||
109
scripts/bots.js
Executable file
109
scripts/bots.js
Executable file
@@ -0,0 +1,109 @@
|
||||
function createNewBot() {
|
||||
Swal.fire({
|
||||
title: 'Create Bot',
|
||||
html:
|
||||
'<label for="name">Name</label>' +
|
||||
'<input id="name" class="swal2-input" placeholder="Project Name">' +
|
||||
'<label for="id">Bot ID</label>' +
|
||||
'<input id="id" class="swal2-input" placeholder="Bot ID">' +
|
||||
'<label for="token">Token</label>' +
|
||||
'<input id="token" class="swal2-input" placeholder="Bot Token">',
|
||||
focusConfirm: false,
|
||||
showCancelButton: true,
|
||||
cancelButtonText: 'Cancel',
|
||||
confirmButtonText: 'Create',
|
||||
preConfirm: () => {
|
||||
const name = Swal.getPopup().querySelector('#name').value;
|
||||
const token = Swal.getPopup().querySelector('#token').value;
|
||||
const clientID = Swal.getPopup().querySelector('#id').value;
|
||||
|
||||
// Check if both name and token are filled
|
||||
if (!name || !token || !clientID) {
|
||||
Swal.showValidationMessage('Please fill in both the Name and Token fields');
|
||||
return false; // Prevent closing the modal
|
||||
}
|
||||
|
||||
// Perform the POST request to /create-bot
|
||||
return fetch('/create-bot', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify({
|
||||
name: name,
|
||||
token: token,
|
||||
clientId: clientID,
|
||||
}),
|
||||
})
|
||||
.then(response => {
|
||||
if (!response.ok) {
|
||||
throw new Error('Network response was not ok');
|
||||
}
|
||||
return response.json();
|
||||
})
|
||||
.then(data => {
|
||||
console.log(data);
|
||||
Swal.fire('Bot Created!', 'Your bot has been successfully created.', 'success');
|
||||
refreshList();
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('There was a problem with the fetch operation:', error);
|
||||
Swal.fire('Error', 'There was an error creating the bot.', 'error');
|
||||
});
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
function refreshList() {
|
||||
let xhr = new XMLHttpRequest();
|
||||
xhr.open('GET', '/fetch-bots', true);
|
||||
xhr.send();
|
||||
|
||||
xhr.onload = function () {
|
||||
if (xhr.status == 200) {
|
||||
let jsonResponse = JSON.parse(xhr.responseText);
|
||||
|
||||
const gridContainer = document.getElementById("grid");
|
||||
gridContainer.innerHTML = '';
|
||||
|
||||
|
||||
const specialButton = document.createElement('div');
|
||||
specialButton.classList.add('grid-btn');
|
||||
specialButton.id = 'special-button';
|
||||
|
||||
const button = document.createElement('button');
|
||||
button.innerText = 'NEW BOT';
|
||||
button.id = 'add-bot-button';
|
||||
button.onclick = createNewBot;
|
||||
|
||||
specialButton.appendChild(button);
|
||||
gridContainer.appendChild(specialButton);
|
||||
|
||||
jsonResponse.forEach(bot => {
|
||||
const gridItem = document.createElement('div');
|
||||
gridItem.classList.add('grid-btn');
|
||||
|
||||
const button = document.createElement('button');
|
||||
button.innerText = bot.name;
|
||||
button.dataset.projectID=bot.id;
|
||||
button.addEventListener("click", (event)=>{
|
||||
window.location.href=`/projects/${event.target.dataset.projectID}/`
|
||||
});
|
||||
|
||||
|
||||
gridItem.appendChild(button);
|
||||
gridContainer.appendChild(gridItem);
|
||||
});
|
||||
|
||||
} else {
|
||||
console.error('Request failed. Status: ' + xhr.status);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
document.addEventListener('DOMContentLoaded', function () {
|
||||
refreshList();
|
||||
});
|
||||
266
scripts/project.js
Executable file
266
scripts/project.js
Executable file
@@ -0,0 +1,266 @@
|
||||
function getProjectId() {
|
||||
let currentPage = window.location.href;
|
||||
return parseInt(currentPage.split('/projects/')[1].split('/')[0]);
|
||||
}
|
||||
|
||||
function editProjectName(){
|
||||
Swal.fire({
|
||||
title: 'Enter Project Name',
|
||||
html:
|
||||
'<input id="projectName" class="swal2-input" placeholder="Project Name">',
|
||||
focusConfirm: false,
|
||||
preConfirm: () => {
|
||||
const name = Swal.getPopup().querySelector('#projectName').value;
|
||||
|
||||
// Check if both name and token are filled
|
||||
if (!name) {
|
||||
Swal.showValidationMessage('Please fill in all the fields');
|
||||
return false; // Prevent closing the modal
|
||||
}
|
||||
|
||||
// Perform the POST request to /create-bot
|
||||
return fetch('/rename-project', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify({
|
||||
name: name,
|
||||
id: getProjectId()
|
||||
}),
|
||||
})
|
||||
.then(response => {
|
||||
if (!response.ok) {
|
||||
throw new Error('Network response was not ok');
|
||||
}
|
||||
return response.json();
|
||||
})
|
||||
.then(data => {
|
||||
Swal.fire('Project Rename!', 'Your project has been successfully been renamed.', 'success').then(() => {
|
||||
window.location.reload();
|
||||
});
|
||||
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('There was a problem with the fetch operation:', error);
|
||||
Swal.fire('Error', 'There was an error creating the bot.', 'error');
|
||||
});
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
function exportProject() {
|
||||
Swal.fire({
|
||||
title: "Exporting...",
|
||||
text: "Your project export is in progress.",
|
||||
icon: "info",
|
||||
showConfirmButton: false,
|
||||
allowOutsideClick: false,
|
||||
allowEscapeKey: false
|
||||
});
|
||||
|
||||
fetch(`/export?id=${getProjectId()}`, { method: 'POST' })
|
||||
.then(response => {
|
||||
if (!response.ok) {
|
||||
throw new Error(`Request failed. Status: ${response.status}`);
|
||||
}
|
||||
return response.blob();
|
||||
})
|
||||
.then(blob => {
|
||||
// Create a link element
|
||||
const link = document.createElement('a');
|
||||
link.href = window.URL.createObjectURL(blob);
|
||||
|
||||
// Set the download attribute and trigger a click
|
||||
link.download = `bot_builds_${getProjectId()}.zip`;
|
||||
link.click();
|
||||
|
||||
// Clean up
|
||||
window.URL.revokeObjectURL(link.href);
|
||||
|
||||
Swal.close();
|
||||
|
||||
})
|
||||
.then(() => {
|
||||
Swal.fire({
|
||||
title: "Exported!",
|
||||
text: "Your project has been exported.",
|
||||
icon: "success"
|
||||
});
|
||||
loadData();
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('Error:', error);
|
||||
Swal.fire({
|
||||
title: "Export Failed",
|
||||
text: "There was an error exporting your project.",
|
||||
icon: "error"
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
function createNewCommand() {
|
||||
Swal.fire({
|
||||
title: 'Create Command',
|
||||
html:
|
||||
'<label for="name">Command Name</label>' +
|
||||
'<input id="name" class="swal2-input" placeholder="Command Name">' +
|
||||
'<label for="description">Description</label>' +
|
||||
'<input id="description" class="swal2-input" placeholder="Command Description">'+
|
||||
'<label for="response">Command Response</label>' +
|
||||
'<input id="response" class="swal2-input" placeholder="Command Response">',
|
||||
focusConfirm: false,
|
||||
showCancelButton: true,
|
||||
cancelButtonText: 'Cancel',
|
||||
confirmButtonText: 'Create',
|
||||
preConfirm: () => {
|
||||
const name = Swal.getPopup().querySelector('#name').value;
|
||||
const description = Swal.getPopup().querySelector('#description').value;
|
||||
const response = Swal.getPopup().querySelector('#response').value;
|
||||
|
||||
// Check if both name and token are filled
|
||||
if (!name || !description || !response) {
|
||||
Swal.showValidationMessage('Please fill in all the fields');
|
||||
return false; // Prevent closing the modal
|
||||
}
|
||||
|
||||
// Perform the POST request to /create-bot
|
||||
return fetch('/create-command', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify({
|
||||
name: name,
|
||||
description: description,
|
||||
response: response,
|
||||
projectId: getProjectId()
|
||||
}),
|
||||
})
|
||||
.then(response => {
|
||||
if (!response.ok) {
|
||||
throw new Error('Network response was not ok');
|
||||
}
|
||||
return response.json();
|
||||
})
|
||||
.then(data => {
|
||||
console.log(data);
|
||||
Swal.fire('Command Created!', 'Your command has been successfully created.', 'success');
|
||||
loadData();
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('There was a problem with the fetch operation:', error);
|
||||
Swal.fire('Error', 'There was an error creating the bot.', 'error');
|
||||
});
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
function deleteCommand (event) {
|
||||
const commandId=event.target.dataset.commandId;
|
||||
const projectId = getProjectId();
|
||||
|
||||
Swal.fire({
|
||||
title: "Are you sure you want to delete this command?",
|
||||
text: "You won't be able to revert this!",
|
||||
icon: "warning",
|
||||
showCancelButton: true,
|
||||
confirmButtonColor: "#3085d6",
|
||||
cancelButtonColor: "#d33",
|
||||
confirmButtonText: "Yes, delete it!"
|
||||
}).then((result) => {
|
||||
if (result.isConfirmed) {
|
||||
let xhr = new XMLHttpRequest();
|
||||
xhr.open("POST", `/delete-command?commandId=${commandId}&projectId=${projectId}`);
|
||||
xhr.send();
|
||||
xhr.onload = () => {
|
||||
if (xhr.status == 200){
|
||||
Swal.fire({
|
||||
title: "Deleted!",
|
||||
text: "Your command has been deleted.",
|
||||
icon: "success"
|
||||
})
|
||||
loadData();
|
||||
} else {
|
||||
console.error('Request failed. Status: ' + xhr.status);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
function loadData() {
|
||||
let projectId = getProjectId()
|
||||
|
||||
let xhr = new XMLHttpRequest();
|
||||
xhr.open('GET', `/fetch-project-data?id=${projectId}`, true);
|
||||
xhr.send();
|
||||
xhr.onload = () => {
|
||||
if (xhr.status == 200){
|
||||
|
||||
let jsonResponse = JSON.parse(xhr.responseText);
|
||||
if (jsonResponse != {}){
|
||||
document.querySelector("#title").innerHTML = jsonResponse.projectName.toUpperCase();
|
||||
document.querySelector("#description").innerHTML = "Project Id: "+jsonResponse.projectId;
|
||||
}
|
||||
} else {
|
||||
console.error('Request failed. Status: ' + xhr.status);
|
||||
}
|
||||
}
|
||||
|
||||
let xhr2 = new XMLHttpRequest();
|
||||
xhr2.open('GET', `/fetch-commands?id=${projectId}`, true);
|
||||
xhr2.send();
|
||||
|
||||
xhr2.onload = function () {
|
||||
if (xhr2.status == 200) {
|
||||
let jsonResponse = JSON.parse(xhr2.responseText);
|
||||
console.log(jsonResponse)
|
||||
|
||||
const gridContainer = document.getElementById("grid");
|
||||
gridContainer.innerHTML = '';
|
||||
|
||||
|
||||
const specialButton = document.createElement('div');
|
||||
specialButton.classList.add('grid-btn');
|
||||
specialButton.id = 'special-button';
|
||||
|
||||
const button = document.createElement('button');
|
||||
button.innerText = 'NEW COMMAND';
|
||||
button.id = 'add-command-button';
|
||||
button.onclick = createNewCommand;
|
||||
|
||||
specialButton.appendChild(button);
|
||||
gridContainer.appendChild(specialButton);
|
||||
|
||||
jsonResponse.forEach(command => {
|
||||
const gridItem = document.createElement('div');
|
||||
gridItem.classList.add('grid-btn');
|
||||
|
||||
const button = document.createElement('button');
|
||||
button.innerHTML = "<strong class='command-bold'>"+command.name+"</strong><br>"+command.description;
|
||||
button.dataset.commandId=command.id;
|
||||
button.dataset.commandResponse=command.response;
|
||||
button.addEventListener("click", (event)=>{
|
||||
deleteCommand(event);
|
||||
});
|
||||
|
||||
|
||||
gridItem.appendChild(button);
|
||||
gridContainer.appendChild(gridItem);
|
||||
});
|
||||
|
||||
} else {
|
||||
console.error('Request failed. Status: ' + xhr2.status);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
|
||||
document.addEventListener('DOMContentLoaded', function () {
|
||||
loadData();
|
||||
});
|
||||
390
server.js
Executable file
390
server.js
Executable file
@@ -0,0 +1,390 @@
|
||||
/*
|
||||
Importing all the required packages
|
||||
*/
|
||||
const express = require('express');
|
||||
const session = require('express-session');
|
||||
const bodyParser = require('body-parser');
|
||||
const mysql = require('mysql');
|
||||
const bcrypt = require('bcrypt');
|
||||
const fs = require('fs-extra');
|
||||
const path = require('path');
|
||||
const archiver = require('archiver');
|
||||
|
||||
|
||||
/*
|
||||
Creating some handy constants
|
||||
*/
|
||||
const documentRoot = `${__dirname}/httpdocs`
|
||||
const webserverPort = 3000
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Creates a MySQL connection.
|
||||
* @returns {Object} MySQL connection object
|
||||
*/
|
||||
const createConnection = () => {
|
||||
return mysql.createConnection({
|
||||
host: "localhost",
|
||||
user: "dcBB",
|
||||
password: "DiscordBotBuilder",
|
||||
database: "PS_DISCORD_BOT_BUILDER",
|
||||
connectTimeout: 20000,
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Setting up the express webserver
|
||||
*
|
||||
*/
|
||||
const app = express()
|
||||
|
||||
app.use(express.static("styles"))
|
||||
app.use(express.static("scripts"))
|
||||
|
||||
app.use(session({secret: 'secret',resave: true,saveUninitialized: true}));
|
||||
|
||||
app.use( bodyParser.json() );
|
||||
app.use(express.json());
|
||||
|
||||
app.use(bodyParser.urlencoded({extended: true}));
|
||||
app.use(express.urlencoded({extended: true}));
|
||||
|
||||
|
||||
|
||||
/*
|
||||
Setting up the login system
|
||||
*/
|
||||
const requireLogin = (req, res, next) => {
|
||||
if (!req.session.userId) {
|
||||
res.redirect('/');
|
||||
} else {
|
||||
next();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
Setting up all the website pages
|
||||
*/
|
||||
app.get("/", (req, res) => {
|
||||
res.sendFile(`${documentRoot}/login.html`);
|
||||
})
|
||||
|
||||
|
||||
app.get("/dashboard",requireLogin, (req, res) => {
|
||||
res.sendFile(`${documentRoot}/dashboard.html`);
|
||||
});
|
||||
|
||||
app.get("/projects/:projectId/", requireLogin, (req, res)=>{
|
||||
const con = createConnection();
|
||||
|
||||
const sql = "SELECT MAX(project_id) as maxProjectID FROM Projects";
|
||||
con.query(sql, (err, results) => {
|
||||
if (err) throw err;
|
||||
con.end();
|
||||
const maxProjectID = results[0].maxProjectID;
|
||||
|
||||
if (parseInt(maxProjectID) < parseInt(req.params.projectId)) return res.redirect("/dashboard");
|
||||
else {
|
||||
res.sendFile(`${documentRoot}/project.html`);
|
||||
}
|
||||
});
|
||||
})
|
||||
|
||||
|
||||
/*
|
||||
Setting up all the website posting pages.
|
||||
*/
|
||||
|
||||
app.post("/", (req, res) => {
|
||||
/**
|
||||
* Login Validation
|
||||
*/
|
||||
const { username, password } = req.body;
|
||||
|
||||
const con = createConnection();
|
||||
|
||||
const sql = "SELECT * FROM Users WHERE username = ?";
|
||||
con.query(sql, [username], (err, results) => {
|
||||
if (err) {
|
||||
console.error('Error executing login query:', err);
|
||||
res.status(500).send('Internal Server Error');
|
||||
return;
|
||||
}
|
||||
con.end();
|
||||
|
||||
if (results.length > 0) {
|
||||
bcrypt.compare(password, results[0].password, (bcryptErr, isMatch) => {
|
||||
if (bcryptErr) {
|
||||
console.error('Error comparing passwords:', bcryptErr);
|
||||
res.status(500).send('Internal Server Error');
|
||||
return;
|
||||
}
|
||||
if (isMatch) {
|
||||
req.session.userId = results[0].user_id;
|
||||
res.redirect('/dashboard');
|
||||
} else {
|
||||
res.send('Invalid username or password');
|
||||
}
|
||||
});
|
||||
} else {
|
||||
res.send('Invalid username or password');
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
/*
|
||||
Commands Grid
|
||||
*/
|
||||
app.get("/fetch-commands", requireLogin, (req, res)=> {
|
||||
const projectId = req.query.id;
|
||||
const userId = req.session.userId;
|
||||
|
||||
const con = createConnection();
|
||||
|
||||
const ownerCheck = "SELECT project_id FROM Projects WHERE project_id=? AND project_owner=?"
|
||||
con.query(ownerCheck, [projectId, userId], (err, results)=>{
|
||||
if (err) throw err;
|
||||
if (results.length != 1)return res.json({});
|
||||
|
||||
|
||||
|
||||
const sql = "SELECT command_id, command_name, command_description, command_response FROM Commands WHERE project_id = ?";
|
||||
con.query(sql, [projectId], (err, results) => {
|
||||
if (err) throw err;
|
||||
con.end();
|
||||
let result = [];
|
||||
|
||||
for (let i = 0; i < results.length; i++){
|
||||
result.push({"name": results[i]["command_name"], "description": results[i]["command_description"], "id": results[i]["command_id"], "response": results[i]["command_response"]});
|
||||
}
|
||||
|
||||
res.json(result);
|
||||
});
|
||||
|
||||
})
|
||||
|
||||
|
||||
});
|
||||
|
||||
app.get("/fetch-project-data", requireLogin, (req, res)=>{
|
||||
const projectId = req.query.id;
|
||||
const userId = req.session.userId;
|
||||
|
||||
let response = {};
|
||||
|
||||
const con = createConnection();
|
||||
|
||||
const sql = "SELECT * FROM Projects WHERE project_id=? AND project_owner=?";
|
||||
con.query(sql, [projectId, userId], (err, results)=>{
|
||||
if (err) throw err;
|
||||
if (results.length != 1) return res.json(response);
|
||||
con.end();
|
||||
|
||||
response["projectName"] = results[0]["project_name"];
|
||||
response["projectId"] = projectId;
|
||||
|
||||
res.json(response)
|
||||
})
|
||||
});
|
||||
|
||||
app.post("/delete-command", requireLogin, (req, res)=> {
|
||||
const projectId = req.query.projectId;
|
||||
const commandId = req.query.commandId;
|
||||
const userId = req.session.userId;
|
||||
|
||||
const con = createConnection();
|
||||
|
||||
const ownerCheck = "SELECT project_id FROM Projects WHERE project_id=? AND project_owner=?"
|
||||
con.query(ownerCheck, [projectId, userId], (err, results)=>{
|
||||
if (err) throw err;
|
||||
if (results.length != 1)return res.json({});
|
||||
|
||||
const sql = "DELETE FROM Commands WHERE command_id=?";
|
||||
con.query(sql, [commandId], (err, results)=>{
|
||||
if (err) throw err;
|
||||
con.end();
|
||||
|
||||
res.status(200).send("true");
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
})
|
||||
|
||||
app.post("/create-command", requireLogin, (req, res)=> {
|
||||
let name = req.body.name;
|
||||
let description = req.body.description;
|
||||
let response = req.body.response;
|
||||
|
||||
name = name.replace(" ", "-");
|
||||
|
||||
let projectId = req.body.projectId;
|
||||
let owner = req.session.userId;
|
||||
|
||||
const con = createConnection();
|
||||
|
||||
const ownerCheck = "SELECT project_id FROM Projects WHERE project_id=? AND project_owner=?"
|
||||
con.query(ownerCheck, [projectId, owner], (err, results)=>{
|
||||
if (err) throw err;
|
||||
if (results.length != 1)return;
|
||||
|
||||
const sql = "INSERT INTO Commands (project_id, command_name, command_description, command_response) VALUES (?,?,?,?)";
|
||||
con.query(sql, [projectId, name, description, response], (err, results)=>{
|
||||
if (err) throw err;
|
||||
con.end();
|
||||
res.status(200).send("true");
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
Projects Grid
|
||||
*/
|
||||
app.get("/fetch-bots", requireLogin, (req, res)=> {
|
||||
const sql = "SELECT project_name, project_id FROM Projects WHERE project_owner = ?";
|
||||
|
||||
const con = createConnection();
|
||||
|
||||
con.query(sql, [req.session.userId], (err, results) => {
|
||||
if (err) throw err;
|
||||
con.end();
|
||||
|
||||
let result = [];
|
||||
|
||||
for (let i = 0; i < results.length; i++){
|
||||
result.push({"name": results[i]["project_name"], "id": results[i]["project_id"]});
|
||||
}
|
||||
|
||||
res.json(result);
|
||||
});
|
||||
});
|
||||
|
||||
app.post("/create-bot", requireLogin, (req, res)=> {
|
||||
let name = req.body.name;
|
||||
let token = req.body.token;
|
||||
let clientId = req.body.clientId;
|
||||
let owner = req.session.userId;
|
||||
|
||||
if (name.length > 20)return;
|
||||
|
||||
let bot = {"name": name}
|
||||
|
||||
const con = createConnection();
|
||||
|
||||
var sql = "INSERT INTO Projects (project_name, project_owner, bot_token, bot_id) VALUES (?, ?, ?, ?)";
|
||||
con.query(sql, [name, owner, token, clientId], function (err, result) {
|
||||
if (err) throw err;
|
||||
con.end();
|
||||
});
|
||||
|
||||
res.send('true');
|
||||
})
|
||||
|
||||
app.post("/rename-project", requireLogin, (req,res)=>{
|
||||
let name = req.body.name;
|
||||
let projectId = req.body.id;
|
||||
let userId = req.session.userId;
|
||||
|
||||
const con = createConnection();
|
||||
|
||||
const ownerCheck = "SELECT project_id FROM Projects WHERE project_id=? AND project_owner=?"
|
||||
con.query(ownerCheck, [projectId, userId], (err, results)=>{
|
||||
if (err) throw err;
|
||||
if (results.length != 1)return;
|
||||
|
||||
const sql = "UPDATE Projects SET project_name=? WHERE project_id=?";
|
||||
con.query(sql, [name, projectId], (err, results)=>{
|
||||
if (err) throw err;
|
||||
con.end();
|
||||
res.status(200).send("true");
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
app.post("/export", requireLogin, (req, res) => {
|
||||
const projectId = req.query.id;
|
||||
const userId = req.session.userId;
|
||||
|
||||
const con = createConnection();
|
||||
|
||||
const ownerCheck = "SELECT * FROM Projects WHERE project_id=? AND project_owner=?";
|
||||
con.query(ownerCheck, [projectId, userId], (err, results) => {
|
||||
if (err) throw err;
|
||||
if (results.length !== 1) return res.json({});
|
||||
|
||||
const data = results[0];
|
||||
const botToken = data.bot_token;
|
||||
const clientId = data.bot_id;
|
||||
|
||||
con.query("SELECT command_id, command_name, command_description, command_response FROM Commands WHERE project_id = ?", [projectId], (err, result) => {
|
||||
if (err) throw err;
|
||||
con.end();
|
||||
|
||||
const commands = result.map(command => {
|
||||
return {
|
||||
name: command.command_name,
|
||||
description: command.command_description,
|
||||
response: command.command_response
|
||||
};
|
||||
});
|
||||
|
||||
const jsonContent = {
|
||||
token: botToken,
|
||||
clientId: clientId,
|
||||
commands: commands
|
||||
};
|
||||
|
||||
const botBuildsPath = `./bot_builds/${projectId}`;
|
||||
|
||||
// Create the directory if it doesn't exist
|
||||
fs.ensureDirSync(botBuildsPath);
|
||||
|
||||
// Copy everything from "./example_bot" to "./botBuilds/{id}/"
|
||||
const exampleBotPath = "./example_bot";
|
||||
fs.copySync(exampleBotPath, botBuildsPath);
|
||||
|
||||
// Write JSON to a file in the new directory
|
||||
const configFile = path.join(botBuildsPath, "config.json");
|
||||
fs.writeFileSync(configFile, JSON.stringify(jsonContent, null, 2));
|
||||
|
||||
// Create a zip file
|
||||
const outputZipPath = path.join(__dirname, `./bot_builds/${projectId}.zip`);
|
||||
const outputZipStream = fs.createWriteStream(outputZipPath);
|
||||
const archive = archiver('zip', {
|
||||
zlib: { level: 9 }
|
||||
});
|
||||
|
||||
outputZipStream.on('close', () => {
|
||||
res.download(outputZipPath, (err) => {
|
||||
if (err) throw err;
|
||||
fs.removeSync(outputZipPath);
|
||||
fs.removeSync(botBuildsPath);
|
||||
});
|
||||
});
|
||||
|
||||
archive.on('error', (err) => {
|
||||
throw err;
|
||||
});
|
||||
|
||||
archive.pipe(outputZipStream);
|
||||
archive.directory(botBuildsPath, false);
|
||||
archive.finalize();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
/*
|
||||
Starting up the server.
|
||||
*/
|
||||
app.listen(webserverPort, () => {
|
||||
console.log(`Bot Builder Online at http://localhost:${webserverPort}/`)
|
||||
})
|
||||
2
startServer.sh
Executable file
2
startServer.sh
Executable file
@@ -0,0 +1,2 @@
|
||||
#!/bin/bash
|
||||
node server.js
|
||||
57
styles/dashboard.css
Executable file
57
styles/dashboard.css
Executable file
@@ -0,0 +1,57 @@
|
||||
:root {
|
||||
--mainMargin: 30px;
|
||||
}
|
||||
|
||||
#main {
|
||||
margin: var(--mainMargin);
|
||||
width: calc(100% - var(--mainMargin)*2);
|
||||
height: calc(100vh - var(--mainMargin)*2);
|
||||
|
||||
}
|
||||
|
||||
#container {
|
||||
background: var(--dark-gray);
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
overflow: visible !important;
|
||||
border-radius: 40px;
|
||||
|
||||
-webkit-box-shadow: 0px 0px 10px 10px var(--dark-steel);
|
||||
-moz-box-shadow: 0px 0px 10px 10px var(--dark-steel);
|
||||
box-shadow: 0px 0px 10px 10px var(--dark-steel);
|
||||
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
align-items: center;
|
||||
flex-direction: column;
|
||||
gap: 20px;
|
||||
}
|
||||
|
||||
#grid {
|
||||
width: 90%;
|
||||
height: 90%;
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
gap:5%;
|
||||
flex-wrap: wrap;
|
||||
|
||||
}
|
||||
|
||||
#grid > * {
|
||||
border-radius: 15px;
|
||||
background-color: var(--light-gray);
|
||||
width: 200px;
|
||||
height: 200px;
|
||||
}
|
||||
#special-button {
|
||||
background-color: green;
|
||||
}
|
||||
|
||||
.grid-btn > button {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: none;
|
||||
border:none;
|
||||
cursor:pointer;
|
||||
}
|
||||
52
styles/login.css
Executable file
52
styles/login.css
Executable file
@@ -0,0 +1,52 @@
|
||||
body {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 100vh;
|
||||
background: var(--discord-blue);
|
||||
}
|
||||
|
||||
.login-container {
|
||||
background-color: var(--dark-gray);
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 0 10px rgba(0, 0, 0, 0.2);
|
||||
padding: 30px;
|
||||
text-align: center;
|
||||
color: var(--light-gray);
|
||||
width: 300px;
|
||||
}
|
||||
|
||||
h2 {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
form {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
label {
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
input {
|
||||
padding: 10px;
|
||||
margin-bottom: 16px;
|
||||
border: 1px solid var(--discord-blue);
|
||||
border-radius: 4px;
|
||||
background-color: var(--dark-steel);
|
||||
color: white;
|
||||
}
|
||||
|
||||
button {
|
||||
padding: 12px;
|
||||
background-color: var(--discord-blue);
|
||||
color: white;
|
||||
border: none;
|
||||
border-radius: 4px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
button:hover {
|
||||
background-color: var(--medium-gray);
|
||||
}
|
||||
66
styles/project.css
Executable file
66
styles/project.css
Executable file
@@ -0,0 +1,66 @@
|
||||
:root {
|
||||
--mainMargin: 30px;
|
||||
}
|
||||
|
||||
#main {
|
||||
margin: var(--mainMargin);
|
||||
width: calc(100% - var(--mainMargin)*2);
|
||||
height: calc(100vh - var(--mainMargin)*2);
|
||||
|
||||
}
|
||||
|
||||
#container {
|
||||
background: var(--dark-gray);
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
overflow: visible !important;
|
||||
border-radius: 40px;
|
||||
|
||||
-webkit-box-shadow: 0px 0px 10px 10px var(--dark-steel);
|
||||
-moz-box-shadow: 0px 0px 10px 10px var(--dark-steel);
|
||||
box-shadow: 0px 0px 10px 10px var(--dark-steel);
|
||||
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
align-items: center;
|
||||
flex-direction: column;
|
||||
gap: 20px;
|
||||
}
|
||||
|
||||
#grid {
|
||||
width: 90%;
|
||||
height: 90%;
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
gap:5%;
|
||||
flex-wrap: wrap;
|
||||
|
||||
}
|
||||
|
||||
#grid > * {
|
||||
border-radius: 15px;
|
||||
background-color: var(--light-gray);
|
||||
width: 200px;
|
||||
height: 200px;
|
||||
}
|
||||
#special-button {
|
||||
background-color: green;
|
||||
}
|
||||
|
||||
.grid-btn > button {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: none;
|
||||
border:none;
|
||||
cursor:pointer;
|
||||
}
|
||||
|
||||
.command-bold {
|
||||
font-size: large;
|
||||
}
|
||||
|
||||
#editProjectName,
|
||||
#exportProject {
|
||||
color: black !important;
|
||||
}
|
||||
30
styles/public.css
Executable file
30
styles/public.css
Executable file
@@ -0,0 +1,30 @@
|
||||
:root {
|
||||
--discord-blue: #7289da;
|
||||
--dark-gray: #424549;
|
||||
--medium-gray: #36393e;
|
||||
--light-gray: #282b30;
|
||||
--dark-steel: #1e2124;
|
||||
}
|
||||
|
||||
* {
|
||||
margin:0;
|
||||
padding:0;
|
||||
color: white;
|
||||
}
|
||||
|
||||
body {
|
||||
height: 100vh !important;
|
||||
background: var(--discord-blue);
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
#main {
|
||||
height: 100%;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.swal2-input {
|
||||
color: black !important;
|
||||
}
|
||||
Reference in New Issue
Block a user