Initial Commit

This commit is contained in:
Skylar Grant 2023-12-30 10:43:20 -05:00
parent d3c8e99a43
commit 4390bc5c64
12 changed files with 328 additions and 0 deletions

8
Dockerfile Normal file
View File

@ -0,0 +1,8 @@
FROM node:18
RUN mkdir -p /usr/src/app
WORKDIR /usr/src/app
COPY package.json ./
RUN npm install
COPY . .
CMD ["/bin/sh", "-c", "node main.js 2> /logs/$(date +%Y-%m-%d_%H-%M-%S)-error.txt 1> /logs/$(date +%Y-%m-%d_%H-%M-%S)-status.txt"]

4
data/config.json Normal file
View File

@ -0,0 +1,4 @@
{
"guildId": "",
"validCommands": []
}

22
data/strings.json Normal file
View File

@ -0,0 +1,22 @@
{
"help": {
"info": "",
"setup": "",
"permissions": ""
},
"embeds": {
"footer": "Have a great day!",
"color": "5555FF"
},
"emoji": {
"next": "⏭️",
"previous": "⏮️",
"confirm": "☑️",
"cancel": "❌",
"water": "💧",
"fruit": "🍎",
"status": "📟"
},
"roleIds": {
}
}

55
main.js Normal file
View File

@ -0,0 +1,55 @@
// dotenv for handling environment variables
const dotenv = require('dotenv');
dotenv.config();
const token = process.env.TOKEN;
const heartbeatUrl = process.env.HEARTBEAT_URL;
const sendHeartbeat = typeof heartbeatUrl === 'string';
// Discord.JS
const { Client, GatewayIntentBits } = require('discord.js');
const client = new Client({
intents: [
GatewayIntentBits.Guilds
]
});
// Various imports
const fn = require('./modules/functions.js');
const strings = require('./data/strings.json');
const isDev = process.env.DEBUG;
const statusChannelId = process.env.STATUSCHANNELID;
client.once('ready', () => {
// Build a collection of slash commands for the bot to use
fn.collectionBuilders.slashCommands(client);
console.log('Ready!');
client.channels.fetch(statusChannelId).then(channel => {
channel.send(`${new Date().toISOString()} -- Ready`);
}).catch(err => {
console.error("Error sending status message: " + err);
});
// Heartbeat Timer
if (sendHeartbeat) {
setInterval(() => {
fn.sendHeartbeat(heartbeatUrl);
}, 30000);
if (isDev) console.log("Heartbeat interval set.");
}
});
// slash-commands
client.on('interactionCreate', async interaction => {
if (interaction.isCommand()) {
const { commandName } = interaction;
if (client.slashCommands.has(commandName)) {
client.slashCommands.get(commandName).execute(interaction);
} else {
interaction.reply('Sorry, I don\'t have access to that command.').catch(err => console.error(err));
console.error('Slash command attempted to run but not found: /' + commandName);
}
}
});
client.login(token);

8
modules/_cleanInput.js Normal file
View File

@ -0,0 +1,8 @@
const path = './modules/input.txt';
const fs = require('fs');
const replaceAll = require('string.prototype.replaceall');
const string = fs.readFileSync(path).toString();
console.log(JSON.stringify(string));
let newString = replaceAll(string, '\r\n', '\\n');
fs.writeFileSync(path, newString);
return "Done";

View File

@ -0,0 +1,39 @@
// dotenv for handling environment variables
const dotenv = require('dotenv');
dotenv.config();
const { REST } = require('@discordjs/rest');
const { Routes } = require('discord-api-types/v9');
const clientId = process.env.BOTID;
const token = process.env.TOKEN;
const fs = require('fs');
const commands = [];
const commandFiles = fs.readdirSync('./slash-commands').filter(file => file.endsWith('.js'));
for (const file of commandFiles) {
const command = require(`../slash-commands/${file}`);
if (command.data != undefined) {
commands.push(command.data.toJSON());
}
}
// console.log(commands);
const rest = new REST({ version: '9' }).setToken(token);
(async () => {
try {
console.log('Started refreshing application (/) commands.');
await rest.put(
Routes.applicationCommands(clientId),
{ body: commands },
);
console.log('Successfully reloaded application (/) commands.');
process.exit();
} catch (error) {
console.error(error);
}
})();

View File

@ -0,0 +1,39 @@
// dotenv for handling environment variables
const dotenv = require('dotenv');
dotenv.config();
const { REST, Routes } = require('discord.js');
const { guildId } = require('../data/config.json');
const clientId = process.env.clientId;
const token = process.env.TOKEN;
const fs = require('fs');
const commands = [];
const commandFiles = fs.readdirSync('../slash-commands').filter(file => file.endsWith('.js'));
for (const file of commandFiles) {
const command = require(`../slash-commands/${file}`);
if (command.data != undefined) {
commands.push(command.data.toJSON());
}
}
console.log(commands);
const rest = new REST({ version: '10' }).setToken(token);
(async () => {
try {
console.log('Started refreshing application (/) commands.');
await rest.put(
Routes.applicationGuildCommands(clientId, guildId),
{ body: commands },
);
console.log('Successfully reloaded application (/) commands.');
process.exit();
} catch (error) {
console.error(error);
}
})();

