Examples

Practical examples to help you get started with Disapp.

Simple Bot

import { DisappClient } from "@disapp/core";
import { GatewayIntentBits } from "discord.js";

const client = new DisappClient({
  intents: [GatewayIntentBits.Guilds],
  config: {
    token: process.env.DISCORD_TOKEN!,
    clientId: process.env.CLIENT_ID!,
    database: {
      url: process.env.DATABASE_URL!,
    },
  },
});

await client.start();

Slash Command

import { Command } from "@disapp/core";
import { SlashCommandBuilder, ChatInputCommandInteraction } from "discord.js";

export default class AvatarCommand extends Command {
  constructor() {
    super({
      name: "avatar",
      description: "Show user avatar",
      data: new SlashCommandBuilder()
        .setName("avatar")
        .setDescription("Show user avatar")
        .addUserOption((option) =>
          option
            .setName("user")
            .setDescription("User to show avatar")
            .setRequired(false),
        ),
      execute: async () => {},
    });
  }

  async execute(interaction: ChatInputCommandInteraction): Promise<void> {
    const user = interaction.options.getUser("user") || interaction.user;

    const embed = {
      color: 0x5865f2,
      title: `${user.username} Avatar`,
      image: {
        url: user.displayAvatarURL({ size: 1024 }),
      },
    };

    await interaction.reply({ embeds: [embed] });
  }
}

Database Usage

import { Command, UserRepository } from "@disapp/core";
import { SlashCommandBuilder, ChatInputCommandInteraction } from "discord.js";

export default class ProfileCommand extends Command {
  private userRepo: UserRepository;

  constructor() {
    super({
      name: "profile",
      description: "Show user profile",
      data: new SlashCommandBuilder()
        .setName("profile")
        .setDescription("Show user profile"),
      execute: async () => {},
    });

    this.userRepo = new UserRepository();
  }

  async execute(interaction: ChatInputCommandInteraction): Promise<void> {
    const dbUser = await this.userRepo.getOrCreate(
      BigInt(interaction.user.id),
      interaction.user.username,
      interaction.user.avatar || undefined,
    );

    const embed = {
      color: 0x5865f2,
      title: "Profile",
      fields: [
        {
          name: "User",
          value: interaction.user.username,
          inline: true,
        },
        {
          name: "Registration Date",
          value: `<t:${Math.floor(dbUser.createdAt!.getTime() / 1000)}:R>`,
          inline: true,
        },
      ],
    };

    await interaction.reply({ embeds: [embed] });
  }
}

Event Handling

import { Event } from "@disapp/core";
import { Events, Message } from "discord.js";

export default class MessageCreateEvent extends Event {
  constructor() {
    super({
      name: Events.MessageCreate,
      once: false,
      execute: async () => {},
    });
  }

  async execute(message: Message): Promise<void> {
    if (message.author.bot) return;

    if (message.content.toLowerCase() === "hello") {
      await message.reply("Hello! 👋");
    }
  }
}

Cooldown System

import { Command, Cooldown } from "@disapp/core";
import { SlashCommandBuilder, ChatInputCommandInteraction } from "discord.js";

export default class DailyCommand extends Command {
  constructor() {
    super({
      name: "daily",
      description: "Claim your daily reward",
      data: new SlashCommandBuilder()
        .setName("daily")
        .setDescription("Claim your daily reward"),
      execute: async () => {},
      middlewares: [Cooldown(86400000)],
    });
  }

  async execute(interaction: ChatInputCommandInteraction): Promise<void> {
    await interaction.reply("🎁 You claimed your daily reward! +100 coins");
  }
}

Components V2

import { Command, v2 } from "@disapp/core";
import { SlashCommandBuilder, ButtonStyle } from "discord.js";

export default class MenuCommand extends Command {
  constructor() {
    super({
      name: "menu",
      description: "Show menu",
      data: new SlashCommandBuilder()
        .setName("menu")
        .setDescription("Show menu"),
      execute: async () => {},
    });
  }

  async execute(interaction: any): Promise<void> {
    const message = v2()
      .text("# Main Menu")
      .separator()
      .buttons(
        {
          id: "option1",
          label: "Option 1",
          style: ButtonStyle.Primary,
          onClick: async (i) => {
            await i.reply("You selected Option 1!");
          },
        },
        {
          id: "option2",
          label: "Option 2",
          style: ButtonStyle.Success,
          onClick: async (i) => {
            await i.reply("You selected Option 2!");
          },
        },
      )
      .accentColor(0x5865f2)
      .build();

    await interaction.reply(message);
  }
}

Internationalization

import { Command, I18nHelper } from "@disapp/core";
import { SlashCommandBuilder } from "discord.js";

export default class GreetCommand extends Command {
  constructor() {
    super({
      name: "greet",
      description: "Greet a user",
      data: new SlashCommandBuilder()
        .setName("greet")
        .setDescription("Greet a user")
        .addUserOption((o) =>
          o.setName("user").setDescription("User to greet").setRequired(true),
        ),
      execute: async () => {},
    });
  }

  async execute(interaction: any) {
    const user = interaction.options.getUser("user");
    const lang = interaction.locale?.split("-")[0] || "en";

    const greeting = I18nHelper.t("greet.message", lang, {
      user: user.username,
    });

    await interaction.reply(greeting);
  }
}

More Examples

Check out the basic-bot example for a complete working bot with:

  • Multiple commands
  • Event handlers
  • Database integration
  • Internationalization
  • Hot reload
  • And more!