Skip to main content
Yato is built on Discord.js v12 and uses the gcommands framework for command handling. This page explains the core architecture and how different components work together.

Project structure

The bot follows a modular architecture with clear separation of concerns:
src/
├── index.js              # Entry point and bot initialization
├── commands/             # Command modules organized by category
│   ├── games/
│   ├── images/
│   ├── information/
│   ├── memes/
│   ├── misc/
│   ├── moderation/
│   ├── utilities/
│   └── weeb/
├── models/               # MongoDB schema definitions
│   ├── css.js
│   └── user.js
├── structures/           # Custom classes and utilities
│   ├── BotEmbed.js
│   ├── CanvasUtils.js
│   ├── CanvasTemplates.js
│   └── utils.js
└── config/               # Configuration files
    ├── colors.json
    ├── emojis.json
    └── message.json

Core initialization

The bot initializes in src/index.js:1 with the following flow:
1

Load environment variables

The bot loads configuration from .env using dotenv.
require('dotenv').config();
2

Initialize Canvas utilities

Custom canvas helpers are registered before the client starts.
require('./structures/CanvasUtils').initializeHelpers();
3

Create Discord client

The Discord.js client is created with allowed mentions configuration.
const client = new Discord.Client({ 
  allowedMentions: { parse: ['users', 'roles'] } 
});
4

Connect to MongoDB

Database connection is established in the ready event at src/index.js:11.
await mongoose.connect(process.env.MONGO_URI, { 
  useNewUrlParser: true, 
  useUnifiedTopology: true 
});
5

Initialize gcommands

The gcommands framework is configured to handle commands at src/index.js:15.
const GCommandsClient = new GCommands(client, {
  cmdDir: 'src/commands/',
  language: 'english',
  ownLanguageFile: require('./config/message.json'),
  unkownCommandMessage: true,
  slash: {
    slash: 'both',
    prefix: `^<@!?${client.user.id}> `
  },
  defaultCooldown: '3s'
});

The gcommands framework

Yato uses gcommands v5.2.4 to handle both slash commands and message-based commands with a single codebase.

Key features

Dual command support

Commands work as both slash commands and mention-based prefix commands (@Yato help).

Automatic registration

Commands in src/commands/ are automatically loaded and registered.

Built-in validation

Permission checks, argument validation, and cooldowns are handled by the framework.

Interaction components

Provides utilities for buttons, select menus, and other Discord components.

Configuration options

The gcommands client accepts several configuration options:
OptionValuePurpose
cmdDir'src/commands/'Directory containing command modules
language'english'Default language for built-in messages
ownLanguageFileCustom JSONOverride default error messages
slash'both'Enable both slash and prefix commands
prefixMention regexCommands triggered by mentioning the bot
defaultCooldown'3s'Default cooldown between command uses

Custom structures

Yato extends Discord.js functionality with custom structures:

BotEmbed

Located at src/structures/BotEmbed.js:1, this class extends MessageEmbed with a splitFields() method that automatically handles long content by splitting it across multiple embed fields.
const BotEmbed = require('./structures/BotEmbed');
const embed = new BotEmbed()
  .splitFields('Long Title', veryLongContent);

CanvasUtils

Provides image manipulation helpers at src/structures/CanvasUtils.js:1:
  • Custom context methods: roundImage(), circle(), roundRect(), write()
  • Font registration: Montserrat and Segoe UI families
  • Text alignment: 9-point alignment system (top-left, center, etc.)
  • Advanced effects: Blur, icon coloring, paragraph wrapping
Canvas utilities must be initialized before the bot starts by calling CanvasUtils.initializeHelpers() in the entry file.

Utils module

The src/structures/utils.js:1 file contains shared utilities:
  • cleanHTML() - Strip HTML tags from text
  • descriptionParser() - Truncate descriptions to 800 characters
  • formatPerms() - Format permission names for display
  • formatArray() - Format arrays using Intl.ListFormat
  • animeMangaSearch() - Search anime/manga via AniList API
  • redditFetcher() - Fetch posts from Reddit

Command categories

Commands are organized into logical categories:
Game server queries and integrations (Counter-Strike, Minecraft)
Anime reaction images (hug, pat, kiss, slap, etc.)
Server info, user info, bot stats, help menu
Meme and anime meme fetching from Reddit
Discord activities, avatars, documentation search
Kick, ban, and other moderation actions
Ping, uptime, purge messages, announcements
AniList and MyAnimeList integrations

Status rotation

The bot rotates between different status messages every 15 seconds:
const statuses = [
  `/help | @Yato help`,
  `${client.guilds.cache.size} Servers!`
];
setInterval(() => {
  const status = statuses[Math.floor(Math.random() * statuses.length)];
  client.user.setPresence({ 
    activity: { name: status, type: 'LISTENING' }, 
    status: 'idle' 
  });
}, 15000);

Dependencies

Key dependencies used by Yato:
{
  "discord.js": "^12.5.3",
  "gcommands": "^5.2.4",
  "mongoose": "^5.12.12"
}
The bot uses Discord.js v12, which is outdated. See the upgrading guide for migration to v14+.

Build docs developers (and LLMs) love