Skip to content

Messages and embeds

Declare messages to send a validated embed to the currently active channel. Add ui to obtain explicit input and display errors.

This api-example registers a composer action. Test validation and cancellation with a mock API; clicking Send in a real client creates a real message.

cleanup.push(
await api.ui.registerAttachmentAction(
{ id: "send-embed", label: "Compose embed" },
async () => {
const values = await api.ui.openDialog(
{
title: "Send an embed",
description: "Sends to the channel currently open in Fluxer.",
submitLabel: "Send",
sections: [
{
title: "Content",
controls: [
{
key: "description",
label: "Description",
kind: "textarea",
maxLength: 4096,
},
],
},
],
},
(values) =>
typeof values.description === "string" && values.description.trim()
? undefined
: "Enter a description",
);
if (!values || typeof values.description !== "string") return;
try {
await api.messages.sendEmbed({ description: values.description });
} catch {
await api.ui.notify(
"Could not send the embed. Check the active channel and try again.",
);
}
},
),
);

Do not send from the validator: validation may run repeatedly, and cancellation must not send anything. Recheck instance lifetime if your callback performs additional asynchronous work.

EmbedDraft supports title, url, description, numeric color, author, thumbnail, image, footer, timestamp, and up to 25 fields. Each field has name, value, and optional inline. Host validation remains authoritative.

The plugin cannot choose arbitrary channel IDs through this API. Authentication and origin handling remain in core, and credentials never enter the sandbox.

Self Embeds is the complete bundled example. Automated acceptance must use mocks or controlled fixtures and must not send to production channels.