2024-04-02 04:02:22 +01:00
|
|
|
const fs = require('fs');
|
|
|
|
const sqlite3 = require('sqlite3').verbose();
|
|
|
|
const config = require("./config.js");
|
|
|
|
const packageInfo = require("./package.json");
|
|
|
|
const apiHelper = require("./helpers/api.js");
|
|
|
|
const { queryMulti } = require("./helpers/helper.js");
|
|
|
|
const { Client, GatewayIntentBits, Partials, Collection, ActivityType, Routes, REST, EmbedBuilder } = require('discord.js');
|
|
|
|
|
|
|
|
const clientOptions = {
|
|
|
|
intents: [GatewayIntentBits.Guilds, GatewayIntentBits.GuildMembers, GatewayIntentBits.GuildMessages, GatewayIntentBits.MessageContent, GatewayIntentBits.GuildPresences],
|
|
|
|
partials: [Partials.Channel]
|
|
|
|
};
|
|
|
|
|
|
|
|
const client = new Client(clientOptions);
|
|
|
|
let databaseConnection;
|
|
|
|
|
|
|
|
// Open SQLite Database
|
2024-04-08 12:09:36 +01:00
|
|
|
function connectToDatabase() {
|
|
|
|
console.log("Attempting to connect to database at:", config.sqlite.dbPath);
|
|
|
|
|
|
|
|
// Check if database file exists
|
|
|
|
if (!fs.existsSync(config.sqlite.dbPath)) {
|
|
|
|
console.log("Database file does not exist. Creating a new one...");
|
|
|
|
// Create empty file
|
|
|
|
fs.writeFileSync(config.sqlite.dbPath, '');
|
2024-04-02 04:02:22 +01:00
|
|
|
}
|
|
|
|
|
2024-04-08 12:09:36 +01:00
|
|
|
databaseConnection = new sqlite3.Database(config.sqlite.dbPath, sqlite3.OPEN_READWRITE, (err) => {
|
|
|
|
if (err) {
|
|
|
|
console.error("Error opening database:", err.message);
|
|
|
|
if (err.code === 'SQLITE_CANTOPEN') {
|
|
|
|
console.error("Failed to open database. Retrying in 2 seconds...");
|
|
|
|
setTimeout(connectToDatabase, 2000);
|
|
|
|
} else {
|
|
|
|
throw err;
|
|
|
|
}
|
2024-04-02 04:02:22 +01:00
|
|
|
} else {
|
2024-04-08 12:09:36 +01:00
|
|
|
console.log("Connected to the SQLite database.");
|
|
|
|
createTableIfNotExists();
|
2024-04-02 04:02:22 +01:00
|
|
|
}
|
|
|
|
});
|
2024-04-08 12:09:36 +01:00
|
|
|
|
|
|
|
databaseConnection.on('error', (err) => {
|
|
|
|
console.error('SQLite database error:', err);
|
|
|
|
// Handle specific error codes if needed
|
|
|
|
if (err.code === 'SQLITE_CANTOPEN') {
|
|
|
|
console.error("Failed to open database. Retrying...");
|
|
|
|
connectToDatabase();
|
2024-04-02 04:02:22 +01:00
|
|
|
} else {
|
2024-04-08 12:09:36 +01:00
|
|
|
throw err;
|
2024-04-02 04:02:22 +01:00
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2024-04-08 12:09:36 +01:00
|
|
|
function createTableIfNotExists() {
|
|
|
|
databaseConnection.run(`CREATE TABLE IF NOT EXISTS tableName (
|
|
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
|
|
column1 TEXT,
|
|
|
|
column2 TEXT
|
|
|
|
)`, [], function(err) {
|
|
|
|
if (err) {
|
|
|
|
console.error("Error creating table:", err.message);
|
|
|
|
} else {
|
|
|
|
console.log("Table created or already exists.");
|
|
|
|
require("./helpers/ready.js")(databaseConnection);
|
|
|
|
}
|
2024-04-02 04:02:22 +01:00
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2024-04-08 12:09:36 +01:00
|
|
|
connectToDatabase();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
client.once('ready', async () => {
|
|
|
|
console.log("Successfully logged in.");
|
2024-04-02 04:02:22 +01:00
|
|
|
client.user.setStatus("Online");
|
|
|
|
client.commands = new Collection();
|
2024-04-08 12:09:36 +01:00
|
|
|
await registerCommands();
|
2024-04-02 04:02:22 +01:00
|
|
|
updateActivity();
|
2024-04-08 12:09:36 +01:00
|
|
|
console.log(`Logged in as ${client.user.tag}`);
|
2024-04-02 04:02:22 +01:00
|
|
|
});
|
|
|
|
|
2024-04-08 12:09:36 +01:00
|
|
|
async function registerCommands() {
|
2024-04-02 04:02:22 +01:00
|
|
|
let commandData = [];
|
|
|
|
fs.readdirSync("./slash-commands").forEach(fileName => {
|
|
|
|
let commandModule = require("./slash-commands/" + fileName);
|
|
|
|
client.commands.set(commandModule.data.name, commandModule);
|
|
|
|
commandData.push(commandModule.data.toJSON());
|
|
|
|
});
|
|
|
|
require("./helpers/cron.js")(client);
|
|
|
|
require("./helpers/interaction.js")(client, databaseConnection);
|
|
|
|
require("./helpers/createTicket.js")(client, databaseConnection);
|
|
|
|
const restOptions = {
|
|
|
|
version: 0xa
|
|
|
|
};
|
|
|
|
const requestBody = {
|
|
|
|
"body": commandData
|
|
|
|
};
|
2024-04-08 12:09:36 +01:00
|
|
|
try {
|
|
|
|
console.log('Started refreshing application (/) commands.');
|
|
|
|
await new REST(restOptions).setToken(config.bot_token).put(Routes.applicationGuildCommands(client.user.id, config.guild_id), requestBody);
|
|
|
|
console.log('Successfully reloaded application (/) commands.');
|
|
|
|
} catch (error) {
|
|
|
|
console.error(error);
|
|
|
|
}
|
2024-04-02 04:02:22 +01:00
|
|
|
}
|
|
|
|
|
2024-04-08 12:09:36 +01:00
|
|
|
client.login(config.bot_token).catch((error) => {
|
|
|
|
console.error("Failed to log in:", error);
|
|
|
|
});
|
|
|
|
|
2024-04-02 04:02:22 +01:00
|
|
|
client.on("guildMemberUpdate", async (newMember, oldMember) => {
|
|
|
|
if (newMember.partial) {
|
|
|
|
try {
|
|
|
|
newMember.fetch();
|
|
|
|
} catch (error) {
|
|
|
|
return console.error("Something went wrong: ", error);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (newMember.guild.id !== config.guild_id) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
let roleChangeLog = '';
|
|
|
|
let newRoles = Array.from(newMember.roles.cache.keys());
|
|
|
|
let oldRoles = Array.from(oldMember.roles.cache.keys());
|
|
|
|
let packageRoles = config.package_roles.map(roleData => roleData.roleID);
|
|
|
|
packageRoles.push(config.api_role_id);
|
|
|
|
let addedRoles = newRoles.filter(roleID => !oldRoles.includes(roleID) && packageRoles.includes(roleID));
|
|
|
|
let removedRoles = oldRoles.filter(roleID => !newRoles.includes(roleID) && packageRoles.includes(roleID));
|
|
|
|
if (removedRoles.length) {
|
|
|
|
roleChangeLog = "<@&" + removedRoles.join("> <@&") + "> removed from " + newMember;
|
|
|
|
} else if (addedRoles.length) {
|
|
|
|
roleChangeLog = "<@&" + addedRoles.join("> <@&") + "> added to " + newMember;
|
|
|
|
}
|
|
|
|
if (!roleChangeLog.length) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
const logDetails = {
|
|
|
|
'name': "User Role Updated"
|
|
|
|
};
|
|
|
|
let logEmbed = new EmbedBuilder().setTimestamp().setColor("Random").setDescription(roleChangeLog).setAuthor(logDetails);
|
|
|
|
let notificationChannel = await newMember.guild.channels.fetch(config.notification_channelID)["catch"](_ => {});
|
|
|
|
if (!notificationChannel) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
const messageOptions = {
|
|
|
|
"embeds": [logEmbed]
|
|
|
|
};
|
|
|
|
return notificationChannel.send(messageOptions)["catch"](_ => {});
|
|
|
|
});
|
|
|
|
|
|
|
|
client.on("interactionCreate", async interaction => {
|
|
|
|
let { options } = interaction;
|
|
|
|
if (!interaction.isAutocomplete()) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (interaction.commandName == "remove-question") {
|
|
|
|
let searchQuery = options.getFocused(true);
|
|
|
|
let questions = await queryMulti(databaseConnection, "SELECT * FROM questions WHERE guildID='" + interaction.guildId + "'");
|
|
|
|
if (!questions) {
|
|
|
|
questions = [];
|
|
|
|
}
|
|
|
|
let filteredQuestions = questions.filter(questionData => {
|
|
|
|
return questionData.question?.["toLowerCase"]()["startsWith"](searchQuery.value.toLowerCase());
|
|
|
|
});
|
|
|
|
return interaction.respond(filteredQuestions.map(questionData => ({
|
|
|
|
'name': questionData.question,
|
|
|
|
'value': questionData.id
|
|
|
|
})));
|
|
|
|
} else {
|
|
|
|
if (interaction.commandName == "remove-ticket-option" || interaction.commandName == "create-question") {
|
|
|
|
let searchQuery = options.getFocused(true);
|
|
|
|
let optionsData = await queryMulti(databaseConnection, "SELECT * FROM options WHERE guildID='" + interaction.guildId + "'");
|
|
|
|
if (!optionsData) {
|
|
|
|
optionsData = [];
|
|
|
|
}
|
|
|
|
let filteredOptions = optionsData.filter(optionData => {
|
|
|
|
return optionData.name?.["toLowerCase"]()["startsWith"](searchQuery.value.toLowerCase());
|
|
|
|
});
|
|
|
|
return interaction.respond(filteredOptions.map(optionData => ({
|
|
|
|
'name': optionData.name,
|
|
|
|
'value': optionData.id
|
|
|
|
})));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
client.on("error", async error => {
|
|
|
|
console.log("Discord error '" + error.code + "' (" + error.message + ').', error);
|
|
|
|
});
|
|
|
|
|
|
|
|
async function updateActivity() {
|
|
|
|
setTimeout(updateActivity, 300000);
|
|
|
|
let userCount = (await apiHelper.getAllUsers()).length;
|
|
|
|
let activeOrdersCount = (await apiHelper.getActiveOrders()).length;
|
|
|
|
const activityDetails = {
|
|
|
|
"name": "Users: " + userCount + " / Orders: " + activeOrdersCount,
|
|
|
|
"type": ActivityType.Playing
|
|
|
|
};
|
|
|
|
const activityOptions = {
|
|
|
|
activities: [activityDetails]
|
|
|
|
};
|
|
|
|
client.user.setPresence(activityOptions);
|
2024-04-08 12:09:36 +01:00
|
|
|
}
|