Helpful builders for various Discord related things.
This module is specifically built to be compatible with Oceanic.
Get started by using one of our main classes, ComponentBuilder
or EmbedBuilder
.
// const { ComponentBuilder, (...) } = require("@oceanicjs/builders");
import {
ComponentBuilder,
ButtonColors,
Button,
SelectMenu,
TextInput,
} from "@oceanicjs/builders";
import {
ButtonStyles,
TextInputStyles,
MessageActionRow,
ModalActionRow,
ComponentTypes,
ChannelTypes
} from "oceanic.js";
// undefined can be used to skip uneeded parameters - don't use null!
const builder = new ComponentBuilder();
// add an interaction button (styles 1-4)
// style, customID, label, emoji, disabled
builder.addInteractionButton(ButtonStyles.PRIMARY, "some-custom-id", "My Button Label", { id: null, name: "🐾" }, false);
/*
we have a ButtonColors export - List:
PRIMARY = BLURPLE
SECONDARY = GRAY
SUCCESS = GREEN
DANGER = RED
LINK = URL
*/
// add a url button (style 5)
builder.addURLButton({
disabled: false,
emoji: { id: "681748079778463796", name: "paws8", animated: false },
label: "Click Here",
url: "https://google.com"
});
// for emojis, we have a helper to convert full emoji strings, or code points into a partial emoji (this method is static)
// emoji, type (default/custom)
ComponentBuilder.emojiToPartial("🐾", "default") // { id: null, name: "🐾", animated: false }
ComponentBuilder.emojiToPartial("<:paws8:681748079778463796>", "custom") // { id: "681748079778463796", name: "paws8", animated: false }
ComponentBuilder.emojiToPartial("<a:owoanim:768551122066472990>", "custom") // { id: "768551122066472990", name: "owoanim", animated: true }
// if the current row has a component in it already, this method will automatically create a new row and add the select menu in that row, the create another row for you to continue using in other methods
// add a select menu
builder.addSelectMenu({
channelTypes: [ChannelTypes.GUILD_TEXT, ChannelTypes.GUILD_ANNOUNCEMENT],
customID: "some-custom-id",
disabled: false,
maxValues: 3,
minValues: 1,
options: [],
placeholder: "Some Placeholder Here",
type: ComponentTypes.CHANNEL_SELECT
});
// see https://discord.com/developers/docs/interactions/message-components#select-menu-object-select-option-structure for options structure
// add a text input
builder.addTextInput({
customID: "some-custom-id",
label: "Some Label Here",
maxLength: 100,
minValue: 20,
placeholder: "Some Placeholder Here",
required: true,
style: TextInputStyles.SHORT,
value: "Initial Value"
});
// currently SHORT & PARAGRAPH exist
// remove all currently present empty rows (this is already done while converting to JSON)
builder.removeEmptyRows();
// convert all of the added content into JSON, ready to be used as a components property in a message/modal
builder.toJSON();
// most things have a Raw variant, which returns json that can be sent directly to Discord
builder.toJSONRaw();
// a few other things, if you want to add a new row at any time, just call..
builder.addRow();
// this also accepts an array of components, if you want to add them while creating the row
// if you want to construct the components yourself, you can add them via these methods
builder.addComponent(new Button(ButtonColors.RED, "some-custom-id"));
// add in bulk (these will be passed through addComponent one at a time, in order)
builder.addComponents([
new Button(ButtonStyles.LINK, "https://google.com"),
new SelectMenu("some-custom-id"),
new TextInput(TextInputStyles.PARAGRAPH, "Some Label", "some-custom-id")
]);
// these classes all come with their own methods to change things about them, please refer to the code for a list of them. They are all well documented.
// if you want to limit the maxium amount of items we'll put in a row to a different number than 5, you can provide that in the ComponentBuilder constructor, or call setRowLimit
const builder3 = new ComponentBuilder(3);
builder3.setRowMax(2);
// for those of you out there wanting to break things - we don't validate numbers, break it all you want
// for typescript compatibility, you can cast to either MessageActionRow or ModalActionRow. toJSON accepts a generic parameter for this.
builder.toJSON<MessageActionRow>();
builder.toJSON<ModalActionRow>();
// you can also specify it when creating the builder.
const componentBuilder = new ComponentBuilder<MessageActionRow>();
const modalBuilder = new ComponentBuilder<ModalActionRow>();
// const { EmbedBuilder } = require("@oceanicjs/builders");
import { EmbedBuilder } from "@oceanicjs/builders";
// undefined can be used to skip uneeded parameters - don't use null!
const embed = new EmbedBuilder();
// set author - name, icon url, url
embed.setAuthor("Hello", "https://i.furry.cool/DonPeek.png", "https://furry.cool");
// the get/remove helper methods exist for most functions
console.log(embed.getAuthor()); // { name: "Hello", iconURL: "https://i.furry.cool/DonPeek.png", url: "https://furry.cool" }
embed.removeAuthor();
// set color, accepts a number
embed.setColor(0xFFA500);
// set description
embed.setDescription("hi this is some description content");
console.log(embed.getDescription()); // hi this is some description content"
embed.setDescription("separate parameters will be", "joined by newlines");
console.log(embed.getDescription()); // separate parameters will be
// joined by newlines
embed.setDescription(["arrays are also", "accepted"], ["these will also be", "joined by newlines"]);
console.log(embed.getDescription()); // arrays are also
// accepted
// these will also be
// joined by newlines
// add a field - name, value, inline (optional)
embed.addField("field name", "field value");
embed.addField("field name", "field value", true);
embed.addField("field name", "field value", false);
// add a field with a blank name & value (zero width space) - inline
embed.addBlankField();
embed.addBlankField(true);
embed.addBlankField(false);
// add multiple fields manually
// you can provide embeds as separate parameters, a single array argument, multiple arrays as separate parameters, or a mix of both
embed.addFields({ name: "field name", value: "field value" }, { name: "field name", value: "field value" });
embed.addFields([{ name: "field name", value: "field value" }, { name: "field name", value: "field value" }]);
embed.addFields({ name: "field name", value: "field value" }, [{ name: "field name", value: "field value", inline: true }, { name: "field name", value: "field value", inline: false }]);
embed.addFields([{ name: "field name", value: "field value", inline: true }, { name: "field name", value: "field value", inline: false }], { name: "field name", value: "field value" });
embed.addFields([{ name: "field name", value: "field value", inline: false }, { name: "field name", value: "field value", inline: true }], [{ name: "field name", value: "field value", inline: true }, { name: "field name", value: "field value", inline: false }]);
// set the footer - text, icon url
embed.setFooter("hi", "https://i.furry.cool/DonPride.png");
// set the image - url
embed.setImage("https://i.furry.cool/DonCoffee.png");
// set the timestamp - time (accepts iso timestamp, a Date instance, or "now")
embed.setTimestamp("now");
// to retrieve current value as a Date: getTimestampDate
// set the title - title
embed.setTitle("some title stuff");
// set the url - url
embed.setURL("https://furry.cool");
// convert the embed to a json object
const json = embed.toJSON();
// convert the embed into a json object, inside of an array
const jsonArray = embed.toJSON(true);
// to load an embed from json, use the static loadFromJSON method - this accepts both a singular embed, and multiple embeds
const load1 = EmbedBuilder.loadFromJSON({ title: "embed #1" }); // EmbedBuilder
const load2 = EmbedBuilder.loadFromJSON([ { title: "embed #1" }, { title: "embed #2" } ]); // [EmbedBuilder, EmbedBuilder]
// if you still want to load from an array, but want a singular instance returned, you can set the forceSingular parameter to true
// this will throw away anything but the first embed
const load1FromArray = EmbedBuilder.loadJSON([ { title: "embed #1" } ], true); // EmbedBuilder
// const { ApplicationCommandBuilder } = require("@oceanicjs/builders");
import {
ApplicationCommandBuilder,
ApplicationCommandOptionBuilder
} from "@oceanicjs/builders";
import {
ApplicationCommandTypes,
Permission,
ApplicationCommandOptionTypes,
ChannelTypes
} from "oceanic.js";
const chatInput = new ApplicationCommandBuilder(ApplicationCommandTypes.CHAT_INPUT, "slash-command");
// to allow or disallow usage in dms
chatInput.allowDMUsage(); // setDMPermission(true)
chatInput.disallowDMUsage(); // setDMPermission(false)
// set the default permissions required to use the command
// this accepts: bigint, string, Permission instance (from oceanic), array of permission names, permission names as arguments
chatInput.setDefaultMemberPermissions(3n);
chatInput.setDefaultMemberPermissions("3");
chatInput.setDefaultMemberPermissions(new Permission(3n));
chatInput.setDefaultMemberPermissions(["CREATE_INVITE", "KICK_MEMBERS"]);
chatInput.setDefaultMemberPermissions("CREATE_INVITE", "KICK_MEMBERS"); // provided as separate parameters
// set the description - required for chat input commands
chatInput.setDescription("Some random command");
// set the description localizations - this overrides any present localizations
chatInput.setDescriptionLocalizations({
"es-ES": "Algún comando aleatorio"
});
// you can also add localizations individually
chatInput.addDescriptionLocalization("de", "irgendein zufälliger Befehl");
// set the name, if you want to change the earlier value for some reason
chatInput.setName("slash-command-test");
// set the name localizations - this overrides any present localizations
chatInput.setNameLocalizations({
"es-ES": "barra-comando-prueba"
});
// you can also add localizations individually
chatInput.addNameLocalization("de", "schrägstrich-befehlstest");
// options - the add method can be used in various different ways
chatInput.addOption("option1", ApplicationCommandOptionTypes.STRING, {
description: "Some option.",
descriptionLocalizations: {
"es-ES": "Alguna opción.",
"de": "Einige Optionen."
},
nameLocalizations: {
"es-ES": "opción1",
"de": "option1"
},
required: true,
choices: [ // setChoices(choices) & addChoice(name, value, nameLocalizations?)
{
name: "choice-1",
value: "one",
nameLocalizations: {
"es-ES": "elección-1",
"de": "wahl-1"
}
}
]
});
// or, if you prefer to use methods, you can do that too
chatInput.addOption("option2", ApplicationCommandOptionTypes.STRING, (option) => {
// option is a new ApplicationCommandOptionBuilder instance with prefilled name & type values
option.setDescription("Another option.")
.setDescriptionLocalizations({
"es-ES": "Otra opción."
})
.addDescriptionLocalization("de", "Andere Option.")
.setNameLocalizations({
"es-ES": "opción2"
})
.addNameLocalization("de", "option2")
.setRequired()
.setAutocomplete();
// nothing needs to be returned, any return will be discarded
});
// you can also construct the ApplicationCommandOptionBuilder instance yourself
const option = new ApplicationCommandOptionBuilder(ApplicationCommandOptionTypes.CHANNEL, "channel-option")
.setDescription("An option that accepts a channel.")
.setDescriptionLocalizations({
"es-ES": "Una opción que acepta un canal."
})
.addDescriptionLocalization("de", "Eine Option, die einen Kanal akzeptiert.")
.setNameLocalizations({
"es-ES": "opción-de-canal"
})
.addNameLocalization("de", "kanaloption")
.setRequired(false) // same as not specifying at all
.setChannelTypes([ChannelTypes.GUILD_TEXT, ChannelTypes.GUILD_ANNOUNCEMENT]);
// if you want to convert the option to json for usage elsewhere, a .toJSON() method exists
chatInput.addOption(option);
// you can also do everything yourself, if you feel so inclined
chatInput.addOption({
name: "integer-option",
type: ApplicationCommandOptionTypes.INTEGER,
description: "I'm tired of writing examples",
descriptionLocalizations: {
// Discord has no way to chose fem/masc
"es-ES": "Estoy cansada de escribir ejemplos",
"de": "Ich bin es leid, Beispiele zu schreiben"
},
nameLocalizations: {
"es-ES": "opción-de-entero",
"de": "integer-option"
},
minValue: 1, // for the builder, this is setMinMax(min, max) - this is for both values & length
maxValue: 5
});
npm i @oceanicjs/builders