Kharat Bot Docs

KAL embeds & components

SEND EMBED fields, action rows, buttons, select menus and modals — the exact syntax and every Discord-side limit.

SEND EMBED#

kal
KAL VERSION 2.0;
AUTOMATION news_embed {

    CONFIG {
        target: CHANNEL [
            label: "News channel",
            description: "Where news is posted",
            required: true
        ];
    }

    WHEN COMMAND news {
        SEND EMBED {
            TITLE "Server news";
            DESCRIPTION "Fresh updates from the staff team.";
            COLOR "#6C63FF";
            AUTHOR "Kharat" URL "https://example.com";
            FOOTER "Kharat Bot";
            IMAGE "https://example.com/banner.png";
            TIMESTAMP;
            FIELD "Highlights" VALUE "Three new modules shipped" INLINE;
        } TO config.target;
    }
}
Field keyValue
TITLEAny expression
DESCRIPTIONAny expression
COLORHex string such as "#6C63FF"
AUTHOR <name> [ICON <url>] [URL <url>]Author line
FOOTER <text> [ICON <url>]Footer line
THUMBNAIL <url> / IMAGE <url>Images
URL <url>Embed link
TIMESTAMP [epoch]Bare = now; number = epoch seconds/ms
FIELD "<name>" VALUE <expr> [INLINE]Up to 25 fields; values may be dynamic

Embeds can carry components with a WITH { ACTION_ROW … } clause and target a channel with TO <channel>.

Buttons#

Two ways to build the same thing — a statement grammar and constructor functions.

Statement form:

kal
KAL VERSION 2.0;
AUTOMATION confirm_panel {

    WHEN COMMAND confirm {
        SEND MESSAGE "Please confirm:" WITH {
            ACTION_ROW {
                BUTTON yes_btn WITH "Confirm" STYLE success;
                BUTTON no_btn WITH "Cancel" STYLE secondary;
            }
        };
    }
}

Constructor form (useful when rows are built dynamically):

kal
KAL VERSION 2.0;
AUTOMATION dynamic_panel {

    WHEN COMMAND panel {
        DECLARE yes = UI_BUTTON("yes_btn", "Confirm", "success", false);
        DECLARE no = UI_BUTTON("no_btn", "Cancel", "secondary", false);
        DECLARE row = UI_ACTION_ROW([yes, no]);
        SEND MESSAGE "Please confirm:" WITH [row];
    }
}

Button styles: primary, secondary, success, danger, link (link buttons require a URL). UI_BUTTON(id, label, style, disabled[, url]).

Select menus#

kal
KAL VERSION 2.0;
AUTOMATION team_picker {

    WHEN COMMAND pick_team {
        SEND MESSAGE "Pick a team:" WITH {
            ACTION_ROW {
                SELECT STRING MENU team_pick WITH "Choose a team" MIN 1 MAX 1 {
                    OPTION "Red" VALUE "red" DESCRIPTION "Team red" DEFAULT;
                    OPTION "Blue" VALUE "blue" DESCRIPTION "Team blue";
                };
            }
        };
    }
}
  • Menu types: STRING, USER, ROLE, CHANNEL, MENTIONABLE (non-string menus take Discord's options — do not add OPTION blocks).
  • MIN/MAX bound how many options may be chosen (0–25).
  • Dynamic options: SELECT STRING MENU id WITH "…" OPTIONS FROM <array>; where the array contains UI_OPTION(...) maps.
  • A select menu must be alone in its row.
  • UI_OPTION(label, value, description, default), UI_SELECT_MENU(id, options, placeholder, min, max).

Handling the clicks#

Buttons and menus are answered by WHEN INTERACTION <custom_id> blocks — see Triggers. Acknowledge with DEFER INTERACTION when work takes a moment, then FOLLOWUP:

kal
KAL VERSION 2.0;
AUTOMATION verify_handler {

    WHEN INTERACTION yes_btn {
        DEFER INTERACTION EPHEMERAL;
        FOLLOWUP "Confirmed!" EPHEMERAL;
    }
}

Modals#

A MODAL statement (usually inside an interaction handler) pops a form; the submission arrives as another interaction.

kal
KAL VERSION 2.0;
AUTOMATION feedback_form {

    WHEN INTERACTION open_form {
        MODAL feedback_modal WITH "Send feedback" {
            FIELD feedback_topic WITH "Topic" STYLE SHORT REQUIRED MIN_LENGTH 3 MAX_LENGTH 100;
            FIELD feedback_details WITH "Details" STYLE PARAGRAPH REQUIRED;
        };
    }
}

Modal field styles: SHORT (one line) and PARAGRAPH (multi-line). Keys per field: STYLE, REQUIRED, MIN_LENGTH, MAX_LENGTH, PLACEHOLDER, DEFAULT.