From 924f7c0ba5dcda690fb71718c02ff3da4a681474 Mon Sep 17 00:00:00 2001 From: ITOH Date: Sat, 5 Dec 2020 22:33:04 +0100 Subject: [PATCH] Update Advanced Guide - Changed code to use latest Discordeno Boilerplate features. - Correct deprecated imports. - Change Links to use the new documentation. Changed some more things too --- docs/src/advanced/arguments.md | 14 ++--- docs/src/advanced/dynamiccommands.md | 78 ++++++---------------------- docs/src/advanced/permlevels.md | 50 +++++++++--------- docs/src/advanced/subcommands.md | 16 +++--- 4 files changed, 58 insertions(+), 100 deletions(-) diff --git a/docs/src/advanced/arguments.md b/docs/src/advanced/arguments.md index f5a212694..a69b1d438 100644 --- a/docs/src/advanced/arguments.md +++ b/docs/src/advanced/arguments.md @@ -16,6 +16,8 @@ Discordeno comes with the most useful command arguments already built for you. T - `member` When you want a member object and the user can provide a member id, @mention or their username/nickname. - `number` When you want a number. - `role` When you want a role object. The user can provide the role id, mention or role name. +- `snowflake` When you just want a snowflake. +- `..snowflakes` When you want to check if the mentioned ID is a valid snowflake. - `subcommand` When your command has subcommands. @@ -39,7 +41,7 @@ Suppose you wanted to make it possible so that the boolean argument could accept What if we also wanted to support, `yes` and `no`? Let's open up the `boolean.ts` file in the arguments folder and get started. ```ts -import { botCache } from "../../mod.ts"; +import { botCache } from "../../deps.ts"; botCache.arguments.set("boolean", { name: "boolean", @@ -55,7 +57,7 @@ botCache.arguments.set("boolean", { Simply update the code so it looks like the following: ```ts -import { botCache } from "../../mod.ts"; +import { botCache } from "../../deps.ts"; botCache.arguments.set("boolean", { name: "boolean", @@ -80,7 +82,7 @@ First, we need to update the **CommandArgument** interface in `src/types/command - Once that's done, we can go and create the code for it. Now, lets create a new file in `src/arguments` folder called `url.ts` and paste the base snippet for a command argument below. ```ts -import { botCache } from "../../mod.ts"; +import { botCache } from "../../deps.ts"; botCache.arguments.set("argumentname", { name: "argumentname", @@ -93,7 +95,7 @@ botCache.arguments.set("argumentname", { First let's change the `argumentname` to be `url`. Then we can start adding the pseudo-code. ```ts -import { botCache } from "../../mod.ts"; +import { botCache } from "../../deps.ts"; botCache.arguments.set("url", { name: "url", @@ -111,7 +113,7 @@ botCache.arguments.set("url", { Now we can get started. ```ts -import { botCache } from "../../mod.ts"; +import { botCache } from "../../deps.ts"; botCache.arguments.set("url", { name: "url", @@ -163,6 +165,6 @@ arguments: [ ] ``` -We already covered using the arguments in a command in our guide when we created the role command, so we can skip that here. To re-read that you can check it out [here](https://discordeno.netlify.app/stepbystep/createcommand#arguments). +We already covered using the arguments in a command in our guide when we created the role command, so we can skip that here. To re-read that you can check it out [here](https://discordeno.mod.land/stepbystep/createcommand.html#arguments). Command arguments are an extremely powerful feature that can help make creating bots a lot easier. Discordeno provides extremely flexible command arguments. As a side benefit, command arguments are designed to be hot reloadable from the reload command. 🎉 diff --git a/docs/src/advanced/dynamiccommands.md b/docs/src/advanced/dynamiccommands.md index 209e31b9e..bb52cba04 100644 --- a/docs/src/advanced/dynamiccommands.md +++ b/docs/src/advanced/dynamiccommands.md @@ -15,12 +15,9 @@ Let's create all the commands for the entire Nekos.Life API in a very short time - Create a file in the commands folder called `nekos.ts` which will create all our fun commands. ```ts -import { botCache } from "../../mod.ts"; -import { sendMessage } from "../../deps.ts"; +import { botCache,sendMessage } from "../../deps.ts"; const nekosEndpoints = [ - { name: "spank", path: "/img/spank", nsfw: true }, - { name: "gasm", path: "/img/gasm", nsfw: true }, { name: "tickle", path: "/img/tickle", nsfw: false }, { name: "slap", path: "/img/slap", nsfw: false }, { name: "poke", path: "/img/poke", nsfw: false }, @@ -50,43 +47,7 @@ const nekosEndpoints = [ { name: "gecg", path: "/img/gecg", nsfw: false }, { name: "avatar", path: "/img/avatar", nsfw: false }, { name: "waifu", path: "/img/waifu", nsfw: false }, - // The follow name and paths have been hidden for this guide as they are NSFW. - { name: "nsfw_endpoint", path: "/img/nsfw_example", nsfw: true }, - { name: "nsfw_endpoint", path: "/img/nsfw_example", nsfw: true }, - { name: "nsfw_endpoint", path: "/img/nsfw_example", nsfw: true }, - { name: "nsfw_endpoint", path: "/img/nsfw_example", nsfw: true }, - { name: "nsfw_endpoint", path: "/img/nsfw_example", nsfw: true }, - { name: "nsfw_endpoint", path: "/img/nsfw_example", nsfw: true }, - { name: "nsfw_endpoint", path: "/img/nsfw_example", nsfw: true }, - { name: "nsfw_endpoint", path: "/img/nsfw_example", nsfw: true }, - { name: "nsfw_endpoint", path: "/img/nsfw_example", nsfw: true }, - { name: "nsfw_endpoint", path: "/img/nsfw_example", nsfw: true }, - { name: "nsfw_endpoint", path: "/img/nsfw_example", nsfw: true }, - { name: "nsfw_endpoint", path: "/img/nsfw_example", nsfw: true }, - { name: "nsfw_endpoint", path: "/img/nsfw_example", nsfw: true }, - { name: "nsfw_endpoint", path: "/img/nsfw_example", nsfw: true }, - { name: "nsfw_endpoint", path: "/img/nsfw_example", nsfw: true }, - { name: "nsfw_endpoint", path: "/img/nsfw_example", nsfw: true }, - { name: "nsfw_endpoint", path: "/img/nsfw_example", nsfw: true }, - { name: "nsfw_endpoint", path: "/img/nsfw_example", nsfw: true }, - { name: "nsfw_endpoint", path: "/img/nsfw_example", nsfw: true }, - { name: "nsfw_endpoint", path: "/img/nsfw_example", nsfw: true }, - { name: "nsfw_endpoint", path: "/img/nsfw_example", nsfw: true }, - { name: "nsfw_endpoint", path: "/img/nsfw_example", nsfw: true }, - { name: "nsfw_endpoint", path: "/img/nsfw_example", nsfw: true }, - { name: "nsfw_endpoint", path: "/img/nsfw_example", nsfw: true }, - { name: "nsfw_endpoint", path: "/img/nsfw_example", nsfw: true }, - { name: "nsfw_endpoint", path: "/img/nsfw_example", nsfw: true }, - { name: "nsfw_endpoint", path: "/img/nsfw_example", nsfw: true }, - { name: "nsfw_endpoint", path: "/img/nsfw_example", nsfw: true }, - { name: "nsfw_endpoint", path: "/img/nsfw_example", nsfw: true }, - { name: "nsfw_endpoint", path: "/img/nsfw_example", nsfw: true }, - { name: "nsfw_endpoint", path: "/img/nsfw_example", nsfw: true }, - { name: "nsfw_endpoint", path: "/img/nsfw_example", nsfw: true }, - { name: "nsfw_endpoint", path: "/img/nsfw_example", nsfw: true }, - { name: "nsfw_endpoint", path: "/img/nsfw_example", nsfw: true }, - { name: "nsfw_endpoint", path: "/img/nsfw_example", nsfw: true }, - { name: "nsfw_endpoint", path: "/img/nsfw_example", nsfw: true }, + // All other paths have been removed for this guide as they are NSFW. { name: "nsfw_endpoint", path: "/img/nsfw_example", nsfw: true }, ]; @@ -98,13 +59,15 @@ nekosEndpoints.forEach((endpoint) => { execute: async function (message) { const url = `https://nekos.life/api/v2${endpoint.path}`; const result = await fetch(url).then((res) => res.json()); - sendMessage(message.channelID, result?.url); + sendMessage(message.channelID, result?.url || result[endpoint.name]); }, }); }); ``` -Take a minute to realize what just happened. This has made 68 different unique commands dynamically. In 1 file, using the same piece of code, we created so many commands. You can easily add more commands to this. +> **Note:** We have removed the endpoints that were leading to NSFW content. With them, we would just have created 68 different commands. + +Take a minute to realize what just happened. This has made 29 different unique commands dynamically. In 1 file, using the same piece of code, we created so many commands. You can easily add more commands to this. **That ladies and gentleman is the power and magic of Discordeno!** @@ -113,23 +76,13 @@ Take a minute to realize what just happened. This has made 68 different unique c If your still a little confused, don't worry. Let's break it down. ```ts -nekosEndpoints.forEach((endpoint) => { - botCache.commands.set(endpoint.name, { - name: endpoint.name, - nsfw: endpoint.nsfw, - botChannelPermissions: ["SEND_MESSAGES", "EMBED_LINKS"], - execute: async function (message) { - const url = `https://nekos.life/api/v2${endpoint.path}`; - const result = await fetch(url).then((res) => res.json()); - sendMessage(message.channelID, result?.url); - }, - }); -}); +const nekosEndpoints = [ + { name: "tickle", path: "/img/tickle", nsfw: false }, + // ... +] ``` -This is the part where we are doing the magical stuff. So let's take a look at this a bit. Above this we had an array of all the endpoints on the API giving a name, a path, and a boolean to say if it is NSFW or not. - -We ran a loop `nekosEndpoints.forEach()` on that array and for each item in that array, we created a command. +This is just an array of all the endpoints on the API giving a name, a path, and a boolean to say if it is NSFW or not. ```ts botCache.commands.set(endpoint.name, { @@ -139,14 +92,17 @@ botCache.commands.set(endpoint.name, { execute: async function (message) { const url = `https://nekos.life/api/v2${endpoint.path}`; const result = await fetch(url).then((res) => res.json()); - sendMessage(message.channelID, result?.url); + sendMessage(message.channelID, result?.url || result[endpoint.name]); }, }); ``` -For the command name, we used the `endpoint.name` property. For the `nsfw` property we used the `endpoint.nsfw` property. Since all of these commands, send a message that is a URL we simply required those permissions in all 68 of these commands. +This is the part where we are doing the magical stuff. So let's take a look at this a bit. + +We ran a loop `nekosEndpoints.forEach()` on that array and for each item in that array, we created a command. + +For the command name, we used the `endpoint.name` property. For the `nsfw` property we used the `endpoint.nsfw` property. Since all of these commands, send a message that is a URL we simply required those permissions in all 29 of these commands. Then we simply write the code for the commands and it all just works. If you were to reload/restart your bot now with this. You will see that you have access to 68 new commands. Take a minute and try out some of the commands and how they function. - diff --git a/docs/src/advanced/permlevels.md b/docs/src/advanced/permlevels.md index 7870aacc0..be95119f2 100644 --- a/docs/src/advanced/permlevels.md +++ b/docs/src/advanced/permlevels.md @@ -21,7 +21,7 @@ Any of these can be easily modified, in their files. Let's go ahead and try and If you have a bot support server, you might also have a role setup for your bot's support team. So to make life easier, it would be nice if someone with that role could use the command without having to modify the configs file every time. ```ts -import { botCache } from "../../mod.ts"; +import { botCache } from "../../deps.ts"; import { PermissionLevels } from "../types/commands.ts"; import { configs } from "../../configs.ts"; @@ -38,17 +38,17 @@ Let's add some pseudo-code first. botCache.permissionLevels.set( PermissionLevels.BOT_SUPPORT, async (message) => { - // If the user id exists in the configs allow the command - if (configs.userIDs.botSupporters.includes(message.author.id)) return true - - // The users id was not in the configs, check if they have the role in bot server - - // Get the bots support server - + // If the user id exists in the configs allow the command + if (configs.userIDs.botSupporters.includes(message.author.id)) return true + + // The users id was not in the configs, check if they have the role in bot server + + // Get the bots support server + // If the user is not a member of the support server they can't be one of the support staff. // If they have the role allow the command otherwise it will be false and block the command. - }, + }, ); ``` @@ -58,12 +58,12 @@ Awesome, now that the plan is in place, let's add the code. botCache.permissionLevels.set( PermissionLevels.BOT_SUPPORT, async (message) => { - // If the user id exists in the configs allow the command - if (configs.userIDs.botSupporters.includes(message.author.id)) return true - - // The users id was not in the configs, check if they have the role in bot server - - // Get the bots support server + // If the user id exists in the configs allow the command + if (configs.userIDs.botSupporters.includes(message.author.id)) return true + + // The users id was not in the configs, check if they have the role in bot server + + // Get the bots support server const guild = cache.guilds.get(configs.supportServerID) if (!guild) return false @@ -73,7 +73,7 @@ botCache.permissionLevels.set( // If they have the role allow the command otherwise it will be false and block the command. return member.roles.includes('BOT_SUPPORT_ROLE_ID_HERE') - }, + }, ); ``` @@ -101,8 +101,8 @@ Let's add a new one for a Nitro Booster role. You can add it in any order here y ```ts export enum PermissionLevels { - MEMBER, - NITRO_BOOSTER, + MEMBER, + NITRO_BOOSTER, MODERATOR, ADMIN, SERVER_OWNER, @@ -115,19 +115,19 @@ export enum PermissionLevels { Once that's done, we can go and create the code for it. Now, lets create a new file in `permissionLevels` folder called `booster.ts` and paste the base snippet for a permission level below. ```ts -import { botCache } from "../../mod.ts"; +import { botCache } from "../../deps.ts"; import { PermissionLevels } from "../types/commands.ts"; import { configs } from "../../configs.ts"; botCache.permissionLevels.set( PermissionLevels, async (message) => { - // Code goes here - } + // Code goes here + } ); ``` -**NOTE:** You will see an error in the `PermissionLevels,` line because we need to select one of the permission levels. In this case we want the NITRO_BOOSTER level we just created above. +> **NOTE:** You will see an error in the `PermissionLevels,` line because we need to select one of the permission levels. In this case we want the NITRO_BOOSTER level we just created above. ```ts PermissionLevels.NITRO_BOOSTER @@ -136,7 +136,7 @@ PermissionLevels.NITRO_BOOSTER Next we can add the code in place. ```ts -import { botCache } from "../../mod.ts"; +import { botCache } from "../../deps.ts"; import { PermissionLevels } from "../types/commands.ts"; import { configs } from "../../configs.ts"; @@ -164,7 +164,7 @@ Awesome! You just created your very own permission level. Now let's check out ho There are two ways to use permission levels. You can provide an array of PermissionLevels or you can provide a custom function. ```ts -botCache.commands.set(`reload`, { +createCommand({ name: `reload`, permissionLevels: [PermissionLevels.BOT_OWNER], botChannelPermissions: ["SEND_MESSAGES"], @@ -185,7 +185,7 @@ If you provide an array of permission levels, only one of these is necessary to There is another way to use permission levels. You can provide a custom function that must return a boolean. For example, ```ts -botCache.commands.set(`example`, { +createCommand({ name: `example`, permissionLevels: (message, command, guild) => { // Anything you'd like to check here and return a boolean. Must return true or false. diff --git a/docs/src/advanced/subcommands.md b/docs/src/advanced/subcommands.md index 7ab7ef288..93def018c 100644 --- a/docs/src/advanced/subcommands.md +++ b/docs/src/advanced/subcommands.md @@ -9,14 +9,14 @@ A subcommand can have it's own settings for example, you can allow 1 subcommand Let's start by understanding the `prefix` command which uses subcommands. It is a good basic example, to help us understand how to create a subcommand. ```ts -import { botCache } from "../../mod.ts"; +import { botCache } from "../../deps.ts"; import { PermissionLevels } from "../types/commands.ts"; -import { sendResponse, sendEmbed, createSubcommand } from "../utils/helpers.ts"; +import { sendResponse, sendEmbed, createSubcommand, createCommand } from "../utils/helpers.ts"; import { parsePrefix } from "../monitors/commandHandler.ts"; import { Embed } from "../utils/Embed.ts"; // This command will only execute if there was no valid sub command: !prefix -botCache.commands.set("prefix", { +createCommand({ name: "prefix", arguments: [ { @@ -31,7 +31,7 @@ botCache.commands.set("prefix", { const embed = new Embed() .setTitle("Prefix Information") .setDescription(` - **Guild**: \`${message.guild()?.name}\` + **Guild**: \`${message.guild?.name}\` **Current Prefix**: \`${parsePrefix(message.guildID)}\` `) .setTimestamp(); @@ -49,7 +49,7 @@ createSubcommand("prefix", { type: "string", required: true, missing: (message) => { - sendResponse(message, `${message.member()} please provid a prefix`); + sendResponse(message, `${message.member} please provid a prefix`); }, }, ], @@ -78,7 +78,7 @@ createSubcommand("prefix", { Let's separate this to understand what is happening here. The first half of the code is the main command. This is like any other command. However, the important thing is in the arguments we requested a subcommand! ```ts -botCache.commands.set("prefix", { +createCommand({ name: "prefix", arguments: [ { @@ -93,7 +93,7 @@ botCache.commands.set("prefix", { const embed = new Embed() .setTitle("Prefix Information") .setDescription(` - **Guild**: \`${message.guild()?.name}\` + **Guild**: \`${message.guild?.name}\` **Current Prefix**: \`${parsePrefix(message.guildID)}\` `) .setTimestamp(); @@ -115,7 +115,7 @@ createSubcommand("prefix", { type: "string", required: true, missing: (message) => { - sendResponse(message, `${message.member()} please provid a prefix`); + sendResponse(message, `${message.member} please provid a prefix`); }, }, ],