Testify

Advanced all-in-one discord bot with prefix & slash commands

MIT License

Stars
51
Committers
5

To test out Testify, be sure to invite him to your server by clicking here

Table of Contents

Installation

Usage

  • Project Setup

    1. Fork the Github project :

      1. Sign up / Sign in to GitHub.
      2. Navigate to Testify.
      3. Click Star to support development.
      4. Click Fork to copy all code to your own repository.
    2. Click the Code button. From the drop-down that appears, click Download ZIP to download the entire repository as a ZIP folder.

    3. Extract the files to a new folder and open it with Visual Studio Code.

  • Obtain Discord Bot Token

    1. Sign in to Discord Developer Portal.

    2. Create a bot :

      1. Enter the left side Applications.
      2. Click New Application in the upper right corner and enter the name of the bot. After confirmation, enter the new page.
      3. Click on the left side Bot.
      4. Enable all intents listed under Privileged Gateway Intents and click Save Changes.
      5. View and copy the token by clicking the Reset Token button.
    3. Set up OAuth2 :

      1. Click on OAuth2 in the left column.
      2. Click on URL Generator in the left column.
      3. In the right column, select bot and applications.commands under SCOPES.
      4. Scroll down and select Administrator under BOT PERMISSIONS.
      5. Copy the URL at the bottom and paste it into your browser.
      6. Choose the server you want to add the bot to and click Continue > Authorize.
  • Obtain MongoDB Connection String

    1. Sign up / Sign in to MongoDB.
    2. Choose your preferred cloud database plan.
    3. Customize the cluster settings to your preference and click Create Cluster.
    4. Navigate to the Network Access page, click Add IP Address and select Allow access from anywhere.
    5. Navigate back to the Database page and click Connect.
    6. Create a database user, click Choose a connection method and select Connect your application.
    7. Copy your connection string and replace <password> with the password for the database user that you created earlier.
  • Setting up the env file

    If you go along with this, you can ignore the parts in the Project Execution that explain how to generate and fill in the .env

    1. For easy setup of the env files, ( .env & .development.env ) you can run the command npm run setup-env:prod
    2. Once you've ran the command, it generates a script in the console
    3. You need to then fill out the fields in the console. Fields marked with the text "Required" are you required fields and you need to fill those ones in. The script will not continue if you ignore to fill in those fields.
    4. Once you've filled in the field, it will write those fields into and generate the .env.
    5. Alternatively, you can ignore this and fill in the fields yourself by viewing the .example.env file.
    6. If you then want to setup the .env.development file, you can run the command npm run setup-env:dev and follow the steps above again.
  • Project Execution

    1. Rename the filed named example.env to .env
    2. Navigate to the Bot page on the Discord Developer Portal and click Reset Token. Afterwards, create a .env file within the root directory.
    3. Paste your bot token into the token variable inside the .env file.
    4. Paste your MongoDB connection string into the mongodb variable inside the .env file.
    5. Navigate to the OAuth2 page and copy the CLIENT ID.
    6. Paste your client ID into the clientid variable inside the .env file.
    7. Navigate to your discord server, enable developer mode and right click the dropdown beside the server name.
    8. Click Copy Server ID and paste it into the guildid variable inside the .env file.
    9. Navigate to the package.json file and pay attention to the runnable commands listed under scripts.
    10. Open the terminal in Visual Studio Code and install all necessary packages using npm run setup. This will install the dependencies and give you a brief install guide
    11. Open a new terminal and type npm run prod to run the file without using nodemon or npm run prod:nodemon to run the bot with nodemon.
    12. The bot should then turn online, you should be able to see this by the console logs that is setup upon start up
  • Runnable commands (scripts)

    Wipe Database - To wipe the database that is connected via your mongoDB url, you can run the command npm run wipe-data:prod, this brings up a menu which you can follow in order to either wipe the entire database from all it's data, or wipe all the data from individual schemas.

    Update Packages - To update all your dependencies, you can run the command npm run update-packages, this cycles through the dependencies and updates one's which are out of date.

    update-ytdl-core - To update the version of the ytdl-core package, you can run the command npm run update-ytdl-core, this updates the package to the most recent version to ensure the music system works.

    setup-env:prod - To run the setup of the .env file you can run the command npm run setup-env:prod, this generates a script in the console that generates a .env file and where you fill out the fields with whats required for the .env file and it writes it in the file.

    setup-env:dev - To run the setup of the .env.development file you can run the command npm run setup-env:dev, this generates a script in the console that generates a .env.development file and where you fill out the fields with whats required for the .env.development file and it writes it in the file.

