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 🙏

© 2026 – Pkg Stats / Ryan Hefner

admix.js

v1.1.2

Published

Official SDK for Admix bots

Readme

admix.js

Version 1.1.2
A comprehensive, developer-friendly API wrapper for Admix bots (admix.admibot.xyz) with rich REST helpers, interaction handling, and a fully synchronized websocket cache.

Overview

admix.js is a Node.js SDK built to feel like a modern bot framework: simple to start, structured enough for production, and flexible enough for advanced integrations.

It gives you:

  • High-level API wrappers for chat, guild, interaction, and bot management.
  • Strong interaction support (deferReply, deferUpdate, direct interaction replies, and component triggers).
  • Chainable builders for embeds and UI components.
  • Permission helpers and channel-format constants.
  • A live cache layer that keeps guilds, channels, roles, members, messages, DMs, voice states, sessions, unread state, and typing state in sync.
  • Automatic request routing and reconnect handling.

This document reflects the current implementation behavior shown in the SDK sources.


Installation

npm install admix.js

Quick Start

const {
  Client,
  ClientEvents,
  EmbedMaker,
  ActionRow,
  Button,
  ButtonVariants,
  Mentions,
} = require("admix.js");

const client = new Client({
  token: process.env.ADMIX_TOKEN,
  autoReconnect: true,
});

client.on(ClientEvents.READY, () => {
  console.log(`Logged in as ${client.currentUser?.username || "Unknown"}!`);
  console.log(`Everyone role ID for every guild is the guild ID.`);
});

client.on(ClientEvents.MESSAGE_CREATE, async (message) => {
  if (message.author?.bot) return;

  if (message.content === "!ping") {
    const embed = new EmbedMaker()
      .setTitle("Pong!")
      .setDescription(`Hello ${Mentions.user(message.authorId || message.author?._id)}.`);

    const button = new Button()
      .setLabel("Click Me")
      .setCustomId("test_btn")
      .setStyle(ButtonVariants.Primary);

    const row = new ActionRow().addComponent(button);

    await client.chat.sendMessage(message.channelId, "", {
      embeds: [embed],
      components: [row],
    });
  }
});

client.on(ClientEvents.INTERACTION_CREATE, async (interaction) => {
  if (interaction.customId === "test_btn") {
    await client.chat.replyInteraction(
      interaction.channelId,
      interaction.id,
      "You clicked it!",
      { ephemeral: true }
    );
  }
});

client.login();

Exports

const {
  Client,
  ClientEvents,
  EmbedMaker,
  ActionRow,
  Button,
  ButtonVariants,
  UIComponentTypes,
  PermissionNodes,
  OverwritesPermissions,
  ChannelFormats,
  Mentions,
} = require("admix.js");

Builders

  • EmbedMaker: chainable embed builder.
  • ActionRow: container for UI components.
  • Button: chainable button builder.

Helpers

  • Mentions: helper for formatting mention strings safely.
  • PermissionNodes: permission constant map for roles and member checks.
  • OverwritesPermissions: channel overwrite permission constant map.
  • ChannelFormats: canonical channel type constants.
  • UIComponentTypes: numeric component type map.

Constants

UIComponentTypes

const UIComponentTypes = Object.freeze({
  ACTION_ROW: 1,
  BUTTON: 2
});

These are the component type values used by the transport layer.

ChannelFormats

const ChannelFormats = Object.freeze({
  GUILD_TEXT: "GUILD_TEXT",
  GUILD_VOICE: "GUILD_VOICE",
  GUILD_CATEGORY: "GUILD_CATEGORY",
  DM: "DM",
});

Use these when creating or updating channels.

OverwritesPermissions

const OverwritesPermissions = Object.freeze({
  VIEW_CHANNEL: "VIEW_CHANNEL",
  SEND_MESSAGES: "SEND_MESSAGES",
  CONNECT: "CONNECT",
  SPEAK: "SPEAK",
});

Use these for channel permission overwrites.

PermissionNodes

PermissionNodes is the broader permission constant map used for roles and member checks. Common values include:

  • ADMINISTRATOR
  • VIEW_CHANNEL
  • MANAGE_GUILD
  • MANAGE_ROLES
  • MANAGE_CHANNELS
  • KICK_MEMBERS
  • BAN_MEMBERS
  • CHANGE_NICKNAME
  • SEND_MESSAGES
  • MANAGE_MESSAGES
  • CONNECT
  • SPEAK
  • CREATE_INVITE
  • PING_ROLES

Use PermissionNodes for role and member permission logic. Use OverwritesPermissions for channel overwrite payloads.


Mentions

Mentions is the safe helper for formatting mentions.

Example

