JSPM

  • ESM via JSPM
  • ES Module Entrypoint
  • Export Map
  • Keywords
  • License
  • Repository URL
  • TypeScript Types
  • README
  • Created
  • Published
  • Downloads 2
  • Score
    100M100P100Q35445F
  • License MIT

A specialized library for managing interactive elements of Discord bots

Package Exports

  • intmen-lib
  • intmen-lib/dist/index.js

This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (intmen-lib) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.

Readme

Intmen-lib

Intmen-lib npm version License: MIT TypeScript Discord.js Test Coverage

A specialized library for managing interactive elements of Discord bots, including slash commands, buttons, select menus, modals, context menus, and autocomplete interactions.

๐Ÿš€ NEW VERSION 1.1.0 AVAILABLE: Featuring enhanced error handling, improved builders, and new utility classes. This version is stable and recommended for production use.

โœจ Features

  • ๐Ÿš€ Simple API - Intuitive interface for managing Discord interactions
  • ๐Ÿ”’ Type-Safe - Built with TypeScript for robust type checking and strict typing
  • ๐Ÿ“ฆ Complete - Supports all Discord interaction types: slash commands, context menus, buttons, select menus, modals, and autocomplete
  • ๐Ÿงฉ Modular - Flexible architecture for clean code organization
  • โšก Builder Pattern - Fluent builders for easy creation of interactive elements
  • ๐Ÿ›ก๏ธ Error Handling - Comprehensive error management with proper typing
  • ๐Ÿงช Fully Tested - High test coverage (>93%) for reliability
  • ๐Ÿ“˜ Well Documented - Clear and concise documentation
  • ๐Ÿ”‘ Permission Utilities - Simplify Discord permission checks with built-in utilities
  • โœ… Validation - Robust interaction validation with fluent API

๐Ÿ“ฅ Installation

# Using npm
npm install intmen-lib

# Using yarn
yarn add intmen-lib

# Using pnpm
pnpm add intmen-lib

๐Ÿš€ Quick Start

import { Client, GatewayIntentBits } from 'discord.js';
import { InteractionManager, SlashCommandBuilder } from 'intmen-lib';

// Create Discord client
const client = new Client({ 
  intents: [GatewayIntentBits.Guilds] 
});

// Create interaction manager
const manager = new InteractionManager(client);

// Register slash command
const pingCommand = new SlashCommandBuilder()
  .setName('ping')
  .setDescription('Check bot latency')
  .setHandler(async (interaction) => {
    const sent = await interaction.reply({ 
      content: '๐Ÿ“ก Pinging...', 
      fetchReply: true 
    });
    
    const latency = sent.createdTimestamp - interaction.createdTimestamp;
    await interaction.editReply(`๐Ÿ“ก Pong! Latency: ${latency}ms`);
  });

// Add command to manager
manager.registerCommand(pingCommand.build());

// Register commands with Discord API
client.once('ready', async () => {
  await manager.registerGlobalCommands(client.application.id);
  console.log('Bot is ready and commands are registered!');
});

// Login
client.login('YOUR_TOKEN_HERE');

๐Ÿ“– Documentation

New in v1.1.0

  • Enhanced error handling with customizable error responses
  • Improved SlashCommandBuilder with subcommand support
  • Added ContextMenuCommandBuilder for easier creation of context menu commands
  • New permission utilities for checking user permissions
  • Interaction validators for validating and filtering interactions
  • Improved type safety throughout the library
  • Better timeout handling for interactions

Interactive Elements

Slash Commands

// Create a command with options
const userCommand = new SlashCommandBuilder()
  .setName('user')
  .setDescription('Get information about a user')
  .addUserOption(option => 
    option
      .setName('target')
      .setDescription('Target user')
      .setRequired(true)
  )
  .setHandler(async (interaction) => {
    const user = interaction.options.getUser('target');
    await interaction.reply(`Username: ${user.username}`);
  });

manager.registerCommand(userCommand.build());

Slash Commands with Subcommands