View File

@ -0,0 +1,27 @@
// dotenv for handling environment variables
const dotenv = require('dotenv');
dotenv.config();
const { REST } = require('@discordjs/rest');
const { Routes } = require('discord-api-types/v9');
const clientId = process.env.clientId;
const { guildId } = require('../data/config.json');
const token = process.env.TOKEN;
const rest = new REST({ version: '9' }).setToken(token);
(async () => {
try {
console.log('Started refreshing application (/) commands.');
await rest.put(
Routes.applicationGuildCommands(clientId, guildId),
{ body: '' },
);
console.log('Successfully reloaded application (/) commands.');
process.exit();
} catch (error) {
console.error(error);
}
})();

91
modules/functions.js Normal file
View File

@ -0,0 +1,91 @@
// dotenv for handling environment variables
const dotenv = require('dotenv');
dotenv.config();
const isDev = process.env.isDev;
// filesystem
const fs = require('fs');
const https = require('https');
// Discord.js
const Discord = require('discord.js');
const { EmbedBuilder, ActionRowBuilder, ButtonBuilder, ButtonStyle } = Discord;
// Various imports from other files
const config = require('../data/config.json');
const strings = require('../data/strings.json');
const slashCommandFiles = fs.readdirSync('./slash-commands/').filter(file => file.endsWith('.js'));
const functions = {
// Functions for managing and creating Collections
collectionBuilders: {
// Create the collection of slash commands
slashCommands(client) {
if (!client.slashCommands) client.slashCommands = new Discord.Collection();
client.slashCommands.clear();
for (const file of slashCommandFiles) {
const slashCommand = require(`../slash-commands/${file}`);
if (slashCommand.data != undefined) {
client.slashCommands.set(slashCommand.data.name, slashCommand);
}
}
if (isDev) console.log('Slash Commands Collection Built');
}
},
builders: {
embeds: {
helpEmbed(content, private) {
const embed = new EmbedBuilder()
.setColor(strings.embeds.color)
.setTitle('Grow A Tree Analyzer Help')
.setDescription(content)
.setFooter({ text: strings.embeds.footer });
const privateBool = private == 'true';
const messageContents = { embeds: [embed], ephemeral: privateBool };
return messageContents;
},
errorEmbed(content) {
const embed = new EmbedBuilder()
.setColor(0xFF0000)
.setTitle('Error!')
.setDescription(content)
.setFooter({ text: strings.embeds.footer });
const messageContents = { embeds: [embed], ephemeral: true };
return messageContents;
},
info(content) {
const embed = new EmbedBuilder()
.setColor(0x8888FF)
.setTitle('Information')
.setDescription(content)
.setFooter({ text: strings.embeds.footer });
const messageContents = { embeds: [embed], ephemeral: true };
return messageContents;
},
rules() {
const actionRow = functions.builders.actionRows.acceptRules();
const embed = new EmbedBuilder()
.setColor(strings.embeds.color)
.setTitle(strings.embeds.rulesTitle)
.setDescription(strings.embeds.rules)
.setFooter({ text: strings.embeds.rulesFooter });
return { embeds: [embed], components: [actionRow] };
}
}
},
async sendHeartbeat(url) {
if (isDev) console.log("Heartbeat Sent: " + url);
https.get(url, async (response) => {
let data = '';
response.on('data', (chunk) => data += chunk);
response.on('end', () => {
parsedData = JSON.parse(data);
if ( !(parsedData.ok) ) console.error("Heartbeat failed");
});
}).on("error", (error) => console.error(error));
}
};
module.exports = functions;

0
modules/input.txt Normal file
View File

24
package.json Normal file
View File

@ -0,0 +1,24 @@
{
"name": "nodgpt",
"version": "1.0.0",
"description": "NodBot's OpenAI features moved to a dedicated bot",
"main": "main.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"repository": {
"type": "git",
"url": "git+https://git.vfsh.dev/voidf1sh/nodgpt.git"
},
"author": "Skylar Grant",
"license": "MIT",
"bugs": {
"url": "https://git.vfsh.dev/voidf1sh/nodgpt/issues"
},
"homepage": "https://git.vfsh.dev/voidf1sh/nodgpt#readme",
"dependencies": {
"discord.js": "^14.9.0",
"dotenv": "^16.0.3",
"string.prototype.replaceall": "^1.0.7"
}
}

11
slash-commands/template Normal file
View File

@ -0,0 +1,11 @@
const { SlashCommandBuilder } = require('discord.js');
const fn = require('../modules/functions.js');
module.exports = {
data: new SlashCommandBuilder()
.setName('')
.setDescription(''),
async execute(interaction) {
await
},
};