await client.chat.sendMessage(
  channelId,
  `Welcome ${Mentions.user(userId)}!`
);

This is the recommended way to ping users in messages instead of manually building mention strings.


EmbedMaker

EmbedMaker is a chainable embed builder.

Methods

setTitle(title)

Sets the embed title.

  • Trimmed to 256 characters.
  • Empty values are ignored.

setDescription(description)

Sets the embed description.

  • Trimmed to 4096 characters.
  • Empty values are ignored.

setURL(url)

Sets the embed URL.

setColor(color)

Sets the embed color.

  • Numbers are preserved.
  • Strings are preserved as provided by the builder and normalized later by the transport.

setFooter(text, iconURL)

Sets the footer.

  • Footer text is trimmed to 2048 characters.
  • iconURL is stored as icon_url.

setImage(url)

Sets the embed image.

setThumbnail(url)

Sets the embed thumbnail.

setAuthor(name, iconURL, url)

Sets the author block.

  • Author name is trimmed to 256 characters.
  • iconURL is stored as icon_url.
  • url is stored as-is when valid.

addField(name, value, inline = false)

Adds a field.

  • Field name is trimmed to 256 characters.
  • Field value is trimmed to 1024 characters.
  • Maximum of 25 fields.
  • inline is converted to a boolean.

toJSON()

Returns a plain embed payload.

Builder limits

The transport layer also enforces embed limits:

  • Maximum 10 embeds per message.
  • Maximum 6000 total characters across an embed payload.
  • Titles, descriptions, author names, footer text, and field lengths are capped as above.

Example

const embed = new EmbedMaker()
  .setTitle("Server Update")
  .setDescription("The server is now online.")
  .setColor("#10b981")
  .setFooter("Admix Bot", "https://example.com/icon.png")
  .addField("Status", "Healthy", true)
  .addField("Latency", "32ms", true);

Example with image and author

const embed = new EmbedMaker()
  .setAuthor("Admix", "https://example.com/avatar.png", "https://example.com")
  .setImage("https://example.com/banner.png")
  .setThumbnail("https://example.com/thumb.png");

URL rules for embeds

The transport accepts:

  • http://
  • https://
  • attachment://filename.ext

For remote images, thumbnails, author icons, and footer icons, the SDK downloads the asset and rewrites it to an attachment reference when possible.


Action rows and buttons

The current component transport expects Discord-style rows and buttons.

ActionRow

  • Uses component type 1.
  • Holds up to 5 buttons.
  • Rows are normalized before send/edit operations.

Button

  • Uses component type 2.
  • Button label is trimmed to 80 characters.
  • custom_id is trimmed to 100 characters.
  • Only button components are kept inside action rows by the transport layer.

Example

const row = new ActionRow()
  .addComponent(
    new Button()
      .setLabel("Confirm")
      .setCustomId("confirm_action")
      .setStyle(ButtonVariants.Primary)
  )
  .addComponent(
    new Button()
      .setLabel("Cancel")
      .setCustomId("cancel_action")
      .setStyle(ButtonVariants.Secondary)
  );

Example with an interaction reply

await client.chat.replyInteraction(channelId, interactionId, "Done.", {
  ephemeral: true,
  components: [row],
});

Channel and permission rules

Channel types

The API supports these channel types:

  • GUILD_TEXT
  • GUILD_VOICE
  • GUILD_CATEGORY
  • DM

Important channel behavior

  • GUILD_TEXT supports topic, parentId, position, and permissionOverwrites.
  • GUILD_VOICE supports bitrate, userLimit, parentId, position, and permissionOverwrites.
  • GUILD_CATEGORY supports permissionOverwrites and position, but not topic, bitrate, or userLimit.
  • DM is not created through GuildAPI.createChannel.

Everyone role rule

In this API, the @everyone role ID is the guild ID.

That means:

client.cache.getEveryoneRoleId(guildId) === guildId

This is the invariant the library uses when resolving the default role in guilds.

Permission overwrite structure

A channel overwrite entry looks like this:

{
  id: "ROLE_OR_USER_ID",
  type: 0, // 0 = role/everyone, 1 = member
  allow: ["VIEW_CHANNEL", "SEND_MESSAGES"],
  deny: []
}

Notes

  • type: 0 is used for roles, including the everyone role.
  • type: 1 is used for a specific member.
  • allow and deny should contain values from OverwritesPermissions.
  • The API uses the guild ID as the everyone-role ID for overwrite targets.

Effective permission order

When evaluating access, use this precedence:

  1. Everyone-role overwrite
  2. Role overwrites
  3. Member overwrite

That mirrors the common server permission model used by the SDK’s cache logic.

