UNPKG

@oceanicjs/builders

Version:

Helpful builders for various Discord related things.

327 lines (278 loc) 13.1 kB
## Builders Helpful builders for various Discord related things. This module is specifically built to be compatible with [Oceanic](https://github.com/OceanicJS/Oceanic). Get started by using one of our main classes, [`ComponentBuilder`](#component-builder) or [`EmbedBuilder`](#embed-builder). ### Component Builder ```ts // 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>(); ``` ### Embed Builder ```ts // 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 ``` ### Application Commands ```ts // 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 }); ``` ## Install ```sh npm i @oceanicjs/builders ```