// Create a command with subcommands
const settingsCommand = new SlashCommandBuilder()
  .setName('settings')
  .setDescription('Manage bot settings')
  .addSubcommand(subcommand =>
    subcommand
      .setName('view')
      .setDescription('View current settings')
  )
  .addSubcommand(subcommand =>
    subcommand
      .setName('edit')
      .setDescription('Edit a setting')
      .addStringOption(option =>
        option
          .setName('setting')
          .setDescription('Setting to edit')
          .setRequired(true)
      )
      .addStringOption(option =>
        option
          .setName('value')
          .setDescription('New value')
          .setRequired(true)
      )
  )
  .setHandler(async (interaction) => {
    const subcommand = interaction.options.getSubcommand();
    
    if (subcommand === 'view') {
      await interaction.reply('Here are your current settings...');
    } else if (subcommand === 'edit') {
      const setting = interaction.options.getString('setting');
      const value = interaction.options.getString('value');
      await interaction.reply(`Setting ${setting} updated to ${value}`);
    }
  });

manager.registerCommand(settingsCommand.build());

Context Menu Commands

import { ContextMenuCommandBuilder } from 'intmen-lib';

// Create a user context menu command
const userInfoContextMenu = new ContextMenuCommandBuilder()
  .setName('User Info')
  .setUserContextMenu()
  .setHandler(async (interaction) => {
    const user = interaction.targetUser;
    await interaction.reply({
      content: `Information about ${user.username}`,
      ephemeral: true
    });
  });

manager.registerCommand(userInfoContextMenu.build());

// Create a message context menu command
const translateContextMenu = new ContextMenuCommandBuilder()
  .setName('Translate Message')
  .setMessageContextMenu()
  .setHandler(async (interaction) => {
    const message = interaction.targetMessage;
    await interaction.reply({
      content: `Translating: ${message.content.slice(0, 100)}...`,
      ephemeral: true
    });
  });

manager.registerCommand(translateContextMenu.build());

Buttons

import { ButtonBuilder, ButtonStyle } from 'intmen-lib';

// Create a styled button
const button = new ButtonBuilder()
  .setCustomId('confirm_button')
  .setLabel('Confirm')
  .setStyle(ButtonStyle.SUCCESS)
  .setEmoji('โœ…')
  .setHandler(async (interaction) => {
    await interaction.reply({ 
      content: 'Action confirmed!', 
      ephemeral: true 
    });
  });

manager.registerButton(button.build());

// In your command handler
await interaction.reply({
  content: 'Please confirm this action',
  components: [
    {
      type: 1, // ActionRow
      components: [button.toJSON()]
    }
  ]
});

Select Menus

import { SelectMenuBuilder } from 'intmen-lib';

// Create a select menu with options
const roleMenu = new SelectMenuBuilder()
  .setCustomId('role_menu')
  .setPlaceholder('Select your role')
  .addOption({
    label: 'Developer', 
    value: 'dev', 
    description: 'Software developer', 
    emoji: '๐Ÿ’ป'
  })
  .addOption({
    label: 'Designer', 
    value: 'design', 
    description: 'UI/UX designer',
    emoji: '๐ŸŽจ'
  })
  .setHandler(async (interaction) => {
    const roles = interaction.values;
    await interaction.reply({
      content: `You selected: ${roles.join(', ')}`,
      ephemeral: true
    });
  });

manager.registerSelectMenu(roleMenu.build());

Modals

import { ModalBuilder, TextInputStyle } from 'intmen-lib';

// Create a modal form
const feedbackModal = new ModalBuilder()
  .setCustomId('feedback_form')
  .setTitle('Submit Feedback')
  .addTextInput({
    customId: 'feedback_name',
    label: 'Your Name',
    style: TextInputStyle.Short,
    required: true
  })
  .addTextInput({
    customId: 'feedback_content',
    label: 'Your Feedback',
    style: TextInputStyle.Paragraph,
    placeholder: 'Please provide your feedback here...',
    required: true,
    minLength: 10,
    maxLength: 1000
  })
  .setHandler(async (interaction) => {
    const name = interaction.fields.getTextInputValue('feedback_name');
    const feedback = interaction.fields.getTextInputValue('feedback_content');
    
    await interaction.reply({
      content: `Thank you, ${name}! Your feedback has been received.`,
      ephemeral: true
    });
    
    // Process the feedback...
  });