Example: private text channel

const overwrites = [
  {
    id: guildId,
    type: 0,
    allow: [],
    deny: [OverwritesPermissions.VIEW_CHANNEL, OverwritesPermissions.SEND_MESSAGES],
  },
  {
    id: userId,
    type: 1,
    allow: [OverwritesPermissions.VIEW_CHANNEL, OverwritesPermissions.SEND_MESSAGES],
    deny: [],
  },
  {
    id: client.currentUser._id,
    type: 1,
    allow: [OverwritesPermissions.VIEW_CHANNEL, OverwritesPermissions.SEND_MESSAGES],
    deny: [],
  },
];

await client.guild.createChannel(guildId, "private-chat", {
  type: ChannelFormats.GUILD_TEXT,
  parentId: categoryId,
  permissionOverwrites: overwrites,
});

Example: private voice channel

await client.guild.createChannel(guildId, "private-voice", {
  type: ChannelFormats.GUILD_VOICE,
  permissionOverwrites: [
    {
      id: guildId,
      type: 0,
      allow: [],
      deny: [OverwritesPermissions.VIEW_CHANNEL, OverwritesPermissions.CONNECT],
    },
    {
      id: userId,
      type: 1,
      allow: [OverwritesPermissions.VIEW_CHANNEL, OverwritesPermissions.CONNECT, OverwritesPermissions.SPEAK],
      deny: [],
    },
  ],
});

Example: allow a specific role in a private category

await client.guild.createChannel(guildId, "mods", {
  type: ChannelFormats.GUILD_CATEGORY,
  permissionOverwrites: [
    {
      id: guildId,
      type: 0,
      deny: [OverwritesPermissions.VIEW_CHANNEL],
      allow: [],
    },
    {
      id: roleId,
      type: 0,
      allow: [OverwritesPermissions.VIEW_CHANNEL, OverwritesPermissions.SEND_MESSAGES],
      deny: [],
    },
  ],
});

Example: member nickname access

await client.guild.updateMember(guildId, userId, {
  nickname: "NightFox",
});

ChatAPI (client.chat)

Handles text, message, channel, DM, and interaction-related operations.

sendMessage(channelId, content?, options?)

Sends a message to a channel.

Useful for:

  • plain text
  • embeds
  • attachments
  • components
  • replies

Supported options:

  • repliedTo
  • attachments
  • embeds
  • components

Example:

await client.chat.sendMessage(channelId, "Hello world!");

With embed and buttons:

const embed = new EmbedMaker().setTitle("Hi!");
const button = new Button().setLabel("Press me").setCustomId("press_me").setStyle(ButtonVariants.Primary);
const row = new ActionRow().addComponent(button);

await client.chat.sendMessage(channelId, " ", {
  embeds: [embed],
  components: [row],
});

With a reply target:

await client.chat.sendMessage(channelId, "Thanks!", {
  repliedTo: messageId,
});

Attachments can be either:

  • a file path string
  • an object with path / filePath, filename, contentType, and optional isTemp

Example:

await client.chat.sendMessage(channelId, "Here is the file", {
  attachments: [
    "/tmp/image.png",
    {
      path: "/tmp/report.pdf",
      filename: "report.pdf",
      contentType: "application/pdf",
    },
  ],
});

Expected response shape:

{
  "_id": "112233445566778899",
  "channelId": "998877665544332211",
  "authorId": "123456789012345678",
  "content": "Hello world!",
  "attachments": [],
  "reactions": [],
  "edited": false,
  "mentions": [],
  "mentionRoles": [],
  "mentionEveryone": false,
  "pingWorked": true,
  "resolvedPings": [],
  "createdAt": "2023-10-01T12:05:00.000Z",
  "author": {
    "username": "JohnDoe",
    "displayName": "John",
    "avatar": "https://..."
  }
}

fetchMessages(channelId, options?)

Fetches message history for a channel.

Options:

  • before — message ID to fetch before
  • limit — max messages to return, up to 100

Example:

const history = await client.chat.fetchMessages(channelId, {
  before: lastMessageId,
  limit: 25,
});

Expected response shape:

{
  "messages": [
    {
      "_id": "112233445566778899",
      "channelId": "998877665544332211",
      "authorId": "123456789012345678",
      "content": "Hello world!",
      "attachments": [],
      "reactions": [],
      "edited": false,
      "mentions": [],
      "mentionRoles": [],
      "mentionEveryone": false,
      "resolvedPings": [],
      "createdAt": "2023-10-01T12:00:00.000Z",
      "author": {
        "username": "JohnDoe",
        "displayName": "John",
        "avatar": "https://..."
      },
      "repliedMessage": null
    }
  ],
  "containsFirstMessage": true,
  "lastReadMessageId": "112233445566778899"
}

