Discord_API_Bot/index.js
2024-04-01 19:02:22 -08:00

227 lines
7.8 KiB
JavaScript

const fs = require('fs');
const sqlite3 = require('sqlite3').verbose();
const request = require("request");
const config = require("./config.js");
const packageInfo = require("./package.json");
const terminal = require("terminal-kit").terminal;
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 mysql = require('mysql');
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
databaseConnection = new sqlite3.Database(config.sqlite.dbPath, sqlite3.OPEN_READWRITE, (err) => {
if (err) {
console.error("Error opening database", err.message);
} else {
console.log("Connected to the SQLite database.");
// Ensure a table exists
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);
}
});
}
});
function handleDisconnect() {
const mysqlConfig = {
"port": config.mysql.port,
"charset": 'utf8mb4',
host: config.mysql.host,
"user": config.mysql.user,
"password": config.mysql.password,
"database": config.mysql.database
};
databaseConnection = mysql.createConnection(mysqlConfig);
databaseConnection.connect(function (connectionError) {
if (connectionError) {
console.log("error when connecting to db:", connectionError);
setTimeout(handleDisconnect, 0x7d0);
} else {
require("./helpers/ready.js")(databaseConnection);
console.log("Connected to database!");
}
});
databaseConnection.on("error", function (dbError) {
console.log("db error", dbError);
if (dbError.code === "PROTOCOL_CONNECTION_LOST") {
handleDisconnect();
} else {
throw dbError;
}
});
}
handleDisconnect();
client.login(config.bot_token).then(() => {
console.log("Successfully logged in.");
checkLicense();
}).catch((error) => {
console.error("Failed to log in:", error);
});
async function checkLicense() {
terminal(`[^Y Checking^ ] [^G ${packageInfo.description} Checking license^ ].\n`);
const headers = {
"Content-Type": "application/json"
};
const requestData = {
"license": config.licenseKey,
domain: config.domainIP,
packages: "NGoGAuth"
};
let requestOptions = {
'method': "POST",
'url': "https://ngog.net/api/v1/licenses/public/validate",
'headers': headers,
'body': JSON.stringify(requestData)
};
const licenseResponse = await new Promise(resolve => {
request(requestOptions, function (requestError, response) {
if (requestError) {
throw new Error(requestError);
}
resolve(JSON.parse(response.body));
});
});
if (licenseResponse.success) {
client.login(config.bot_token);
terminal(`[^G AUTHORIZED^ ][^B V${packageInfo.version}^ ] [^G ${packageInfo.description} ${licenseResponse.message}^ ]\n`);
} else {
terminal(`[^R UNAUTHORIZED^ ] ${licenseResponse.errors}.\n\n^+Activating Bot:^-\n^K Join our support server: https://discord.gg/TB8WN3fbFM \n^-`);
}
}
client.on('ready', () => {
client.user.setStatus("Online");
client.commands = new Collection();
readCommands();
updateActivity();
terminal(`[^B INFO^ ] [^GLogged in as ${client.user.tag}^ ]\n`);
});
async function readCommands() {
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
};
await new REST(restOptions).setToken(config.bot_token).put(Routes.applicationGuildCommands(client.user.id, config.guild_id), requestBody);
}
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);
}