npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@squiddleton/discordjs-util

v1.3.0

Published

Utility classes and functions for discord.js

Downloads

95

Readme

discord.js-Util

About

Useful utility classes and functions that make discord.js bot developing more efficient.

Usage

Node.js v14+ is required.

First, install this scoped package by running the following command in your terminal:

npm install @squiddleton/discordjs-util

Client

The package exports a Client class that extends the native discord.js class of the same name. By providing more options when initializing it, more features become available:

const { Client } = require('@squiddleton/discordjs-util'); // This package is compiled to CommonJS, so both require() and import syntax are supported
const { GatewayIntentBits } = require('discord.js'); // This package supplements discord.js instead of replacing it

// 'devGuildId' is one property added to the extended Client options, but
// more are available as shown in the extended ClientOptions TSDoc annotations
const client = new Client({ intents: [GatewayIntentBits.Guilds], devGuildId: '1234567890123456789' });

client.on('ready', () => {
    console.log(client.devGuild.name); // Prints the name of the devGuild retrieved from its id
});

client.login('token here');

Commands

The SlashCommand and ContextMenu classes provide support for the construction of Chat Input and Context Menu application commands, respectively.

const { Client, ContextMenu, evalCommand, SlashCommand } = require('@squiddleton/discordjs-util');

const pingCommand = new SlashCommand({
    name: 'ping',
    description: 'Replies with pong',
    scope: 'Global', // Scopes determine where commands are deployed to
    async execute(interaction) {
        await interaction.reply('Pong!');
    }
});

const evalContextMenu = new ContextMenu({
    name: 'Eval',
    type: ApplicationCommandType.Message,
    scope: 'Dev', // Only deployed to the server indicated with the "devGuildId" in the ClientOptions
    async execute(interaction) {
        await evalCommand(interaction, interaction.targetMessage.content, true); // evalCommand() is a function tailored for application commands
    }
});

const client = new Client({ intents: [GatewayIntentBits.Guilds], commands: [pingCommand, evalContextMenu] });

client.on('ready', async () => {
    if (client.isReady()) {
        await client.deploy(); // Deploys all commands from the ClientOptions "commands" array (should only be called when command structures are updated)
    }
});

client.login('token here');

The constructor argument can contain other properties familiar to the official discord.js guide's command handler, including options and permissions.

The scope property of a command is entirely custom, and it determines where the command will be deployed. There are four possible scopes:

  1. Global: The command is deployed globally and is accessible in both servers and direct messages.
  2. Guild: The command is deployed globally but is only accessible in servers.
  3. Dev: The command is only deployed in the guild with the id from devGuildId in the ClientOptions (if provided).
  4. Exclusive: The command is only deployed in the guild with the id from exclusiveGuildId in the ClientOptions (if provided) and deployed in the devGuild (if provided). This is to ensure that all commands are accessible in the devGuild.

Both command class instances have a .toJSON() method which returns an object in ApplicationCommandData format. The ContextMenu class also has .isMessage() and .isUser() methods which will narrow down the its specific type.

Events

The ClientEvent class standardizes the construction of the events that the client emits, and it automatically adds listeners for those events to the client upon construction.

const { Client, ClientEvent } = require('@squiddleton/discordjs-util');

const event1 = new ClientEvent({
    name: 'ready',
    once: true, // Registers the event using EventEmitter#once() instead of EventEmitter#on()
    async execute(client) {
        console.log(`Now logged in as ${client.user.tag}!`);
    }
});

const event2 = new ClientEvent({
    name: 'interactionCreate',
    async execute(interaction) { // No "once" property defaults to using #on()
        if (interaction.isRepliable()) {
            await interaction.reply('Hi!');
        }
    }
});

const client = new Client({ intents: [GatewayIntentBits.Guilds], events: [event1, event2] });
// When ready, the Client's username will be logged, and any application command interactions will be met with "Hi!"

client.login('token here');

Miscellaneous

Along with the aforementioned evalCommand() function, this package has two more functions as top-level exports: validateChannel() and validateGuild().

Using the normal discord.js method <Client>.(channels|guild).cache.get(<Id>) returns a union type of either the expected structure or undefined. Additionally, getting channels by this method provides no automatic typeguarding, so typeguards like <BaseChannel>.isTextBased() must be used before calling .send() on the channel. Both of these methods return solely the structure instead of possibly returning undefined; if the structure is unavailable, an error will be thrown to call out this unexpected behavior. When the third argument of validateChannel() is set to true (the default value), it will also only return a TextBasedChannel, otherwise throwing an error. Although these functions may seem insignificant, TypeScript users will find this automatic type narrowing much more efficient than manually checking every time a channel/guild is retrieved.

const { Client, ClientEvent, validateChannel, validateGuild } = require('@squiddleton/discordjs-util');

const ready = new ClientEvent({
    name: 'ready',
    once: true,
    async execute(client) {
        const channel = validateChannel(client, '1234567890123456789'); // TextBasedChannel instead of Channel|undefined
        const guild = validateGuild(client, '987654310987654321'); // Guild instead of Guild|undefined

        await channel.send(guild.name);
    }
});

const client = new Client({ intents: [GatewayIntentBits.Guilds], events: [ready] });

Credits

This package is fully independent and unaffiliated with both Discord Inc. and discord.js.