editMessage(channelId, messageId, content, options?)

Edits a previously sent message.

Supported options:

  • embeds
  • components

Example:

await client.chat.editMessage(channelId, messageId, "Updated text!");

With embeds:

await client.chat.editMessage(channelId, messageId, "Updated text!", {
  embeds: [new EmbedMaker().setTitle("Edited")],
});

Expected response shape:

{
  "_id": "112233445566778899",
  "channelId": "998877665544332211",
  "authorId": "123456789012345678",
  "content": "Updated text!",
  "edited": true,
  "author": {
    "username": "JohnDoe",
    "displayName": "John",
    "avatar": "https://..."
  }
}

deleteMessage(channelId, messageId)

Deletes a message.

Example:

await client.chat.deleteMessage(channelId, messageId);

Expected response shape:

{
  "success": true,
  "message": "Message deleted successfully"
}

reactToMessage(channelId, messageId, emoji)

Adds a Unicode emoji reaction to a message.

Example:

await client.chat.reactToMessage(channelId, messageId, "👍");

Expected response shape:

{
  "success": true,
  "reactions": [
    {
      "emoji": "👍",
      "users": ["123456789012345678"]
    }
  ]
}

reportMessage(channelId, messageId, reason)

Reports a message.

Example:

await client.chat.reportMessage(channelId, messageId, "Harassment");

Expected response shape:

{
  "success": true,
  "message": "Message successfully reported."
}

triggerInteraction(channelId, messageId, customId)

Triggers a component interaction for a message.

Example:

await client.chat.triggerInteraction(channelId, messageId, "confirm_btn");

searchMentions(channelId, query?)

Searches users and roles that can be mentioned in a channel.

This is useful for mention pickers, autocompletion, and custom UI.

Example:

const result = await client.chat.searchMentions(channelId, "mod");

Expected response shape:

{
  "users": [
    {
      "_id": "123456789012345678",
      "username": "JohnDoe",
      "displayName": "John",
      "avatar": "https://...",
      "nickname": "Johnny"
    }
  ],
  "roles": [
    {
      "id": "223344556677889900",
      "name": "Admin",
      "color": "#ff0000",
      "position": 5,
      "permissions": ["ADMINISTRATOR"],
      "defaultRole": false
    }
  ],
  "includeEveryone": false
}

createInvite(channelId, options?)

Creates an invite for a channel.

Options:

  • maxAge
  • maxUses

Example:

const invite = await client.chat.createInvite(channelId, {
  maxAge: 86400,
  maxUses: 0,
});

Expected response shape:

{
  "_id": "aBcDeFgH",
  "guildId": "998877665544332211",
  "channelId": "556677889900112233",
  "inviterId": "123456789012345678",
  "maxAge": 86400,
  "maxUses": 0,
  "uses": 0,
  "createdAt": "2023-10-01T12:00:00.000Z",
  "expiresAt": "2023-10-02T12:00:00.000Z"
}

getInviteInformation(code)

Fetches info about an invite code.

Example:

const info = await client.chat.getInviteInformation("aBcDeFgH");

Expected response shape:

{
  "_id": "aBcDeFgH",
  "guildId": "998877665544332211",
  "channelId": "556677889900112233",
  "guild": {
    "name": "Cool Server",
    "icon": "https://..."
  },
  "channel": {
    "name": "general",
    "type": "GUILD_TEXT"
  },
  "inviter": {
    "username": "JohnDoe",
    "avatar": "https://..."
  }
}

sendTyping(channelId)

Triggers the typing indicator.

The helper is throttled locally to once every 3 seconds per channel.

Example:

await client.chat.sendTyping(channelId);

Expected response shape:

{
  "success": true
}

markRead(channelId, messageId)

Marks a DM channel as read up to a message.

Example:

await client.chat.markRead(dmChannelId, messageId);

Expected response shape:

{
  "success": true
}

markReadGuild(channelId)

Marks a guild channel as read.

Example:

await client.chat.markReadGuild(channelId);

Expected response shape:

{
  "success": true
}

Interactions API

deferReply(channelId, interactionId, ephemeral?)

Acknowledges an interaction and shows a loading state.

Example:

await client.chat.deferReply(channelId, interactionId, true);

Expected response shape:

{
  "_id": "NEW_MSG_ID",
  "channelId": "CHANNEL_ID",
  "isDeferring": true,
  "isEphemeral": true,
  "interactionId": "INTERACTION_ID"
}

deferUpdate(channelId, interactionId)

Acknowledges a component interaction without creating a new message.

Example:

