Browse Source

More conenet added to the README file

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

+ 1262 - 4
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.
 
@@ -66,8 +66,8 @@ Your tsconfig.json should look like this:
 ```
 
 ### Setup and start your application
-In order to start your application, you must use the `discord.`**`ts`**'s `Client` (not the client that is provided by `discord.`**`js`**!).  
-It works the same as the `discord.js`**'s `Client` (same methods, properties, ...).
+**#### NB ####**  To start your application, you must use the `discord.ts`'s Client and not the client that is provided by `discord.js.  
+It works the same as the `discord.js`'s `Client` (same methods, properties, ...).
 
 You have different parameters in addition to discord.js when you initialize your `Client`:
 - **`classes` (required)**:  
@@ -102,7 +102,1265 @@ 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/#/)
+
 
 
 ## Deploying the Bot
-This is also for whomever takes step three of the bounty.
+This is also for whomever takes step three of the bounty.bounty.