From b8104483fa311990818da727380fad001ca605b7 Mon Sep 17 00:00:00 2001 From: GRZ4NA Date: Wed, 23 Jun 2021 18:46:32 +0200 Subject: [PATCH] README.md --- README.md | 165 ++++++++++++++++++++++++++++++++++++++- assets/error_example.png | Bin 0 -> 16831 bytes 2 files changed, 164 insertions(+), 1 deletion(-) create mode 100644 assets/error_example.png diff --git a/README.md b/README.md index 3efa70f..cb0e3cc 100644 --- a/README.md +++ b/README.md @@ -1 +1,164 @@ -# DiscordCommands \ No newline at end of file +# DiscordCommands +**1.0.0** + +Discord.js wrapper that helps you build your own Discord bot. + +Key features +- command system +- auto-generated help command +- command permissions + +## Table of contents +- [Getting started](#getting-started) + + [Installation](#installation) + + [Creating bot instance](#creating-bot-instance) +- [Commands](#commands) + + [All parameters](#all-parameters) + + [Command function](#command-function) + * [Arguments](#arguments) + * [Return](#return) + * [Errors](#errors) + + [Command examples](#command-examples) + * [Simple reply](#simple-reply) + * [Arguments example](#arguments-example) + +## Getting started +### Installation +1. Install this package using npm +``` +npm install discordcommands@latest +``` + +2. Add the following entry to your *package.json* file +```json +"type": "module" +``` + +3. Import the package +```javascript +import { Bot, Command } from 'discordcommands' +``` +### Creating bot instance +```javascript +const bot = new Bot({ + name: "Command bot", // Name of your bot + prefix: "!", // Prefix used to call commands + argumentSeparator: "," // Used to get arguments from message + helpCommand: true, // Enable or disable the *help* command (optional) + clientOptions: undefined, // Instance of ClientOptions from Discord.js + token: "" // Bot token from Discord Developer Portal (optional, you can pass the token in *start* method) +}); +``` + +Start your bot using +```javascript +bot.start(); +``` +Optional arguments for this method +- **port** - *number* - if specified, the app will create a http server that will be listening on the specified port +- **token** - *string* - app token from Discord Developer Portal +## Commands +> [!IMPORTANT] +> All commands have to be declared above the *start* method +### All parameters +- name - *string* - command name (used to trigger the command) +- function - *Function* - function that will trigger when the commands gets called +- visible - *boolean* - show command in the *help message* (optional, defaults to *true*) +- description - *string* - command description shown in the *help message* (optional) +- usage - *string* - command usage description shown in the *help message* (optional) +- permissions - *[PermissionResolvable](https://discord.js.org/#/docs/main/stable/typedef/PermissionResolvable)* - permissions needed to run the command (optional) +- aliases - *string | string[]* - other words that can trigger the command with prefix (optional) +- keywords - *string | string[]* - other words that can trigger the command without prefix (optional) +### Command function +#### Arguments +- m - *[Message](https://discord.js.org/#/docs/main/stable/class/Message)* - a message object instance containing message content, author and additional informations +- a - *string[]* - list of arguments passed with the message (separated with *argumentSeparator*) +#### Return +If command function returns +- *string* - the returned text will be sent as a reply to the command caller +- *[MessageEmbed](https://discord.js.org/#/docs/main/stable/class/MessageEmbed)* - the embedded content will be sent as a standalone message +#### Errors +If your command throws an error, it will get logged to the console and sent to the user in a message with embedded content. **The bot will not crash.** + +:::image type="content" source="assets/error_example.png" alt-text="Error message example"::: + +### Command examples +#### Simple reply +1. Create a command +```javascript +//CREATE COMMAND +const command = new Command({ + name: "ping", + function: (m, a) => { + return 'pong'; + } +}); +//APPEND IT TO THE COMMANDS LIST +bot.commands.add(command); +``` +or +```javascript +bot.commands.add(new Command({ + name: "ping", + function: (m, a) => { + return 'pong'; + } +})); +``` +2. Call it from Discord text channel (example prefix: "!") +```javascript +!ping // replies "pong" with the user mention +``` +#### Arguments example +1. Create a command +```javascript +const command = new Command({ + name: "repeat", + function: async (m, a) => { + if(a[0] && a[1]) { + const count = parseInt(a[1]); + if(!isNaN(count)) { + for(let i = 0; i < count; i++) { + await m.channel.send(a[0]); + } + return `Repeated "${a[0]}" ${count} times`; + } + else { + throw new Error('Number of messages is incorrect'); + } + } + } +}) +``` +or +```javascript +bot.commands.add(new Command({ + name: "repeat", + function: async (m, a) => { + if(a[0] && a[1]) { + const count = parseInt(a[1]); + if(!isNaN(count)) { + for(let i = 0; i < count; i++) { + await m.channel.send(a[0]); + } + return `Repeated "${a[0]}" ${count} times`; + } + else { + throw new Error('Number of messages is incorrect'); + } + } + } +})); +``` +2. Call it from Discord text channel (example prefix: "!", example separator: "," [default]) +``` +!repeat test, 5 + +Result: +test +test +test +test +test +@caller, Repeated "test" 5 times +``` \ No newline at end of file diff --git a/assets/error_example.png b/assets/error_example.png new file mode 100644 index 0000000000000000000000000000000000000000..b4dd674ca12e8917af9fff25a349f9356c05802c GIT binary patch literal 16831 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