await client.chat.deferUpdate(channelId, interactionId);

Expected response shape:

{
  "success": true
}

replyInteraction(channelId, interactionId, content, options?)

Replies directly to an interaction.

Supported options:

  • ephemeral
  • attachments
  • embeds
  • components

Example:

await client.chat.replyInteraction(
  channelId,
  interactionId,
  "Action completed!",
  { ephemeral: true }
);

Expected response shape:

{
  "_id": "NEW_MSG_ID",
  "content": "Action completed!",
  "isEphemeral": true,
  "ephemeralFor": "USER_ID"
}

GuildAPI (client.guild)

Handles guild, channel, role, and member management.

fetchGuild(guildId)

Fetches the full guild payload.

Expected response shape:

{
  "_id": "998877665544332211",
  "name": "Awesome Server",
  "ownerId": "123456789012345678",
  "icon": "https://...",
  "backgroundImage": null,
  "roles": [],
  "my_member_info": {
    "nickname": null,
    "roles": [],
    "joinedAt": "2023-01-01T12:00:00.000Z"
  },
  "permissions": [
    "VIEW_CHANNEL",
    "SEND_MESSAGES"
  ],
  "channels": [
    {
      "_id": "556677889900112233",
      "name": "general",
      "type": "GUILD_TEXT"
    }
  ]
}

updateGuild(guildId, options?)

Updates guild metadata.

Supports:

  • name
  • description
  • customInvite
  • discoveryEnabled
  • icon
  • clearIcon
  • backgroundImage
  • clearBackgroundImage

Example:

await client.guild.updateGuild(guildId, {
  name: "Updated Server",
  discoveryEnabled: true,
});

Image uploads are sent as multipart when icon or backgroundImage is provided.

deleteGuild(guildId)

Deletes a guild. Owner-only behavior is expected.

Example:

await client.guild.deleteGuild(guildId);

Expected response shape:

{
  "success": true,
  "message": "Guild deleted successfully"
}

createChannel(guildId, name, options?)

Creates a channel in a guild.

Supported options:

  • type
  • parentId
  • topic
  • position
  • bitrate
  • userLimit
  • permissionOverwrites

Behavior:

  • Text channels do not send bitrate or userLimit.
  • Voice channels validate bitrate and userLimit.
  • Categories do not send topic, bitrate, or userLimit.
  • Overwrites are normalized to valid structures.
  • The everyone-role overwrite target uses the guild ID.

Example: category with private overwrites

const overwrites = [
  {
    id: guildId,
    type: 0,
    allow: [],
    deny: [OverwritesPermissions.VIEW_CHANNEL],
  },
  {
    id: userId,
    type: 1,
    allow: [OverwritesPermissions.VIEW_CHANNEL],
    deny: [],
  },
];

const category = await client.guild.createChannel(guildId, "test category", {
  type: ChannelFormats.GUILD_CATEGORY,
  position: 0,
  permissionOverwrites: overwrites,
});

Example: text channel under a category

const channel = await client.guild.createChannel(guildId, "test channel", {
  type: ChannelFormats.GUILD_TEXT,
  parentId: category._id,
  topic: "Private discussion",
  permissionOverwrites: overwrites,
});

Example: voice channel

await client.guild.createChannel(guildId, "voice room", {
  type: ChannelFormats.GUILD_VOICE,
  bitrate: 64000,
  userLimit: 10,
  permissionOverwrites: [
    {
      id: guildId,
      type: 0,
      allow: [],
      deny: [OverwritesPermissions.VIEW_CHANNEL, OverwritesPermissions.CONNECT],
    },
  ],
});

Expected response shape:

{
  "_id": "112233445566778899",
  "guildId": "998877665544332211",
  "type": "GUILD_TEXT",
  "name": "new-channel",
  "parentId": null,
  "position": 5,
  "permissionOverwrites": [],
  "topic": ""
}

updateChannel(channelId, options?)

Updates a channel.

Supported options:

  • name
  • topic
  • position
  • parentId
  • permissionOverwrites
  • bitrate
  • userLimit

Example:

await client.guild.updateChannel(channelId, {
  name: "updated-channel",
  topic: "New topic here",
  permissionOverwrites: [],
});

Expected response shape:

{
  "_id": "556677889900112233",
  "guildId": "998877665544332211",
  "type": "GUILD_TEXT",
  "name": "updated-channel",
  "topic": "New topic here",
  "position": 1,
  "parentId": null,
  "permissionOverwrites": []
}

deleteChannel(channelId)

Deletes a channel.

Example:

await client.guild.deleteChannel(channelId);

Expected response shape:

{
  "success": true
}

bulkUpdateChannels(guildId, channels)

