made it download exe, and made that work (scuffed in GO)

This commit is contained in:
HerpieDerpie@example.com
2024-03-19 22:10:51 +01:00
parent 749a01b8e4
commit c9e10b85b8
11 changed files with 210 additions and 492 deletions

View File

@@ -1,5 +0,0 @@
How to run your new amazing discord bot.
First make sure you have node.js installed on your system, you can check with "node --version".
After that run the install.bat file. it will install the required packages, it wont take very long. When thats done, you can run the run.bat file, it should make your discord bot come online! If it does not, please check your token and your bot id in the config.json file

View File

@@ -1,55 +0,0 @@
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);

View File

@@ -1,2 +0,0 @@
@echo off
npm i discord.js

View File

@@ -1,269 +0,0 @@
{
"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
}
}
}
}
}

View File

@@ -1,5 +0,0 @@
{
"dependencies": {
"discord.js": "^14.14.1"
}
}

View File

@@ -1,2 +0,0 @@
@echo off
node bot.js

View File

@@ -1,82 +0,0 @@
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
}

View File

@@ -15,7 +15,7 @@
<h1 id="title"></h1>
<div id="projectButtons">
<button id="editProjectName" onclick="editProjectName()">Edit Name</button>
<button id="exportProject" onclick="exportProject()">Export Project</button>
<button id="exportProject" onclick="exportProject()">Export Project (Windows EXE)</button>
</div>
<h3 id="section-title">Commands:</h3>
<div id="grid" class="bot-list">

View File

