oiclid 4 years ago
parent
commit
b8b1d4c79f
1 changed files with 1 additions and 1257 deletions
  1. 1 1257
      community-contributions/discordbot/README.md

+ 1 - 1257
community-contributions/discordbot/README.md

@@ -30,7 +30,7 @@ As an aside, never store any keys or tokens on GitHub, ESPECIALLY if the repo is
 
 ## Developing the Bot
 
-While Discord bots can be built with several different languages - the unofficial [Discord API  server](https://discord.gg/discord-api) has channels for at least 19 different languages -  I will concentrate on TypeScript.
+While DIscord bots can be built with several different languages - the unofficial [Discord API  server](https://discord.gg/discord-api) has channels for at least 19 different languages -  I will concentrate on TypeScript.
 
 The [Discord TypeScript Server](https://discord.gg/VDjwu8E) is an ideal source for interacting with other TypeScript developers. as well as a potential source for any technical help one may need. There's also an [examples folder](https://github.com/OwenCalvin/discord.ts/tree/master/examples) of bots built using the Discord TypeScript library.
 
@@ -102,1263 +102,7 @@ async function start() {
 start();
 ```
 
-### @Discord - Getting started
-So we start with an empty class (abstract is not necessary but this is more type-safe, the class shouldn't be initialized).
-```typescript
-abstract class AppDiscord {
-}
-```
-
-Then you must declare it as a Discord app class with the `@Discord` decorator :
-
-```typescript
-import { Discord } from "@typeit/discord";
-
-@Discord() // Decorate the class
-abstract class AppDiscord {
-}
-```
-
-### @On / @Once - Listen to the events
-We can now declare methods that will be executed whenever a Discord event is triggered.  
-Our methods must be decorated with the `@On(event: string)` or `@Once(event: string)` decorator.  
-That's simple, when the event is triggered, the method is called:
-
-```typescript
-import {
-  Discord,
-  On,
-  Once
-} from "@typeit/discord";
-
-@Discord()
-abstract class AppDiscord {
-  @On("message")
-  private onMessage() {
-    // ...
-  }
-
-  @Once("messageDelete")
-  private onMessageDelete() {
-    // ...
-  }
-}
-```
-
-### Client payload injection
-For each event a list of arguments is injected in your decorated method, you can type this list thanks to the `ArgsOf<Event>` type provided by `discord.ts`.
-You also receive other useful arguments after that:
-1. The event payload (`ArgsOf<Event>`)
-2. The `Client` instance
-3. The [guards](https://github.com/OwenCalvin/discord.ts#%EF%B8%8F-guards) payload
-
-> You should use JS desctructuring for `ArgsOf<Event>` like in this example
-```typescript
-import {
-  Discord,
-  On,
-  Client,
-  ArgsOf
-} from "@typeit/discord";
-
-@Discord()
-abstract class AppDiscord {
-  @On("message")
-  private onMessage(
-    [message]: ArgsOf<"message">, // Type message automatically
-    client: Client, // Client instance injected here,
-    guardPayload: any
-  ) {
-    // ...
-  }
-}
-```
-
-## 📟 Commands
-`discord.ts` provides a decorator allowing the implementation of command systems very simply by essentially using only two decorators `@Command(commandName?: string)` and `@CommandNotFound()`.
-
-We will also use `@Discord(prefix: string)` to specify a prefix for our commands within the class.
-
-**You can specify a `regex` expression for your command names**  
-**For advanced usage use the `@Rules` decorator, you can also specify aliases using that**
-
-> Notice that the first arguments do not use `ArgsOf`, the first payload is a `CommandMessage`.
-```typescript
-import {
-  Discord,
-  On,
-  Client,
-  Command,
-  CommandMessage,
-  CommandNotFound
-} from "@typeit/discord";
-
-// Specify your prefix
-@Discord("!") 
-abstract class AppDiscord {
-  // Reachable with the command: !hello
-  @Command("hello")
-  private hello(message: CommandMessage) {
-  }
-
-  // !bye
-  // !yo
-  @CommandNotFound()
-  private notFound(message: CommandMessage) {
-  }
-}
-```
-
-### The `CommandMessage` object
-The `CommandMessage` is the first argument injected into a method using `@Command` or `@CommandNotFound`, it has exactly the same structure as the `Message` object in `discord.js` except that it includes useful information about the command that was executed such as:  
-- `prefix`: `string`   
-The prefix that is applied to your command.
-
-- `commandName`: `string`  
-The command name
-
-- `commandContent`: `string`  
-The message content without the prefix (`-cmd hello there` becomes `hello there`)
-
-- `description`: `string`  
-[The command description](https://github.com/OwenCalvin/discord.ts#infos--description)
-
-- `infos`: `InfoType` (`any`)  
-[The command infos](https://github.com/OwenCalvin/discord.ts#infos--description)  
-
-- `args`: `ArgsType` (`any`)  
-[The command arguments](https://github.com/OwenCalvin/discord.ts#args-parsing)  
-
-- `discord`: `DiscordInfos`:  
-The linked `@Discord` class infos
-
-- `argsRules`: (`ArgsRulesFunction<Expression>[]`)  
-The rules that are applied to execute the command (advanced)
-
-### Args parsing
-You have the ability to specify arguments for your command, as `express.js` does in it's routing system. So by using `":"` (or the value specified in `variablesChar` when your `Client` intializes) in the name of your `@Command` in front of the dynamic values, `discord.ts` will extract these informations when a command is executed and inject it into the `args` property of your `CommandMessage` with the correct name that you indicated in the command name.
-
-> If the argument value is a number the value will be casted automaticaly
-```typescript
-@Discord("!")
-abstract class AppDiscord {
-  @Command("args :slug :number")
-  private hello(message: CommandMessage) {
-    const mySlug = message.args.slug;
-    const myNumber = message.args.number;
-
-    // Using js destructuring:
-    const { slug, number } = message.args; 
-  }
-}
-```
-
-### Dynamic Values
-Okay but what if my prefix or my command name of my `@Discord` / `@Command` decorators depends on external datas? Well you can specify a function that will be executed when a command is executed to verify the origin and return the correct value.  
-
-You receive the `Message` as the first argument and the `Client` instance as the second one.
-
-> This is also applied to `@ComputedRules`
-
-```typescript
-// If the message has been sent in the guild with
-// the name MyGuildName the prefix "." will be considered
-// otherwise the prefix "$" will trigger the action.
-async function prefixBehaviour(message: Message, client: Client) {
-  if (message.guild.name === "MyGuildName") {
-    return ".";
-  }
-  return "$";
-}
-
-@Discord(prefixBehaviour)
-abstract class AppDiscord {
-  @Command("hello")
-  private hello(message: CommandMessage) {
-    // ...
-  }
-}
-```
-
-With a dynamic command name:
-> May be for a very specific use case
-```typescript
-// If the message has been sent in the guild with
-// the name MyGuildName the prefix "." will be considered
-// otherwise the prefix "$" will trigger the action.
-async function prefixBehaviour(message: Message, client: Client) {
-  if (message.guild.name === "MyGuildName") {
-    return ".";
-  }
-  return "$";
-}
-
-// The command name will be yo if the message is "hello"
-async function commandName(message: Message, client: Client) {
-  if (message.content === "hello") {
-    return "yo";
-  }
-  return "hello";
-}
-
-
-@Discord(prefixBehaviour)
-abstract class AppDiscord {
-  @Command(commandName)
-  private hello(message: CommandMessage) {
-    // ...
-  }
-}
-```
-
-### Command directory pattern
-> [Example](https://github.com/OwenCalvin/discord.ts/tree/master/examples/commands-dir)  
-
-If you have a directory pattern that looks like this:
-```sh
-Main.ts
-DiscordApp.ts
-commands
-- Ping.ts
-- Hello.ts
-- Blabla.ts
-events
-- MessageDelete.ts
-```
-
-You should use the `import` parameter for the `@Discord` decorator.
-Here, all the elements will be injected into this Discord class instance.
-```typescript
-import * as Path from "path";
-import {
-  Discord,
-  CommandNotFound
-} from "@typeit/discord";
-
-// The prefix will be applied to the imported commands
-@Discord("!", {
-  import: [
-    Path.join(__dirname,  "commands", "*.ts"),
-    Path.join(__dirname,  "events", "*.ts")
-    // You can also specify the class directly here if you don't want to use a glob
-  ]
-})
-export abstract class DiscordApp {
-  // This command not found is triggered
-  @CommandNotFound()
-  notFoundA(command: CommandMessage) {
-    command.reply("Command not found");
-  }
-}
-```
-
-Here is an example of what your command file should look like:
-*Bye.ts*
-```typescript
-import {
-  Command,
-  CommandMessage
-} from "@typeit/discord";
-
-// Do not have to decorate the class with @Discord
-// It applied the parameters of the @Discord decorator that imported it
-export abstract class Bye {
-  @Command("bye")
-  async bye(command: CommandMessage) {
-    command.reply("Bye!");
-  }
-
-  @Command("ciao")
-  async ciao(command: CommandMessage) {
-    command.reply("Ciao!");
-  }
-}
-```
-
-*MessageDelete.ts*
-```typescript
-import {
-  On,
-  ArgsOf
-} from "@typeit/discord";
-
-// Do not have to decorate the class with @Discord
-// It applied the parameters of the @Discord decorator that imported it
-export abstract class MessageDelete {
-  @On("messageDelete")
-  async onMessageDelete([message]: ArgsOf<"messageDelete">) {
-    message.reply("Bye!");
-  }
-}
-```
-
-## ℹ️ @Infos / @Description
-It would be useful to be able to specify order information, for example to display a help command (`!help`) in your application.
-For the one you have two useful decorators which are `@Infos` and `@Description`.
-
-> `@Description` is a shortcut for `@Infos({ description: "..." })`
-```typescript
-import {
-  ClassCommand,
-  Command,
-  CommandMessage
-} from "@typeit/discord";
-
-@Discord("!")
-@Description("Admin commands")
-@Infos({ forAdmins: true })
-export abstract class Bye {
-  @Command("ciao")
-  @Description("say ciao")
-  async ciao(command: CommandMessage) {
-    command.reply("Ciao!");
-  }
-}
-```
-
-To retrieve these informations, you can use the `Client` static methods:  
-```typescript
-import { Client } from "@typeit/discord";
-
-Client.getCommands();         // @Command
-Client.getCommandsNotFound(); // @CommandNotFound
-Client.getEvents();           // @On
-Client.getDiscords();         // @Discord
-```
-
-## @Rules / @ComputedRules - Advanced message validation
-If you need to use advanced expressions and aliases for your commands, this decorator is for you. It accepts regex (if you specify a string it will be considered as a regex expression, you have to escape the `"."` => `"\."` characters) and an instance of [RuleBuilder](https://github.com/OwenCalvin/discord.ts#rulebuilder).
-
-```typescript
-import {
-  ClassCommand,
-  Command,
-  CommandMessage,
-  Rules
-} from "@typeit/discord";
-
-@Discord("!")
-export abstract class Bye {
-  @Command()
-  @Rules(/salut\s{1,}toi(\s{1,}|$)/i)
-  async hello(command: CommandMessage) {
-    command.reply("Ciao!");
-  }
-}
-```
-
-The rules can also be applied to `@Discord`, it will be merged to the rules of commands inside the class:
-> In this example we rewrite explicitly the prefix rule
-```typescript
-import {
-  ClassCommand,
-  Command,
-  CommandMessage,
-  Rules,
-  Rule
-} from "@typeit/discord";
-
-@Discord()
-@Rules(Rule().startWith("!")) // Explicit prefix
-export abstract class Bye {
-  @Rules(Rule("salut").space("toi").spaceOrEnd())
-  async hello(command: CommandMessage) {
-    command.reply("Ciao!");
-  }
-}
-```
-
-### RuleBuilder
-But it's not clear to put a RegExp... 
-Yes for this reason you can use the `RuleBuilder` API:  
-Now to write `/salut\s{1,}toi(\s{1,}|$)/i` it's simple:
-
-```typescript
-import {
-  ClassCommand,
-  Command,
-  CommandMessage,
-  Rules,
-  Rule
-} from "@typeit/discord";
-
-@Discord("!")
-export abstract class Bye {
-  @Rules(Rule("salut").space("toi").spaceOrEnd())
-  async hello(command: CommandMessage) {
-    command.reply("Ciao!");
-  }
-}
-```
-
-### Computed rules
-Okay but I have rules that depends on computed my server datas like for my `@CommandName`...
-No problem just use `@ComputedRules`:
-```typescript
-import {
-  ClassCommand,
-  Command,
-  CommandMessage,
-  Rules,
-  Rule
-} from "@typeit/discord";
-
-async function getRules() {
-  return [Rule("salut").space("toi").spaceOrEnd()]
-}
-
-@Discord("!")
-export abstract class Bye {
-  @ComputedRules(getRules)
-  async hello(command: CommandMessage) {
-    command.reply("Ciao!");
-  }
-}
-```
-
-## ⚔️ Guards
-You can use functions that are executed before your event to determine if it's executed. For example, if you want to apply a prefix to the messages, you can simply use the `@Guard` decorator.  
-
-The order of execution of the guards is done according to their position in the list, so they will be executed in order (from top to bottom).  
-
-Guards works also with `@Command` and `@CommandNotFound`.  
-
-```typescript
-import {
-  Discord,
-  On,
-  Client,
-  Guard
-} from "@typeit/discord";
-import { NotBot } from "./NotBot";
-import { Prefix } from "./Prefix";
-
-@Discord()
-abstract class AppDiscord {
-  @On("message")
-  @Guard(
-    NotBot, // You can use multiple guard functions, they are excuted in the same order!
-    Prefix("!")
-  )
-  async onMessage([message]: ArgsOf<"message">) {
-    switch (message.content.toLowerCase()) {
-      case "hello":
-        message.reply("Hello!");
-        break;
-      default:
-        message.reply("Command not found");
-        break;
-    }
-  }
-}
-```
-
-### The guard functions
-> Notice that the guard function is impacted by your payloadInjection policy  
-
-Here is a simple example of a guard function (the payload and the client instance are injected like for events)  
-Guards work like `Koa`'s, it's a function passed in parameter (after the `Client`'s instance) and you will have to call if the guard is passed.
-> If next isn't called the next guard (or the main method) will not be executed
-```typescript
-import { GuardFunction } from "@typeit/discord";
-
-export const NotBot: GuardFunction<"message"> = (
-  [message],
-  client,
-  next
-) => {
-  if (client.user.id !== message.author.id) {
-    await next();
-  }
-}
-```
-
-If you have to indicate parameters for a guard function you can simple use the "function that returns a function" pattern like this:
-```typescript
-import { GuardFunction } from "@typeit/discord";
-
-export function Prefix(text: string, replace: boolean = true) {
-  const guard: GuardFunction<"message"> = (
-    [message],
-    client,
-    next
-  ) => {
-    const startWith = message.content.startsWith(text);
-    if (replace) {
-      message.content = message.content.replace(text, "");
-    }
-    if (startWith) {
-      await next();
-    }
-  };
-
-  return guard;
-}
-```
-
-### Guard datas
-As 4th parameter you receive a basic empty object that can be used to transmit data between guard and with your main method.
-```typescript
-import { GuardFunction } from "@typeit/discord";
-
-export const NotBot: GuardFunction<"message"> = (
-  [message],
-  client,
-  next,
-  guardDatas
-) => {
-  if (client.user.id !== message.author.id) {
-    guardDatas.message = "the NotBot guard passed"
-    await next();
-  }
-}
-```
-```typescript
-import {
-  Discord,
-  Command,
-  Client,
-  Guard
-} from "@typeit/discord";
-import { NotBot } from "./NotBot";
-import { Prefix } from "./Prefix";
-
-@Discord()
-abstract class AppDiscord {
-  @Command()
-  @Guard(
-    NotBot,
-    Prefix("!")
-  )
-  async hello(
-    command: CommandMessage,
-    client: Client,
-    guardDatas: any
-  ) {
-    console.log(guardDatas.message);
-    // > the NotBot guard passed 
-  }
-}
-```
-
-## API - Retrieve the infos
-You can simply get all the infos about your decorated stuff using:
-
-```typescript
-import { Client } from "@typeit/discord";
-
-Client.getCommands();         // @Command
-Client.getCommandsNotFound(); // @CommandNotFound
-Client.getEvents();           // @On
-Client.getDiscords();         // @Discord
-```
-
-## 💡 Events and payload
-Here you have the details about the payloads that are injected into the method related to a specific event.
-Note that on some events, for example voiceStateUpdate, it will return an array of the subsequent event payloads, and the second parameter will be the discord.ts Client.
-**`@Once(event: DiscordEvent)` exists too, it executes the method only one time**
-
-### The argument list
-Here is all the `DiscordEvents` and their parameters (`discord.js` version 12.2.0)
-- **channelCreate**: `(Channel)`
-- **channelDelete**: `(Channel | PartialDMChannel)`
-- **channelPinsUpdate**: `(Channel | PartialDMChannel, Date)`
-- **channelUpdate**: `(Channel, Channel)`
-- **debug**: `(string)`
-- **warn**: `(string)`
-- **disconnect**: `(any, number)`
-- **emojiCreate**: `(GuildEmoji)`
-- **emojiDelete**: `(GuildEmoji)`
-- **emojiUpdate**: `(GuildEmoji, GuildEmoji)`
-- **error**: `(Error)`
-- **guildBanAdd**: `(Guild, User | PartialUser)`
-- **guildBanRemove**: `(Guild, User | PartialUser)`
-- **guildCreate**: `(Guild)`
-- **guildDelete**: `(Guild)`
-- **guildUnavailable**: `(Guild)`
-- **guildIntegrationsUpdate**: `(Guild)`
-- **guildMemberAdd**: `(GuildMember | PartialGuildMember)`
-- **guildMemberAvailable**: `(GuildMember | PartialGuildMember)`
-- **guildMemberRemove**: `(GuildMember | PartialGuildMember)`
-- **guildMembersChunk**: `(Collection<Snowflake, GuildMember | PartialGuildMember>, Guild)`
-- **guildMemberSpeaking**: `(GuildMember | PartialGuildMember, Readonly<Speaking>)`
-- **guildMemberUpdate**: `(GuildMember | PartialGuildMember, GuildMember | PartialGuildMember)`
-- **guildUpdate**: `(Guild, Guild)`
-- **inviteCreate**: `(Invite)`
-- **inviteDelete**: `(Invite)`
-- **message**: `(Message)`
-- **messageDelete**: `(Message | PartialMessage)`
-- **messageReactionRemoveAll**: `(Message | PartialMessage)`
-- **messageReactionRemoveEmoji**: `(MessageReaction)`
-- **messageDeleteBulk**: `(Collection<Snowflake, Message | PartialMessage>)`
-- **messageReactionAdd**: `(MessageReaction, User | PartialUser)`
-- **messageReactionRemove**: `(MessageReaction, User | PartialUser)`
-- **messageUpdate**: `(Message | PartialMessage, Message | PartialMessage)`
-- **presenceUpdate**: `(Presence | undefined, Presence)`
-- **rateLimit**: `(RateLimitData)`
-- **ready**: `()`
-- **invalidated**: `()`
-- **roleCreate**: `(Role)`
-- **roleDelete**: `(Role)`
-- **roleUpdate**: `(Role, Role)`
-- **typingStart**: `(Channel | PartialDMChannel, User | PartialUser)`
-- **userUpdate**: `(User | PartialUser, User | PartialUser)`
-- **voiceStateUpdate**: `(VoiceState, VoiceState)`
-- **webhookUpdate**: `(TextChannel)`
-- **shardDisconnect**: `(CloseEvent, number)`
-- **shardError**: `(Error, number)`
-- **shardReady**: `(number)`
-- **shardReconnecting**: `(number)`
-- **shardResume**: `(number, number)`
-
-## Examples
-Some examples are provided in the [`/examples` folder](https://github.com/OwenCalvin/discord.ts/tree/master/examples) !
-
-## Migration v1 to v2
-You should just add parenthesis after the `@Discord` decorator, everywhere in your app.  
-`@Discord class X` should now be `@Discord() class X`.
-
-## Migration v2 to v3
-Now the `payloadInjection` policy is by default `"first"`, convert each events of your app or change your `payloadInjection` policy to `"spread"` inside the `Client` constructor:  
-```typescript
-const client = new Client({
-  payloadInjection: "spread"
-})
-```
-
-## Migration v3 to v4
-payloadInjection policy doesn't exists anymore, moreover the parameters inside the decorators has changed, please refer to the documentation or ask help using the discord server.
-
-## See also
-- [discord.js](https://discord.js.org/#/)## @Discord - Getting started
-So we start with an empty class (abstract is not necessary but this is more type-safe, the class shouldn't be initialized).
-```typescript
-abstract class AppDiscord {
-}
-```
-
-Then you must declare it as a Discord app class with the `@Discord` decorator :
-
-```typescript
-import { Discord } from "@typeit/discord";
-
-@Discord() // Decorate the class
-abstract class AppDiscord {
-}
-```
-
-### @On / @Once - Listen to the events
-We can now declare methods that will be executed whenever a Discord event is triggered.  
-Our methods must be decorated with the `@On(event: string)` or `@Once(event: string)` decorator.  
-That's simple, when the event is triggered, the method is called:
-
-```typescript
-import {
-  Discord,
-  On,
-  Once
-} from "@typeit/discord";
-
-@Discord()
-abstract class AppDiscord {
-  @On("message")
-  private onMessage() {
-    // ...
-  }
-
-  @Once("messageDelete")
-  private onMessageDelete() {
-    // ...
-  }
-}
-```
-
-### Client payload injection
-For each event a list of arguments is injected in your decorated method, you can type this list thanks to the `ArgsOf<Event>` type provided by `discord.ts`.
-You also receive other useful arguments after that:
-1. The event payload (`ArgsOf<Event>`)
-2. The `Client` instance
-3. The [guards](https://github.com/OwenCalvin/discord.ts#%EF%B8%8F-guards) payload
-
-> You should use JS desctructuring for `ArgsOf<Event>` like in this example
-```typescript
-import {
-  Discord,
-  On,
-  Client,
-  ArgsOf
-} from "@typeit/discord";
-
-@Discord()
-abstract class AppDiscord {
-  @On("message")
-  private onMessage(
-    [message]: ArgsOf<"message">, // Type message automatically
-    client: Client, // Client instance injected here,
-    guardPayload: any
-  ) {
-    // ...
-  }
-}
-```
-
-## 📟 Commands
-`discord.ts` provides a decorator allowing the implementation of command systems very simply by essentially using only two decorators `@Command(commandName?: string)` and `@CommandNotFound()`.
-
-We will also use `@Discord(prefix: string)` to specify a prefix for our commands within the class.
-
-**You can specify a `regex` expression for your command names**  
-**For advanced usage use the `@Rules` decorator, you can also specify aliases using that**
-
-> Notice that the first arguments do not use `ArgsOf`, the first payload is a `CommandMessage`.
-```typescript
-import {
-  Discord,
-  On,
-  Client,
-  Command,
-  CommandMessage,
-  CommandNotFound
-} from "@typeit/discord";
-
-// Specify your prefix
-@Discord("!") 
-abstract class AppDiscord {
-  // Reachable with the command: !hello
-  @Command("hello")
-  private hello(message: CommandMessage) {
-  }
-
-  // !bye
-  // !yo
-  @CommandNotFound()
-  private notFound(message: CommandMessage) {
-  }
-}
-```
-
-### The `CommandMessage` object
-The `CommandMessage` is the first argument injected into a method using `@Command` or `@CommandNotFound`, it has exactly the same structure as the `Message` object in `discord.js` except that it includes useful information about the command that was executed such as:  
-- `prefix`: `string`   
-The prefix that is applied to your command.
-
-- `commandName`: `string`  
-The command name
-
-- `commandContent`: `string`  
-The message content without the prefix (`-cmd hello there` becomes `hello there`)
-
-- `description`: `string`  
-[The command description](https://github.com/OwenCalvin/discord.ts#infos--description)
-
-- `infos`: `InfoType` (`any`)  
-[The command infos](https://github.com/OwenCalvin/discord.ts#infos--description)  
-
-- `args`: `ArgsType` (`any`)  
-[The command arguments](https://github.com/OwenCalvin/discord.ts#args-parsing)  
-
-- `discord`: `DiscordInfos`:  
-The linked `@Discord` class infos
-
-- `argsRules`: (`ArgsRulesFunction<Expression>[]`)  
-The rules that are applied to execute the command (advanced)
-
-### Args parsing
-You have the ability to specify arguments for your command, as `express.js` does in it's routing system. So by using `":"` (or the value specified in `variablesChar` when your `Client` intializes) in the name of your `@Command` in front of the dynamic values, `discord.ts` will extract these informations when a command is executed and inject it into the `args` property of your `CommandMessage` with the correct name that you indicated in the command name.
-
-> If the argument value is a number the value will be casted automaticaly
-```typescript
-@Discord("!")
-abstract class AppDiscord {
-  @Command("args :slug :number")
-  private hello(message: CommandMessage) {
-    const mySlug = message.args.slug;
-    const myNumber = message.args.number;
-
-    // Using js destructuring:
-    const { slug, number } = message.args; 
-  }
-}
-```
-
-### Dynamic Values
-Okay but what if my prefix or my command name of my `@Discord` / `@Command` decorators depends on external datas? Well you can specify a function that will be executed when a command is executed to verify the origin and return the correct value.  
-
-You receive the `Message` as the first argument and the `Client` instance as the second one.
-
-> This is also applied to `@ComputedRules`
-
-```typescript
-// If the message has been sent in the guild with
-// the name MyGuildName the prefix "." will be considered
-// otherwise the prefix "$" will trigger the action.
-async function prefixBehaviour(message: Message, client: Client) {
-  if (message.guild.name === "MyGuildName") {
-    return ".";
-  }
-  return "$";
-}
-
-@Discord(prefixBehaviour)
-abstract class AppDiscord {
-  @Command("hello")
-  private hello(message: CommandMessage) {
-    // ...
-  }
-}
-```
-
-With a dynamic command name:
-> May be for a very specific use case
-```typescript
-// If the message has been sent in the guild with
-// the name MyGuildName the prefix "." will be considered
-// otherwise the prefix "$" will trigger the action.
-async function prefixBehaviour(message: Message, client: Client) {
-  if (message.guild.name === "MyGuildName") {
-    return ".";
-  }
-  return "$";
-}
-
-// The command name will be yo if the message is "hello"
-async function commandName(message: Message, client: Client) {
-  if (message.content === "hello") {
-    return "yo";
-  }
-  return "hello";
-}
-
-
-@Discord(prefixBehaviour)
-abstract class AppDiscord {
-  @Command(commandName)
-  private hello(message: CommandMessage) {
-    // ...
-  }
-}
-```
-
-### Command directory pattern
-> [Example](https://github.com/OwenCalvin/discord.ts/tree/master/examples/commands-dir)  
-
-If you have a directory pattern that looks like this:
-```sh
-Main.ts
-DiscordApp.ts
-commands
-- Ping.ts
-- Hello.ts
-- Blabla.ts
-events
-- MessageDelete.ts
-```
-
-You should use the `import` parameter for the `@Discord` decorator.
-Here, all the elements will be injected into this Discord class instance.
-```typescript
-import * as Path from "path";
-import {
-  Discord,
-  CommandNotFound
-} from "@typeit/discord";
-
-// The prefix will be applied to the imported commands
-@Discord("!", {
-  import: [
-    Path.join(__dirname,  "commands", "*.ts"),
-    Path.join(__dirname,  "events", "*.ts")
-    // You can also specify the class directly here if you don't want to use a glob
-  ]
-})
-export abstract class DiscordApp {
-  // This command not found is triggered
-  @CommandNotFound()
-  notFoundA(command: CommandMessage) {
-    command.reply("Command not found");
-  }
-}
-```
-
-Here is an example of what your command file should look like:
-*Bye.ts*
-```typescript
-import {
-  Command,
-  CommandMessage
-} from "@typeit/discord";
-
-// Do not have to decorate the class with @Discord
-// It applied the parameters of the @Discord decorator that imported it
-export abstract class Bye {
-  @Command("bye")
-  async bye(command: CommandMessage) {
-    command.reply("Bye!");
-  }
-
-  @Command("ciao")
-  async ciao(command: CommandMessage) {
-    command.reply("Ciao!");
-  }
-}
-```
-
-*MessageDelete.ts*
-```typescript
-import {
-  On,
-  ArgsOf
-} from "@typeit/discord";
-
-// Do not have to decorate the class with @Discord
-// It applied the parameters of the @Discord decorator that imported it
-export abstract class MessageDelete {
-  @On("messageDelete")
-  async onMessageDelete([message]: ArgsOf<"messageDelete">) {
-    message.reply("Bye!");
-  }
-}
-```
-
-## ℹ️ @Infos / @Description
-It would be useful to be able to specify order information, for example to display a help command (`!help`) in your application.
-For the one you have two useful decorators which are `@Infos` and `@Description`.
-
-> `@Description` is a shortcut for `@Infos({ description: "..." })`
-```typescript
-import {
-  ClassCommand,
-  Command,
-  CommandMessage
-} from "@typeit/discord";
-
-@Discord("!")
-@Description("Admin commands")
-@Infos({ forAdmins: true })
-export abstract class Bye {
-  @Command("ciao")
-  @Description("say ciao")
-  async ciao(command: CommandMessage) {
-    command.reply("Ciao!");
-  }
-}
-```
-
-To retrieve these informations, you can use the `Client` static methods:  
-```typescript
-import { Client } from "@typeit/discord";
-
-Client.getCommands();         // @Command
-Client.getCommandsNotFound(); // @CommandNotFound
-Client.getEvents();           // @On
-Client.getDiscords();         // @Discord
-```
-
-## @Rules / @ComputedRules - Advanced message validation
-If you need to use advanced expressions and aliases for your commands, this decorator is for you. It accepts regex (if you specify a string it will be considered as a regex expression, you have to escape the `"."` => `"\."` characters) and an instance of [RuleBuilder](https://github.com/OwenCalvin/discord.ts#rulebuilder).
-
-```typescript
-import {
-  ClassCommand,
-  Command,
-  CommandMessage,
-  Rules
-} from "@typeit/discord";
-
-@Discord("!")
-export abstract class Bye {
-  @Command()
-  @Rules(/salut\s{1,}toi(\s{1,}|$)/i)
-  async hello(command: CommandMessage) {
-    command.reply("Ciao!");
-  }
-}
-```
-
-The rules can also be applied to `@Discord`, it will be merged to the rules of commands inside the class:
-> In this example we rewrite explicitly the prefix rule
-```typescript
-import {
-  ClassCommand,
-  Command,
-  CommandMessage,
-  Rules,
-  Rule
-} from "@typeit/discord";
-
-@Discord()
-@Rules(Rule().startWith("!")) // Explicit prefix
-export abstract class Bye {
-  @Rules(Rule("salut").space("toi").spaceOrEnd())
-  async hello(command: CommandMessage) {
-    command.reply("Ciao!");
-  }
-}
-```
-
-### RuleBuilder
-But it's not clear to put a RegExp... 
-Yes for this reason you can use the `RuleBuilder` API:  
-Now to write `/salut\s{1,}toi(\s{1,}|$)/i` it's simple:
-
-```typescript
-import {
-  ClassCommand,
-  Command,
-  CommandMessage,
-  Rules,
-  Rule
-} from "@typeit/discord";
-
-@Discord("!")
-export abstract class Bye {
-  @Rules(Rule("salut").space("toi").spaceOrEnd())
-  async hello(command: CommandMessage) {
-    command.reply("Ciao!");
-  }
-}
-```
-
-### Computed rules
-Okay but I have rules that depends on computed my server datas like for my `@CommandName`...
-No problem just use `@ComputedRules`:
-```typescript
-import {
-  ClassCommand,
-  Command,
-  CommandMessage,
-  Rules,
-  Rule
-} from "@typeit/discord";
-
-async function getRules() {
-  return [Rule("salut").space("toi").spaceOrEnd()]
-}
-
-@Discord("!")
-export abstract class Bye {
-  @ComputedRules(getRules)
-  async hello(command: CommandMessage) {
-    command.reply("Ciao!");
-  }
-}
-```
-
-## ⚔️ Guards
-You can use functions that are executed before your event to determine if it's executed. For example, if you want to apply a prefix to the messages, you can simply use the `@Guard` decorator.  
-
-The order of execution of the guards is done according to their position in the list, so they will be executed in order (from top to bottom).  
-
-Guards works also with `@Command` and `@CommandNotFound`.  
-
-```typescript
-import {
-  Discord,
-  On,
-  Client,
-  Guard
-} from "@typeit/discord";
-import { NotBot } from "./NotBot";
-import { Prefix } from "./Prefix";
-
-@Discord()
-abstract class AppDiscord {
-  @On("message")
-  @Guard(
-    NotBot, // You can use multiple guard functions, they are excuted in the same order!
-    Prefix("!")
-  )
-  async onMessage([message]: ArgsOf<"message">) {
-    switch (message.content.toLowerCase()) {
-      case "hello":
-        message.reply("Hello!");
-        break;
-      default:
-        message.reply("Command not found");
-        break;
-    }
-  }
-}
-```
-
-### The guard functions
-> Notice that the guard function is impacted by your payloadInjection policy  
-
-Here is a simple example of a guard function (the payload and the client instance are injected like for events)  
-Guards work like `Koa`'s, it's a function passed in parameter (after the `Client`'s instance) and you will have to call if the guard is passed.
-> If next isn't called the next guard (or the main method) will not be executed
-```typescript
-import { GuardFunction } from "@typeit/discord";
-
-export const NotBot: GuardFunction<"message"> = (
-  [message],
-  client,
-  next
-) => {
-  if (client.user.id !== message.author.id) {
-    await next();
-  }
-}
-```
-
-If you have to indicate parameters for a guard function you can simple use the "function that returns a function" pattern like this:
-```typescript
-import { GuardFunction } from "@typeit/discord";
-
-export function Prefix(text: string, replace: boolean = true) {
-  const guard: GuardFunction<"message"> = (
-    [message],
-    client,
-    next
-  ) => {
-    const startWith = message.content.startsWith(text);
-    if (replace) {
-      message.content = message.content.replace(text, "");
-    }
-    if (startWith) {
-      await next();
-    }
-  };
-
-  return guard;
-}
-```
-
-### Guard datas
-As 4th parameter you receive a basic empty object that can be used to transmit data between guard and with your main method.
-```typescript
-import { GuardFunction } from "@typeit/discord";
-
-export const NotBot: GuardFunction<"message"> = (
-  [message],
-  client,
-  next,
-  guardDatas
-) => {
-  if (client.user.id !== message.author.id) {
-    guardDatas.message = "the NotBot guard passed"
-    await next();
-  }
-}
-```
-```typescript
-import {
-  Discord,
-  Command,
-  Client,
-  Guard
-} from "@typeit/discord";
-import { NotBot } from "./NotBot";
-import { Prefix } from "./Prefix";
-
-@Discord()
-abstract class AppDiscord {
-  @Command()
-  @Guard(
-    NotBot,
-    Prefix("!")
-  )
-  async hello(
-    command: CommandMessage,
-    client: Client,
-    guardDatas: any
-  ) {
-    console.log(guardDatas.message);
-    // > the NotBot guard passed 
-  }
-}
-```
-
-## API - Retrieve the infos
-You can simply get all the infos about your decorated stuff using:
-
-```typescript
-import { Client } from "@typeit/discord";
-
-Client.getCommands();         // @Command
-Client.getCommandsNotFound(); // @CommandNotFound
-Client.getEvents();           // @On
-Client.getDiscords();         // @Discord
-```
-
-## 💡 Events and payload
-Here you have the details about the payloads that are injected into the method related to a specific event.
-Note that on some events, for example voiceStateUpdate, it will return an array of the subsequent event payloads, and the second parameter will be the discord.ts Client.
-**`@Once(event: DiscordEvent)` exists too, it executes the method only one time**
-
-### The argument list
-Here is all the `DiscordEvents` and their parameters (`discord.js` version 12.2.0)
-- **channelCreate**: `(Channel)`
-- **channelDelete**: `(Channel | PartialDMChannel)`
-- **channelPinsUpdate**: `(Channel | PartialDMChannel, Date)`
-- **channelUpdate**: `(Channel, Channel)`
-- **debug**: `(string)`
-- **warn**: `(string)`
-- **disconnect**: `(any, number)`
-- **emojiCreate**: `(GuildEmoji)`
-- **emojiDelete**: `(GuildEmoji)`
-- **emojiUpdate**: `(GuildEmoji, GuildEmoji)`
-- **error**: `(Error)`
-- **guildBanAdd**: `(Guild, User | PartialUser)`
-- **guildBanRemove**: `(Guild, User | PartialUser)`
-- **guildCreate**: `(Guild)`
-- **guildDelete**: `(Guild)`
-- **guildUnavailable**: `(Guild)`
-- **guildIntegrationsUpdate**: `(Guild)`
-- **guildMemberAdd**: `(GuildMember | PartialGuildMember)`
-- **guildMemberAvailable**: `(GuildMember | PartialGuildMember)`
-- **guildMemberRemove**: `(GuildMember | PartialGuildMember)`
-- **guildMembersChunk**: `(Collection<Snowflake, GuildMember | PartialGuildMember>, Guild)`
-- **guildMemberSpeaking**: `(GuildMember | PartialGuildMember, Readonly<Speaking>)`
-- **guildMemberUpdate**: `(GuildMember | PartialGuildMember, GuildMember | PartialGuildMember)`
-- **guildUpdate**: `(Guild, Guild)`
-- **inviteCreate**: `(Invite)`
-- **inviteDelete**: `(Invite)`
-- **message**: `(Message)`
-- **messageDelete**: `(Message | PartialMessage)`
-- **messageReactionRemoveAll**: `(Message | PartialMessage)`
-- **messageReactionRemoveEmoji**: `(MessageReaction)`
-- **messageDeleteBulk**: `(Collection<Snowflake, Message | PartialMessage>)`
-- **messageReactionAdd**: `(MessageReaction, User | PartialUser)`
-- **messageReactionRemove**: `(MessageReaction, User | PartialUser)`
-- **messageUpdate**: `(Message | PartialMessage, Message | PartialMessage)`
-- **presenceUpdate**: `(Presence | undefined, Presence)`
-- **rateLimit**: `(RateLimitData)`
-- **ready**: `()`
-- **invalidated**: `()`
-- **roleCreate**: `(Role)`
-- **roleDelete**: `(Role)`
-- **roleUpdate**: `(Role, Role)`
-- **typingStart**: `(Channel | PartialDMChannel, User | PartialUser)`
-- **userUpdate**: `(User | PartialUser, User | PartialUser)`
-- **voiceStateUpdate**: `(VoiceState, VoiceState)`
-- **webhookUpdate**: `(TextChannel)`
-- **shardDisconnect**: `(CloseEvent, number)`
-- **shardError**: `(Error, number)`
-- **shardReady**: `(number)`
-- **shardReconnecting**: `(number)`
-- **shardResume**: `(number, number)`
-
-## Examples
-Some examples are provided in the [`/examples` folder](https://github.com/OwenCalvin/discord.ts/tree/master/examples) !
-
-## Migration v1 to v2
-You should just add parenthesis after the `@Discord` decorator, everywhere in your app.  
-`@Discord class X` should now be `@Discord() class X`.
-
-## Migration v2 to v3
-Now the `payloadInjection` policy is by default `"first"`, convert each events of your app or change your `payloadInjection` policy to `"spread"` inside the `Client` constructor:  
-```typescript
-const client = new Client({
-  payloadInjection: "spread"
-})
-```
-
-## Migration v3 to v4
-payloadInjection policy doesn't exists anymore, moreover the parameters inside the decorators has changed, please refer to the documentation or ask help using the discord server.
 
-## See also
-- [discord.js](https://discord.js.org/#/)