Bulk reorders or mass-edits guild channels.

Example:

await client.guild.bulkUpdateChannels(guildId, [
  { _id: channelA, position: 0 },
  { _id: channelB, position: 1 },
]);

Expected response shape:

{
  "success": true,
  "updated": 3
}

createRole(guildId, options?)

Creates a role.

Options:

  • name
  • color
  • permissions

Example:

const role = await client.guild.createRole(guildId, {
  name: "Moderator",
  color: "#ff0000",
  permissions: ["KICK_MEMBERS", "BAN_MEMBERS"],
});

Expected response shape:

{
  "id": "778899001122334455",
  "name": "Moderator",
  "color": "#3498db",
  "position": 1,
  "permissions": [
    "KICK_MEMBERS",
    "BAN_MEMBERS"
  ],
  "defaultRole": false
}

updateRole(guildId, roleId, options?)

Updates a role.

Example:

await client.guild.updateRole(guildId, roleId, {
  name: "Super Moderator",
  color: "#e74c3c",
  permissions: ["ADMINISTRATOR"],
  position: 2,
});

Expected response shape:

{
  "id": "778899001122334455",
  "name": "Super Moderator",
  "color": "#e74c3c",
  "position": 2,
  "permissions": ["ADMINISTRATOR"],
  "defaultRole": false
}

reorderRoles(guildId, roles)

Changes role ordering.

Example:

await client.guild.reorderRoles(guildId, [
  { id: roleA, position: 1 },
  { id: roleB, position: 2 },
]);

Expected response shape:

{
  "success": true
}

deleteRole(guildId, roleId)

Deletes a role.

Example:

await client.guild.deleteRole(guildId, roleId);

Expected response shape:

{
  "success": true
}

updateMember(guildId, userId, options?)

Updates nickname or roles for a member.

Options:

  • nickname
  • roles

Example:

await client.guild.updateMember(guildId, userId, {
  nickname: "Cool Nickname",
  roles: [roleId],
});

kickMember(guildId, userId)

Kicks a member.

Expected response shape:

{
  "success": true,
  "message": "User kicked"
}

banMember(guildId, userId, reason?)

Bans a member.

Expected response shape:

{
  "success": true,
  "message": "User banned"
}

unbanMember(guildId, userId)

Unbans a member.

Expected response shape:

{
  "success": true
}

fetchBans(guildId)

Fetches ban records.

Expected response shape:

[
  {
    "_id": "abc123def456",
    "guildId": "998877665544332211",
    "userId": "112233445566778899",
    "reason": "Spamming",
    "user": {
      "username": "Spammer",
      "avatar": "https://..."
    }
  }
]

searchMembers(guildId, query, page?)

Searches members.

Expected response shape:

{
  "members": [
    {
      "_id": "...",
      "guildId": "998877665544332211",
      "userId": "123456789012345678",
      "nickname": "Johnny",
      "roles": [],
      "user": {
        "_id": "123456789012345678",
        "username": "JohnDoe",
        "displayName": "John",
        "avatar": "https://..."
      }
    }
  ],
  "hasMore": false
}

updateAutoRole(guildId, roleId)

Sets the default role for new members.

Example:

await client.guild.updateAutoRole(guildId, roleId);

Expected response shape:

{
  "success": true,
  "autoRoleId": "778899001122334455"
}

fetchDiscovery(page?, query?)

Fetches discovery results.

Expected response shape:

{
  "guilds": [
    {
      "_id": "998877665544332211",
      "name": "Public Community",
      "description": "A public discoverable community",
      "icon": "https://...",
      "memberCount": 1500
    }
  ],
  "page": 1,
  "totalPages": 5
}

leaveGuild(guildId)

Leaves a guild.

Expected response shape:

{
  "success": true
}

CacheManager

The cache keeps your bot state in sync with websocket updates. It tracks:

  • current user
  • guilds
  • members
  • roles
  • channels
  • messages
  • DMs
  • voice states
  • typing indicators
  • unread state
  • sessions
  • todo statistics

Everyone-role helpers

These are the most important helpers for channel overwrites and permission logic.

getEveryoneRole(guildId)

Returns the everyone role object for the guild.

getEveryoneRoleId(guildId)

Returns the guild ID as the everyone-role ID.

Example:

const everyoneId = client.cache.getEveryoneRoleId(guildId);

isEveryoneRole(guildId, roleId)

Returns true if the role ID is the guild ID.

Example:

if (client.cache.isEveryoneRole(guildId, roleId)) {
  console.log("That is the everyone role.");
}

Guild and role helpers

getGuild(guildId)

Returns a cached guild or null.

getGuilds()

