JellyCommands

website·Indexed 31 days ago

https://jellycommands.dev

A fully typed framework built around discord.js for creating Discord bots. It provides a structured system for managing components such as slash, user, and message commands, events, buttons, and modals, featuring built-in support for guards, interaction deferring, and custom props.

Tokens
7.1K
Snippets
52
Records
58
Agent score
53%

What's inside JellyCommands

  1. Overview of Context Menu Commands in jellycommands

    Context menu commands allow users to trigger actions by right-clicking a message or user in Discord, removing the need to type a slash command. There are two types: messageCommand and userCommand. Unlike standard slash commands, context menu commands have more relaxed requirements regarding name casing.
  2. Implement Autocomplete for Slash Command options

    To provide real-time suggestions as a user types, set autocomplete: true on a specific option. You must then implement the autocomplete handler function. Inside this handler, use interaction.options.getFocused(true) to determine which option is being typed and its current value. Use interaction.respond() to return an array of up to 25 suggestions (though the example shows a slice of 3) containing name and value properties.
    import { command } from 'jellycommands';
    
    const colors = ['Violet', 'Indigo', 'Blue', 'Green', 'Yellow', 'Orange', 'Red'];
    
    export default command({
      name: 'color',
      description: 'get a colour of the rainbow',
      options: [
        {
          type: 'String',
          name: 'color',
          description: 'The color of the thing idk',
          required: true,
          autocomplete: true,
        },
      ],
      async run({ interaction }) {
        const colour = interaction.options.getString('color', true);
        await interaction.reply(`You chose the colour: ${colour}`);
      },
      async autocomplete({ interaction }) {
        // Get the name and value of the option currently being focused
        const focused = interaction.options.getFocused(true);
        
        if (focused.name === 'color') {
          // Filter list based on current input and respond with matches
          interaction.respond(
            colors
              .filter((color) => color.startsWith(focused.value))
              .map((color) => ({ name: color, value: color }))
              .slice(0, 3),
          );
        }
      },
    });
  3. Resolve component paths for portability

    Relative paths in the components option are resolved against the current working directory (cwd). To ensure the bot remains portable across different execution directories, use absolute paths. The recommended approach is using import.meta.dirname combined with node:path.join to create a path relative to the current file.
    import { JellyCommands } from 'jellycommands';
    import { join } from 'node:path';
    
    const client = new JellyCommands({
      // Use absolute path for portability
      components: [join(import.meta.dirname, './components')],
    });
  4. Update Guard Permissions for Discord.js v14

    When migrating to Discord.js v14, update permission strings within the guards configuration from SNAKE_CASE to CamelCase. For example, change ADMINISTRATOR to Administrator.
    export default command({
        guards: {
           permissions: ['Administrator'],
        },
    })
    
  5. Update dependencies for JellyCommands 1.0.0-next.44

    JellyCommands version 1.0.0-next.44 introduces minimum version requirements for the runtime environment and core dependencies. Ensure your project meets these minimums to avoid compatibility issues.
    Node: v20.13.1
    Discord.js: v14.15.3
  6. Export components for discovery

    JellyCommands identifies components by reading all exports of a loaded file. Only immediate values returned by the command() function are recognized. Nested exports (e.g., inside an array or object) are ignored. The name of the export is not used for discovery.
    import { command } from 'jellycommands';
    
    // These will be found
    export const test = command();
    export const test2 = command();
    export default command();
    
    // These will NOT be found
    export const test3 = [ command() ];
    export default { test };
  7. Import modules using CommonJS (CJS)

    In CommonJS, use the require function to import modules. You can import the entire module as a default export or use object destructuring to import specific named exports.
    // Import named export using destructuring
    const { Client } = require('discord.js');
    
    // Import default export
    const Discord = require('discord.js');
  8. Defer command responses for long-running tasks

    Discord requires a response within 3 seconds. To avoid interaction failure for tasks taking longer than 3 seconds, set defer: true in the command configuration. When a command is deferred, use interaction.followUp to send the final response instead of interaction.reply.
    import { command } from 'jellycommands';
    
    export default command({
      name: 'hello-world',
      description: 'demo command',
      defer: true,
      async run({ interaction }) {
        // Perform long-running task here
        await interaction.followUp('Hello World');
      },
    });
  9. Handle button interactions with the button component

    Use the button component from jellycommands to respond to button presses. The id property of the component must match the customId set on the ButtonBuilder when the button was created.
    import { button } from 'jellycommands';
    
    export default button({
      id: 'test', // Matches the .setCustomId('test') from the ButtonBuilder
      async run({ interaction }) {
        await interaction.reply({
          content: 'Hello World',
        });
      },
    });
  10. Export modules using ECMAScript Modules (ESM)

    ESM uses the export keyword. Unlike CommonJS, a single ESM module can contain both a default export and multiple named exports.
    // Named export
    export const something = 'Hello World';
    
    // Default export
    export default 'Hello World';
    
    // Example of both in one file:
    export default 'Hello World';
    export const something = true;
  11. Update Slash Command Options for Discord.js v14

    When migrating to Discord.js v14, update command option types from SNAKE_CASE to CamelCase to align with the new Discord.js enum naming convention. For example, change CHANNEL to Channel.
    export default command({
        options: [
            {
                type: 'Channel',
                name: 'channel',
                description: 'Channel to send a message into',
                required: true,
            },
        ],
    })
  12. Initialize a JellyCommands project using the official template

    The fastest way to start a project with JellyCommands is to use the official template, which sets up the necessary boilerplate and project structure automatically.
    npm create jellycommands@latest