KAL embeds & components
SEND EMBED fields, action rows, buttons, select menus and modals — the exact syntax and every Discord-side limit.
SEND EMBED#
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 key | Value |
|---|---|
TITLE | Any expression |
DESCRIPTION | Any expression |
COLOR | Hex 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 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 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 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 addOPTIONblocks). MIN/MAXbound how many options may be chosen (0–25).- Dynamic options:
SELECT STRING MENU id WITH "…" OPTIONS FROM <array>;where the array containsUI_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 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 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.