Returns all cached guilds.

getGuildRoles(guildId)

Returns all roles for a guild.

getRoleIndex(guildId)

Returns a Map of role ID to role object.

getRole(guildId, roleId)

Returns a single role.

getRoleByName(guildId, roleName)

Finds a role by name, case-insensitive.

Channel helpers

getChannel(channelId)

Returns a DM channel or guild channel from cache.

getGuildChannel(guildId, channelId)

Returns a channel within a specific guild.

getGuildChannelByName(guildId, channelName, type?, parentId?)

Finds a guild channel by name, type, and optional parent.

getTextChannels(guildId, parentId?)

Returns text channels, optionally filtered by parent category.

getCategories(guildId)

Returns category channels in a guild.

User and member helpers

getUser(userId)

Returns a cached user.

getMember(userId)

Returns a member from the global member cache.

getGuildMember(guildId, userId)

Returns a member object augmented with:

  • permissions
  • highestRolePosition

getGuildMemberRoleIds(guildId, userId)

Returns only the role IDs held by a member.

getGuildMemberPermissions(guildId, userId)

Returns the member’s effective permissions.

hasGuildPermission(guildId, userId, permission)

Checks whether a member has a specific permission.

calculateMemberPermissions(guild, member)

Computes effective permissions from:

  • everyone role
  • member roles
  • administrator shortcut
  • owner shortcut

calculateHighestRolePosition(guild, member)

Returns the highest role position for a member.

hasPermission(guildId, userId, permission)

Convenience permission check.

canManageRole(guildId, userId, roleId)

Checks whether a user can manage a target role.

getManageableRoles(guildId, userId)

Returns roles the member can manage.

getMemberRoleObjects(guildId, userId)

Returns full role objects for the member’s roles.

Message and DM helpers

getDM(channelId)

Returns a cached DM channel.

getMessage(messageId)

Returns a cached message.

upsertMessage(message)

Adds or updates a message in cache.

updateMessage(message)

Updates an existing cached message.

deleteMessage(channelId, messageId)

Removes a message from cache and updates unread state.

Read state and typing helpers

setUnread(channelId, count, lastUnreadMessageId?, unreadStartMessageId?)

Updates unread counters.

ackChannel(channelId)

Marks a channel read.

handleTypingStart(data)

Adds a user to the typing cache and removes them after the timeout.

updateInteractionDefer(data)

Marks UI components as deferred in cached messages.

Session and user-sync helpers

setCurrentUser(user)

Sets the current user in cache.

indexUser(user)

Normalizes and caches a user.

indexUsersFromGuild(guild)

Indexes users from a guild payload and updates cached members and channel authors.

updateUserEverywhere(userId, changes)

Updates a user everywhere in cache:

  • guild members
  • messages
  • DMs
  • notifications
  • friends
  • author refs

syncMemberCacheFromGuild(guild)

Syncs member cache from a guild payload.

Guild mutation helpers

updateGuildRolesAndMemberRoles(guild, roles)

Normalizes and applies role updates to a guild and its members.

updateServerSettings(data)

Updates a guild in cache when server settings change.

updateSettings(data)

Updates current user settings in cache.

setAdminAccess(value)

Sets the global admin access flag.

hydrateReady(data)

Hydrates the cache from a ready payload.

snapshot()

Returns a full snapshot of the cache state.

reset()

Clears the cache.


Websocket events

These are the events handled by the SDK and exposed through ClientEvents.

Connection and core

  • READY
  • TOKEN_RESET
  • HEARTBEAT_ACK
  • NEW_SESSION_CONNECTED
  • SESSION_REMOVED
  • TODO_STATS_UPDATE
  • ADMIN_ACCESS_UPDATE

Messaging and channels

  • MESSAGE_CREATE
  • MESSAGE_UPDATE
  • MESSAGE_DELETE
  • MESSAGE_REACTION_ADD
  • MESSAGE_REACTION_REMOVE
  • TYPING_START
  • UNREAD_UPDATE
  • MESSAGE_ACK

Guild lifecycle and settings

  • GUILD_CREATE
  • GUILD_UPDATE
  • GUILD_DELETE
  • SERVER_SETTINGS_UPDATE
  • UPDATED_SERVER_LIST_POSITION
  • DISCOVERY_UPDATE

Guild channels

  • CHANNEL_CREATE
  • CHANNEL_UPDATE
  • CHANNEL_DELETE

Guild roles

  • GUILD_ROLE_CREATE
  • GUILD_ROLE_UPDATE
  • GUILD_ROLE_DELETE