manager.registerModal(feedbackModal.build());

// Show modal in a command or button handler
await interaction.showModal(feedbackModal.toJSON());

New Utilities in v1.1.0

Permission Utilities

import { PermissionUtils, PermissionFlagsBits } from 'intmen-lib';

// In a command handler
if (PermissionUtils.hasPermission(interaction.member, PermissionFlagsBits.ManageMessages)) {
  // User has permission to manage messages
  await interaction.reply('You can manage messages!');
} else {
  // User lacks permission
  const missingPermissions = PermissionUtils.getMissingPermissions(
    interaction.member, 
    [PermissionFlagsBits.ManageMessages]
  );
  
  const readableNames = PermissionUtils.getReadablePermissionNames(missingPermissions);
  await interaction.reply({
    content: `You lack the required permissions: ${readableNames.join(', ')}`,
    ephemeral: true
  });
}

Interaction Validators

import { InteractionValidators } from 'intmen-lib';

// In a button handler
if (InteractionValidators.isFromUser(interaction, originalUserId)) {
  // Only the original user can interact with this button
  await interaction.reply('Processing your request...');
} else {
  await interaction.reply({
    content: 'This button is not for you!',
    ephemeral: true
  });
}

// Combine multiple conditions
const isValid = InteractionValidators.all(interaction, [
  // Must be in a guild
  (int) => InteractionValidators.isInGuild(int),
  // Must be in a specific channel
  (int) => InteractionValidators.isInChannel(int, targetChannelId),
  // Custom condition
  (int) => InteractionValidators.custom(int, i => i.user.id === ownerId || i.member.roles.cache.has(adminRoleId))
]);

if (isValid) {
  // All conditions passed
  await interaction.reply('Command executed successfully!');
} else {
  await interaction.reply({
    content: 'You cannot use this command here!',
    ephemeral: true
  });
}

Timeout Utilities

import { withTimeout } from 'intmen-lib';

// Automatically timeout a long-running operation
const result = await withTimeout(
  someAsyncOperation(), // Promise that might take too long
  5000, // Timeout in ms (5 seconds)
  () => {
    // Optional callback when timeout occurs
    console.log('Operation timed out');
    return 'Fallback value';
  }
);

// With interaction handler
const command = new SlashCommandBuilder()
  .setName('search')
  .setDescription('Search for something')
  .setHandler(async (interaction) => {
    // Defer the reply first
    await interaction.deferReply();
    
    try {
      // Wrap the long operation with timeout
      const result = await withTimeout(
        performLongSearch(interaction.options.getString('query')),
        10000, // 10 seconds
        async () => {
          // This runs if the operation times out
          await interaction.editReply('The search operation timed out!');
          return null; // Return a fallback value
        }
      );
      
      if (result) {
        await interaction.editReply(`Search results: ${result}`);
      }
    } catch (error) {
      await interaction.editReply('An error occurred during the search.');
    }
  });

๐Ÿค Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

  1. Fork the repository
  2. Create your feature branch: git checkout -b feature/amazing-feature
  3. Commit your changes: git commit -m 'Add some amazing feature'
  4. Push to the branch: git push origin feature/amazing-feature
  5. Open a Pull Request

๐Ÿ“ License

Distributed under the MIT License. See LICENSE for more information.

๐Ÿ”„ Changelog

v1.1.0

  • Added support for subcommands and subcommand groups
  • Created new ContextMenuCommandBuilder for easier context menu commands
  • Added PermissionUtils for managing Discord permissions
  • Added InteractionValidators for interaction validation
  • Enhanced error handling with customizable error responses
  • Improved timeout handling for long-running operations
  • Added extensive documentation

v1.0.4

  • Fixed critical issues with interaction handling
  • Enhanced type safety for TypeScript users
  • Improved error handling

v1.0.3

  • Initial stable release
  • Core interaction management functionality
  • Basic builders for all interaction types