> For the complete documentation index, see [llms.txt](https://docs.drakodevelopment.net/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.drakodevelopment.net/addon-system/premium-addons/prefix-commands.md).

# Prefix Commands

## Key Features

* **Prefix Commands** → Run any slash command with a text prefix (e.g. `^ban @user`)
* **YAML Mappings** → Each command has a simple `.yml` file that maps aliases to the slash command
* **Argument Parsing** → Supports users, channels, roles, numbers, booleans, and rest-of-message text
* **Permission Enforcement** → Respects `default_member_permissions`, per-mapping role locks, and each command's own internal checks
* **Per-User Cooldowns** → Prevent command spam with configurable cooldown timers
* **Components V2 Support** → Automatically patches rich message replies to work through prefix
* **Auto-Generated Mappings** → Includes a tool to scan your commands folder and generate all YAML mappings at once
* **Hot Reload** → Clears the command cache on load so you always get fresh command code
* **Clean Unload** → Properly removes its listener and clears state when disabled

## Configuration

Edit `config.yml` inside the `addons/PrefixBridge` folder.

```yaml
# The character(s) users type before a command, e.g. ^ban
PREFIX: "^"

# Reply to the user's message, or just send in the channel
REPLY_TO_INVOKER: true

# Delete the user's message after running the command
DELETE_INVOKING: false

# Tell the user when they type a prefix command that doesn't exist
UNKNOWN_COMMAND_REPLY: false

# Per-user cooldown between uses of the same command (in seconds)
COOLDOWN_SECONDS: 2

# Shown when someone tries a command they can't use
NO_PERMISSION_MESSAGE: "🔒 You don't have permission to use that command."

# Shown when a command throws an unexpected error
ERROR_MESSAGE: "Something went wrong running that command."
```

## Command Mappings

Each command has a YAML file in `addons/PrefixBridge/commands/`. A mapping tells the bridge which slash command to run, what aliases to listen for, and how to parse arguments.

### Basic Command (no subcommands)

```yaml
ENABLED: true
PATH: commands/Fun/8ball.js
NAMES:
  - 8ball
ARGS:
  - NAME: question
    TYPE: string
    REST: true
```

### Command with Subcommands

```yaml
ENABLED: true
PATH: commands/Moderation/moderation.js

SUBCOMMANDS:
  ban:
    NAMES: ["ban", "b"]
    ARGS:
      - USER_OR_ID:
          USER_OPTION: "user"
          ID_OPTION: "user_id"
        OPTIONAL: false
      - NAME: "reason"
        TYPE: "string"
        REST: true
        OPTIONAL: true

  kick:
    NAMES: ["kick", "k"]
    ARGS:
      - NAME: "user"
        TYPE: "user"
      - NAME: "reason"
        TYPE: "string"
        REST: true
```

### Mapping Options

| Option                 | Description                                                               |
| ---------------------- | ------------------------------------------------------------------------- |
| `ENABLED`              | Set to `false` to disable this mapping without deleting it                |
| `PATH`                 | Relative path to the slash command file (from bot root)                   |
| `NAMES`                | List of prefix aliases for the command                                    |
| `ARGS`                 | Argument definitions (see below)                                          |
| `SUBCOMMANDS`          | Map of subcommand definitions, each with their own `NAMES` and `ARGS`     |
| `REQUIRED_ROLES`       | Role IDs that can use this command (on top of existing permission checks) |
| `REQUIRED_PERMISSIONS` | Discord permission flags required to use this command                     |

### Subcommand Options

| Option                 | Description                                                                 |
| ---------------------- | --------------------------------------------------------------------------- |
| `NAMES`                | Aliases for the subcommand (e.g. `["ban", "b"]`)                            |
| `SUBCOMMAND`           | The actual subcommand name passed to the handler (defaults to the YAML key) |
| `GROUP`                | Subcommand group name, if the slash command uses groups                     |
| `ARGS`                 | Argument definitions for this subcommand                                    |
| `REQUIRED_ROLES`       | Override the top-level `REQUIRED_ROLES` for this subcommand                 |
| `REQUIRED_PERMISSIONS` | Override the top-level `REQUIRED_PERMISSIONS` for this subcommand           |

## Argument Types

| Type               | Description           | Example Input                      |
| ------------------ | --------------------- | ---------------------------------- |
| `string`           | Plain text            | `hello world`                      |
| `integer` / `int`  | Whole number          | `42`                               |
| `number`           | Decimal number        | `3.14`                             |
| `boolean` / `bool` | True or false         | `true`, `yes`, `1`, `on`           |
| `user`             | User mention or ID    | `@User` or `123456789012345678`    |
| `channel`          | Channel mention or ID | `#general` or `123456789012345678` |
| `role`             | Role mention or ID    | `@Admin` or `123456789012345678`   |

### Special Argument Options

| Option           | Description                                                                      |
| ---------------- | -------------------------------------------------------------------------------- |
| `REST: true`     | Captures all remaining text (must be the last argument)                          |
| `OPTIONAL: true` | Argument can be skipped                                                          |
| `USER_OR_ID`     | Accepts either a user mention or a raw ID and maps to two different option names |

## Permission System

Permissions are checked in this order:

1. **Administrators** always pass
2. **`REQUIRED_ROLES`** on the mapping — if set, user must have one of these roles
3. **`REQUIRED_PERMISSIONS`** on the mapping — if set, user must have these Discord permissions
4. **Command-level checks** — each command's own permission logic still runs inside `execute()`

{% hint style="info" %}
**Note:** Discord's per-channel and per-role slash command overrides (Server Settings → Integrations) are not enforced for prefix commands. If you rely on those, add `REQUIRED_ROLES` to the mapping or disable that mapping.
{% endhint %}

## Generating Mappings

The addon includes a tool to auto-generate YAML mappings from your existing slash commands.

```bash
node addons/PrefixBridge/tools/generate-mappings.js
```

| Flag              | Description                                      |
| ----------------- | ------------------------------------------------ |
| `--force`         | Overwrite existing mapping files                 |
| `--commands=path` | Custom commands directory (relative to bot root) |

The tool scans every `.js` file in your commands folder, reads its `SlashCommandBuilder` data, and writes a `.yml` mapping with correct argument types and subcommand structure.

After generating, review the files and tweak aliases as needed.

## Included Mappings

The addon ships with mappings for all built-in commands:

| Category       | Commands                                                                                                                                                                                                  |
| -------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Fun**        | 2048, 8ball, advice, ascii, compliment, connectfour, darkjoke, fact, fliptext, guess, hangman, hug, image, kill, kiss, lennyface, meme, pickupline, quote, rizz, roast, rps, say, slap, tictactoe, wordle |
| **Economy**    | balance, beg, booster, crime, daily, deposit, economy, games, heist, inventory, lottery, pets, prestige, rob, store, transfer, use, withdraw, work                                                        |
| **Music**      | music, play                                                                                                                                                                                               |
| **General**    | botavatar, botinfo, giveaway, help, inviter, invites, leaderboard, level, rank, reminder, serverinfo, snipe, suggestion, user                                                                             |
| **Moderation** | antihoist, moderation, modtools, poll, removerole, role                                                                                                                                                   |
| **Utility**    | autoreact, autoresponse, backup, botactivity, channelstats, embed, steal, tickets, translate, update                                                                                                      |

## How It Works

1. User sends a message starting with the prefix (e.g. `^ban @user spamming`)
2. The bridge looks up the alias in its registry
3. Permissions are checked (cooldown → role/permission → command-level)
4. Arguments are parsed according to the mapping's `ARGS` spec
5. A fake interaction object is created that mimics a real slash command interaction
6. The original command's `execute()` function is called with the fake interaction
7. Replies, edits, follow-ups, and deletions all route back to the channel

## Limitations

* **Ephemeral messages** — There's no way to send ephemeral messages outside of slash commands. Permission errors and other "ephemeral" replies will be visible in the channel.
* **Integration overrides** — Discord's per-channel/role slash command restrictions from Server Settings → Integrations are not enforced. Use `REQUIRED_ROLES` in mappings instead.

## Troubleshooting

<table><thead><tr><th>Problem</th><th width="452">Solution</th></tr></thead><tbody><tr><td>Command not found</td><td>Check that the mapping's <code>ENABLED</code> is <code>true</code> and the alias is listed in <code>NAMES</code></td></tr><tr><td>Wrong arguments</td><td>Review the <code>ARGS</code> order in the mapping — it must match what the command expects</td></tr><tr><td>Permission denied</td><td>Check <code>REQUIRED_ROLES</code> and <code>REQUIRED_PERMISSIONS</code></td></tr><tr><td>Command errors on run</td><td>The slash command itself may need a real interaction — check if it uses modals or components</td></tr><tr><td>Mapping not loading</td><td>Check the console for <code>[PrefixBridge]</code> errors — usually a bad <code>PATH</code> or missing command file</td></tr><tr><td>Stale command behavior</td><td>Restart the bot — the bridge clears the command cache on startup</td></tr></tbody></table>

## Support

If you run into issues:

* Check the console for `[PrefixBridge]` log messages
* Verify your `config.yml` formatting
* Make sure command files exist at the paths referenced in your mappings
* Re-run `generate-mappings.js --force` after adding or renaming commands