@@ -67,33 +67,30 @@ function exportProject() {
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`;
// Adjusted for .exe download; consider adjusting the filename as needed
link.download = `discordBot_${getProjectId()}.exe`;
document.body.appendChild(link); // Append to body to ensure visibility in some browsers
link.click();
// Clean up
document.body.removeChild(link); // Clean up
window.URL.revokeObjectURL(link.href);
Swal.close();
})
.then(() => {
Swal.fire({
title: "Exported!",
text: "Your project has been exported.",
text: "Your project has been exported successfully.",
icon: "success"
});
loadData();
loadData(); // Reload or refresh data if necessary
})
.catch(error => {
console.error('Error:', error);
Swal.fire({
title: "Export Failed",
text: "There was an error exporting your project.",
text: "There was an error exporting your project. Please try again.",
icon: "error"
});
});

257
server.js
View File

@@ -9,6 +9,7 @@ const fs = require('fs-extra');
const path = require('path');
const archiver = require('archiver');
const mysql = require('mysql');
const { exec } = require('child_process');
const {db} = require("./config.json")
@@ -16,7 +17,7 @@ const {db} = require("./config.json")
Creating some handy constants
*/
const documentRoot = `${__dirname}/httpdocs`
const webserverPort = 3000
const webserverPort = 3002
@@ -311,82 +312,222 @@ app.post("/rename-project", requireLogin, (req,res)=>{
})
app.post("/export", requireLogin, (req, res) => {
app.post("/export", requireLogin, async (req, res) => {
console.log('Export request received.');
const projectId = req.query.id;
const userId = req.session.userId;
console.log(`Project ID: ${projectId}, User ID: ${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({});
con.query("SELECT * FROM Projects WHERE project_id=? AND project_owner=?", [projectId, userId], async (err, projectResults) => {
if (err) {
console.error('Error checking project owner:', err);
return res.status(500).send('Internal server error');
}
if (projectResults.length !== 1) {
return res.status(404).send('Project not found or user is not the owner.');
}
const data = results[0];
const data = projectResults[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();
con.query("SELECT command_id, command_name, command_description, command_response FROM Commands WHERE project_id = ?", [projectId], async (err, commands) => {
if (err) {
console.error('Error querying commands:', err);
return res.status(500).send('Internal server error');
}
try {
console.log("Started generating code");
await generateGoCode(projectId, botToken, commands);
const commands = result.map(command => {
return {
name: command.command_name,
description: command.command_description,
response: command.command_response
};
});
console.log("Started compiling");
await compileForWindows(projectId);
const jsonContent = {
token: botToken,
clientId: clientId,
commands: commands
};
// Assuming the compilation was successful, and .exe is ready.
const directoryPath = path.join('bot_builds', projectId.toString());
const exePath = path.join(directoryPath, 'discordBot.exe');
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);
console.log("Triggering download of the .exe file");
res.download(exePath, 'discordBot.exe', (err) => {
if (err) {
console.error(`Error sending file: ${err}`);
return res.status(500).send('Failed to download the file.');
} else {
console.log('Download initiated successfully.');
cleanUp(projectId);
}
});
});
archive.on('error', (err) => {
throw err;
});
archive.pipe(outputZipStream);
archive.directory(botBuildsPath, false);
archive.finalize();
} catch (error) {
console.error(error);
res.status(500).send('An error occurred during the export process.');
}
});
});
});
/*
Some functions for creating the bot
*/
function ensureDirectoryExists(directoryPath) {
return new Promise((resolve, reject) => {
console.log(`[ensureDirectoryExists] Ensuring directory exists: ${path.resolve(directoryPath)}`);
fs.mkdir(directoryPath, { recursive: true }, (err) => {
if (err) {
reject(`Error creating directory: ${err}`);
} else {
resolve();
}
});
});
}
function generateGoCode(projectId, botToken, commands) {
return new Promise((resolve, reject) => {
console.log(`[generateGoCode] Generating Go code for project ID: ${path.resolve(projectId)}`);
const directoryPath = path.join('bot_builds', projectId.toString());
const filePath = path.join(directoryPath, 'discordBot.go');
ensureDirectoryExists(directoryPath).then(() => {
let goCode = `
package main
import (
"fmt"
"github.com/bwmarrin/discordgo"
"os"
"os/signal"
"syscall"
)
var (
Token = "${botToken}"
)
func main() {
dg, err := discordgo.New("Bot " + Token)
if err != nil {
fmt.Println("error creating Discord session,", err)
return
}
dg.AddHandler(func(s *discordgo.Session, r *discordgo.Ready) {
fmt.Println("Bot is up and running")
})
dg.AddHandler(func(s *discordgo.Session, i *discordgo.InteractionCreate) {
if i.Type == discordgo.InteractionApplicationCommand {
handleCommandInteraction(s, i)
}
})
err = dg.Open()
if err != nil {
fmt.Println("error opening connection,", err)
return
}
defer dg.Close()
registerSlashCommands(dg)
fmt.Println("Bot is now running. Press CTRL+C to exit.")
sc := make(chan os.Signal, 1)
signal.Notify(sc, syscall.SIGINT, syscall.SIGTERM, os.Interrupt, os.Kill)
<-sc
}
func registerSlashCommands(s *discordgo.Session) {
${commands.map(command => `s.ApplicationCommandCreate(s.State.User.ID, "", &discordgo.ApplicationCommand{
Name: "${command.command_name}",
Description: "${command.command_description}",
Type: discordgo.ChatApplicationCommand,
})`).join('\n\t')}
}
func handleCommandInteraction(s *discordgo.Session, i *discordgo.InteractionCreate) {
${commands.map(command => `
if i.ApplicationCommandData().Name == "${command.command_name}" {
s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{
Type: discordgo.InteractionResponseChannelMessageWithSource,
Data: &discordgo.InteractionResponseData{
Content: "${command.command_response}",
},
})
}`).join('\n\t')}
}
`;
fs.writeFileSync(filePath, goCode);
console.log('Go source code generated.');
resolve();
}).catch(err => {
reject(err);
});
});
}
function compileForWindows(projectId) {
return new Promise((resolve, reject) => {
const directoryPath = path.resolve('bot_builds', projectId.toString());
const exePath = path.resolve(directoryPath, 'discordBot.exe');
console.log(`[compileForWindows] Directory path: ${directoryPath}`);
if (!fs.existsSync(directoryPath)) {
reject(`Directory ${directoryPath} does not exist`);
return;
}
const goModPath = path.resolve(directoryPath, 'go.mod');
if (!fs.existsSync(goModPath)) {
const cmdInit = `go mod init discordBot && go get github.com/bwmarrin/discordgo`;
console.log(`Running command: ${cmdInit} in directory: ${directoryPath}`);
exec(cmdInit, { cwd: directoryPath }, (error, stdout, stderr) => {
if (error) {
reject(`Error initializing Go module or getting discordgo package: ${error.message}`);
return;
}
compile();
});
} else {
compile();
}
function compile() {
const cmdCompile = `GOOS=windows GOARCH=amd64 go build -o "${exePath}"`;
console.log(`Running command: ${cmdCompile} in directory: ${directoryPath}`);
exec(cmdCompile, { cwd: directoryPath }, (error, stdout, stderr) => {
if (error) {
reject(`Compilation error: ${error.message}`);
return;
}
console.log('Compilation for Windows completed.');
resolve();
});
}
});
}
function cleanUp(projectId) {
return new Promise((resolve, reject) => {
const directoryPath = path.join('bot_builds', projectId.toString());
fs.rm(directoryPath, { recursive: true, force: true }, (err) => {
if (err) {
console.error(`Error removing directory: ${err}`);
reject(err);
} else {
console.log(`${directoryPath} was deleted recursively.`);
resolve();
}
});
});
}
/*
Starting up the server.
*/
app.listen(webserverPort, () => {
console.log(`Bot Builder Online at http://localhost:${webserverPort}/`)
console.log(`Bot Builder Online at http://localhost:${webserverPort}/`)
})