Guild members

  • GUILD_MEMBERS_CHUNK
  • GUILD_MEMBER_ADD
  • GUILD_MEMBER_UPDATE
  • GUILD_MEMBER_REMOVE
  • GUILD_BAN_ADD

Voice

  • VOICE_STATE_UPDATE
  • VOICE_SERVER_UPDATE

Notes

  • Message events can include guildId when the message belongs to a server.
  • Role updates should cascade through cached members automatically.
  • @everyone is resolved by guild ID.

Practical examples

Create a private category and text channel

const everyoneId = client.cache.getEveryoneRoleId(guildId);

const overwrites = [
  {
    id: everyoneId,
    type: 0,
    allow: [],
    deny: [OverwritesPermissions.VIEW_CHANNEL, OverwritesPermissions.SEND_MESSAGES],
  },
  {
    id: userId,
    type: 1,
    allow: [OverwritesPermissions.VIEW_CHANNEL, OverwritesPermissions.SEND_MESSAGES],
    deny: [],
  },
  {
    id: client.currentUser._id,
    type: 1,
    allow: [OverwritesPermissions.VIEW_CHANNEL, OverwritesPermissions.SEND_MESSAGES],
    deny: [],
  },
];

const category = await client.guild.createChannel(guildId, "staff", {
  type: ChannelFormats.GUILD_CATEGORY,
  permissionOverwrites: overwrites,
});

await client.guild.createChannel(guildId, "staff-chat", {
  type: ChannelFormats.GUILD_TEXT,
  parentId: category._id,
  topic: "Private staff discussion",
  permissionOverwrites: overwrites,
});

Mention a user in a message

await client.chat.sendMessage(
  channelId,
  `Hello ${Mentions.user(userId)}!`
);

Check whether a member has permission

const perms = client.cache.getGuildMemberPermissions(guildId, userId);

if (perms.includes(PermissionNodes.MANAGE_CHANNELS)) {
  console.log("User can manage channels.");
}

Resolve the everyone role directly

const everyoneRole = client.cache.getEveryoneRole(guildId);
const everyoneRoleId = client.cache.getEveryoneRoleId(guildId);

console.log(everyoneRoleId === guildId); // true

Build a staff-only voice channel

await client.guild.createChannel(guildId, "mods-voice", {
  type: ChannelFormats.GUILD_VOICE,
  bitrate: 64000,
  userLimit: 10,
  permissionOverwrites: [
    {
      id: guildId,
      type: 0,
      deny: [OverwritesPermissions.VIEW_CHANNEL, OverwritesPermissions.CONNECT],
      allow: [],
    },
    {
      id: moderatorRoleId,
      type: 0,
      allow: [OverwritesPermissions.VIEW_CHANNEL, OverwritesPermissions.CONNECT, OverwritesPermissions.SPEAK],
      deny: [],
    },
  ],
});

Reply to a button click

client.on(ClientEvents.INTERACTION_CREATE, async (interaction) => {
  if (interaction.customId === "confirm_action") {
    await client.chat.replyInteraction(
      interaction.channelId,
      interaction.id,
      "Confirmed.",
      { ephemeral: true }
    );
  }
});

Create a richer embed message

const embed = new EmbedMaker()
  .setTitle("Weekly Update")
  .setDescription("Here is what changed this week.")
  .setColor("#5865F2")
  .setFooter("Admix", "https://example.com/icon.png")
  .addField("New", "Added private channel support", false)
  .addField("Fixed", "Improved voice state sync", false);

await client.chat.sendMessage(channelId, " ", {
  embeds: [embed],
});

Add buttons to a message

const row = new ActionRow()
  .addComponent(
    new Button()
      .setLabel("Open")
      .setCustomId("open_panel")
      .setStyle(ButtonVariants.Primary)
  )
  .addComponent(
    new Button()
      .setLabel("Dismiss")
      .setCustomId("dismiss_panel")
      .setStyle(ButtonVariants.Secondary)
  );

await client.chat.sendMessage(channelId, "Choose an option:", {
  components: [row],
});

Notes for developers

  • The library sanitizes channel names before sending create/update requests.
  • Invalid create-channel fields are stripped by the client when the channel type does not support them.
  • permissionOverwrites should always be normalized before sending to the API.
  • When building private channels, use the guild ID as the everyone-role target.
  • Prefer Mentions.user(userId) for user mentions instead of manual formatting.
  • Use the cache helpers instead of walking raw arrays whenever possible.
  • For voice access, combine VIEW_CHANNEL, CONNECT, and SPEAK as needed.
  • For text access, combine VIEW_CHANNEL and SEND_MESSAGES as needed.
  • For member-scoped access, use type: 1.
  • For role-scoped access, use type: 0.

Developed for Admix. Licensed under the MIT License.