Setting-up-audit-logs

To set the advanced logs registry for the Testify audit-logs ( the event handler registers ) than follow this!

  1. Navigate to node_modules => discord-logs => lib => index.js
  2. Once in the index.js file for the discord logs package you'll want to copy and paste this code in below.
 "use strict";
 var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
     function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
     return new (P || (P = Promise))(function (resolve, reject) {
         function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
         function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
         function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
         step((generator = generator.apply(thisArg, _arguments || [])).next());
     });
 };

 const color = {
     red: '\x1b[31m',
     orange: '\x1b[38;5;202m',
     yellow: '\x1b[33m',
     green: '\x1b[32m',
     blue: '\x1b[34m',
     reset: '\x1b[0m',
     pink: '\x1b[38;5;213m'
 }

 function getTimestamp() {
     const date = new Date();
     const year = date.getFullYear();
     const month = date.getMonth() + 1;
     const day = String(date.getDate()).padStart(2, "0");
     const hours = String(date.getHours()).padStart(2, "0");
     const minutes = String(date.getMinutes()).padStart(2, "0");
     const seconds = String(date.getSeconds()).padStart(2, "0");
     return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
 }

 const discord_js_1 = require("discord.js");
 const handlers_1 = require("./handlers");
 let eventRegistered = false;
 module.exports = (client, options) => __awaiter(void 0, void 0, void 0, function* () {
     if (eventRegistered)
         return;
     eventRegistered = true;
     const intents = new discord_js_1.IntentsBitField(client.options.intents);
     /* HANDLE GUILDS EVENTS */
     if (intents.has(discord_js_1.IntentsBitField.Flags.Guilds)) {
         if (options === null || options === void 0 ? void 0 : options.debug)
             console.log(`${color.pink}[${getTimestamp()}] ${color.reset}[AUDIT_LOGS] ChannelUpdate event handler registered.`);
         client.on('channelUpdate', (oldChannel, newChannel) => {
             (0, handlers_1.handleChannelUpdateEvent)(client, oldChannel, newChannel);
         });
         if (options === null || options === void 0 ? void 0 : options.debug)
             console.log(`${color.pink}[${getTimestamp()}] ${color.reset}[AUDIT_LOGS] GuildUpdate event handler registered.`);
         client.on('guildUpdate', (oldGuild, newGuild) => {
             (0, handlers_1.handleGuildUpdateEvent)(client, oldGuild, newGuild);
         });
         if (options === null || options === void 0 ? void 0 : options.debug)
             console.log(`${color.pink}[${getTimestamp()}] ${color.reset}[AUDIT_LOGS] RoleUpdate event handler registered.`);
         client.on('roleUpdate', (oldRole, newRole) => {
             (0, handlers_1.handleRoleUpdateEvent)(client, oldRole, newRole);
         });
         if (options === null || options === void 0 ? void 0 : options.debug)
             console.log(`${color.pink}[${getTimestamp()}] ${color.reset}[AUDIT_LOGS] ThreadUpdate event handler registered.`);
         client.on('threadUpdate', (oldThread, newThread) => {
             (0, handlers_1.handleThreadChannelUpdateEvent)(client, oldThread, newThread);
         });
     }
     else {
         if (options === null || options === void 0 ? void 0 : options.debug)
             console.log(`channelUpdate, guildUpdate, roleUpdate and threadUpdate event handlers not registered (missing Guilds intent).`);
     }
     /* HANDLE MEMBER EVENTS */
     if (intents.has(discord_js_1.IntentsBitField.Flags.GuildMembers)) {
         if (options === null || options === void 0 ? void 0 : options.debug)
             console.log(`${color.pink}[${getTimestamp()}] ${color.reset}[AUDIT_LOGS] GuildMemberUpdate event handler registered.`);
         client.on('guildMemberUpdate', (oldMember, newMember) => {
             (0, handlers_1.handleGuildMemberUpdateEvent)(client, oldMember, newMember);
         });
         if (options === null || options === void 0 ? void 0 : options.debug)
             console.log(`${color.pink}[${getTimestamp()}] ${color.reset}[AUDIT_LOGS] UserUpdate event handler registered.`);
         client.on('userUpdate', (oldUser, newUser) => {
             (0, handlers_1.handleUserUpdateEvent)(client, oldUser, newUser);
         });
     }
     else {
         if (options === null || options === void 0 ? void 0 : options.debug)
             console.log('guildMemberUpdate, userUpdate event handlers not registered (missing GuildMembers intent).');
     }
     /* HANDLE MESSAGE UPDATE EVENTS */
     if (intents.has(discord_js_1.IntentsBitField.Flags.GuildMessages && discord_js_1.IntentsBitField.Flags.MessageContent)) {
         if (options === null || options === void 0 ? void 0 : options.debug)
             console.log(`${color.pink}[${getTimestamp()}] ${color.reset}[AUDIT_LOGS] MessageUpdate event handler registered.`);
         client.on('messageUpdate', (oldMessage, newMessage) => {
             (0, handlers_1.handleMessageUpdateEvent)(client, oldMessage, newMessage);
         });
     }
     else {
         if (options === null || options === void 0 ? void 0 : options.debug)
             console.log('messageUpdate event handler not registered (missing GuildMessages or MessageContent intent).');
     }
     /* HANDLE PRESENCE UPDATE EVENTS */
     if (intents.has(discord_js_1.IntentsBitField.Flags.GuildPresences)) {
         if (options === null || options === void 0 ? void 0 : options.debug)
             console.log(`${color.pink}[${getTimestamp()}] ${color.reset}[AUDIT_LOGS] PresenceUpdate event handler registered.`);
         client.on('presenceUpdate', (oldPresence, newPresence) => {
             (0, handlers_1.handlePresenceUpdateEvent)(client, oldPresence, newPresence);
         });
     }
     else {
         if (options === null || options === void 0 ? void 0 : options.debug)
             console.log('presenceUpdate event handler not registered (missing GuildPresences intent).');
     }
     /* HANDLE VOICE STATE UPDATE */
     if (intents.has(discord_js_1.IntentsBitField.Flags.GuildVoiceStates)) {
         if (options === null || options === void 0 ? void 0 : options.debug)
             console.log(`${color.pink}[${getTimestamp()}] ${color.reset}[AUDIT_LOGS] VoiceStateUpdate event handler registered.`);
         client.on('voiceStateUpdate', (oldState, newState) => {
             (0, handlers_1.handleVoiceStateUpdateEvent)(client, oldState, newState);
         });
     }
     else {
         if (options === null || options === void 0 ? void 0 : options.debug)
             console.log('voiceStateUpdate event handler not registered (missing GuildVoiceStates intent).');
     }
 });
  1. This code makes the logs register like so this image below
  2. To update the color of the logs, you can change the part ${color.pink} to the color you'd like which are defined in the color variable.
  3. That should be it, now when you start up the bot, it should look all cool 😎

Support

Connect with us on Discord for support / any related inquiry.

License

Released under the terms of MIT License license.

Thanks to TheLegendDev for the readme template from Nub Bot 💛