Improve library documentation (#826)

* Improve the Command Service documentation

The following changes have been added to this PR:
•	Fix minor grammatical errors.
•	Capitalize terms such as Commands, Modules and such, as the context is specific to the lib.
•	Wrap methods and properties in code blocks.

The docs page currently has several issues that remains to be fixed.

1. 
```md
>[!WARNING]
>This article is out of date and has not been rewritten yet.
Information is not guaranteed to be accurate.
```

The docs doesn't necessarily seem "out of date" as the warning claims. The basics seem pretty relevant to the latest version of the lib.

2.
>“To manually load a module, invoke [CommandService.AddModuleAsync], by passing in the generic type of your module and optionally, a dependency map.”

The latter part of the sentence seems off. Where should the user pass the dependency map to? It seems to suggest that `AddModuleAsync` has an argument to pass the dependency to. If it is referring to `AddModuleAsync(Type type)`, then I feel like it should be clarified here - or perhaps change the wording of the sentence.

3.
>“First, you need to create an @System.IServiceProvider You may create your own IServiceProvider if you wish.” 

Any mention of @System.IServiceProvider is currently broken on the docs.

4.
>“Submodules are Modules that reside within another one. Typically, submodules are used to create nested groups (although not required to create nested groups).”

Clarification on the part after "although?"

5.
>“Finally, pass the map into the LoadAssembly method. Your modules will automatically be loaded with this dependency map.”

Where is this `LoadAssembly` method?

6.
```md
>[!NOTE]
>Preconditions can be applied to Modules, Groups, or Commands.
```

The docs should mention `ParameterPreconditionAttribute`'s existence.

* Update line breaks to comply with docs standard

* Change "you should..." to "instead, ..."

* Trim trailing spaces

* Change "inherits" to "inherit"

* Fix Context warning note and add ReplyAsync xref

* Fix broken xrefs

* Fix [Command Service] xref

* Fix consistency between TypeReaders and Preconditions returns

* Add missing semi-colons in ServiceProvider sample

* Change CommandContext to SocketCommandContext & change variable naming

* Cleanup TypeReader section

* Wrap [DontInject] in code block

* Fix commands docs linking in intro

* Improve Getting Started - Installation

- Fix character misalignment to comply with docs standard.
- Fix image numbering issues by moving the tooltips above some of the steps.
- Add codeblocks to search terms like `Discord.Net`.
- Remove broken `addons` reference.
- Specify `.NET 4.6.1` as `.NET Framework 4.6.1`.
- Minor cross-reference cleanup.

* Fix Getting Started - Intro

- Minor grammartical fixes.
- Wrap mentions of the methods, properties, and events in code block.
- Replace `Discord.Net` to `Discord.NET`.
- Fix steps numbering under `Creating a Discord Bot` and `Adding your bot to a server`.
- Change `Task-based Asynchronous Pattern ([TAP])` linking to mark the entire term instead.
- Change code block of `Pong!` to quotation mark instead.

* Fix cross references in Sending Voice

* Mention parameter precondition attribute

* Change `Discord.NET` to `Discord.Net` for consistency

* Wrap project names in code blocks & minor fixes in Terminology

* Change `add-ons` to `addons` for consistency

* Fix cross references in Logging

* Fix minor grammatical issues in "Working with Events"

* Missed a tilda

* Remove out-of-date warning in Commands

* Minor grammatical fixes for Entities

* Fix broken xref in Logging

* Adjust service collection sample

...according to f89aecb7bf (r141530227)

* Update Command Handler sample

- Update Main for C# 7.1.
- Inject CommandService and DiscordSocketClient into the service collection.
- Add Async suffix to asynchronous methods.

* Minor grammatical fixes in Events

* Revert 2 incorrect grammar corrections

* Revert async Main sample

* Add hardcode token notice in sample

* Fix missing method for Command Handler

* Modify module samples to use SocketCommandContext instead

* Emphasize CommandContext and SocketCommandContext

* Fix formatting for module sample

* Add SocketCommandContext for Groups sample

* Remove comma

* Fix DepMap sample formatting

* Replace [DontInject] with DontInjectAttribute with cross reference

* Remove connection logic note

There is no reason that this note should still be here since Ready event exists.

* Add a new warning message informing the users the existence of CommandService

* Make command handler private

excellent change
This commit is contained in:
Hsu Still
2017-10-04 04:48:05 +08:00
committed by Christopher F
parent e00f17fe55
commit 22d79c1004
14 changed files with 393 additions and 340 deletions

View File

@@ -2,84 +2,87 @@
title: Installing Discord.Net
---
Discord.Net is distributed through the NuGet package manager, and it is
recommended to use NuGet to get started.
Discord.Net is distributed through the NuGet package manager, and it
is recommended to use NuGet to get started.
Optionally, you may compile from source and install yourself.
# Supported Platforms
Currently, Discord.Net targets [.NET Standard] 1.3, and offers support for
.NET Standard 1.1. If your application will be targeting .NET Standard 1.1,
please see the [additional steps](#installing-on-net-standard-11).
Currently, Discord.Net targets [.NET Standard] 1.3 and offers support
for .NET Standard 1.1. If your application will be targeting .NET
Standard 1.1, please see the [additional steps].
Since Discord.Net is built on the .NET Standard, it is also recommended to
create applications using [.NET Core], though you are not required to. When
using .NET Framework, it is suggested to target `.NET 4.6.1` or higher.
Since Discord.Net is built on the .NET Standard, it is also
recommended to create applications using [.NET Core], though not
required. When using .NET Framework, it is suggested to target
`.NET Framework 4.6.1` or higher.
[.NET Standard]: https://docs.microsoft.com/en-us/dotnet/articles/standard/library
[.NET Core]: https://docs.microsoft.com/en-us/dotnet/articles/core/
[additional steps]: #installing-on-net-standard-11
# Installing with NuGet
Release builds of Discord.Net 1.0 will be published to the
[official NuGet feed].
Development builds of Discord.Net 1.0, as well as [addons](TODO) are published
to our development [MyGet feed].
Development builds of Discord.Net 1.0, as well as addons *(TODO)* are
published to our development [MyGet feed].
Direct feed link: `https://www.myget.org/F/discord-net/api/v3/index.json`
Not sure how to add a direct feed? See how [with Visual Studio]
or [without Visual Studio](#configuring-nuget-without-visual-studio)
Not sure how to add a direct feed? See how [with Visual Studio] or
[without Visual Studio].
[official NuGet feed]: https://nuget.org
[MyGet feed]: https://www.myget.org/feed/Packages/discord-net
[with Visual Studio]: https://docs.microsoft.com/en-us/nuget/tools/package-manager-ui#package-sources
[without Visual Studio]: #configuring-nuget-without-visual-studio
## Using Visual Studio
1. Create a solution for your bot
2. In Solution Explorer, find the 'Dependencies' element under your bot's
project
3. Right click on 'Dependencies', and select 'Manage NuGet packages'
![Step 3](images/install-vs-deps.png)
4. In the 'browse' tab, search for 'Discord.Net'
> [!TIP]
Don't forget to change your package source if you're installing from the
developer feed.
Also make sure to check 'Enable Prereleases' if installing a dev build!
5. Install the 'Discord.Net' package
>Don't forget to change your package source if you're installing from
the developer feed.
>Also make sure to check "Enable Prereleases" if installing a dev
build!
1. Create a solution for your bot.
2. In Solution Explorer, find the "Dependencies" element under your
bot's project.
3. Right click on "Dependencies", and select "Manage NuGet packages."
![Step 3](images/install-vs-deps.png)
4. In the "Browse" tab, search for `Discord.Net`.
5. Install the `Discord.Net` package.
![Step 5](images/install-vs-nuget.png)
## Using JetBrains Rider
1. Create a new solution for your bot
2. Open the NuGet window (Tools > NuGet > Manage NuGet packages for Solution)
![Step 2](images/install-rider-nuget-manager.png)
3. In the 'Packages' tab, search for 'Discord.Net'
![Step 3](images/install-rider-search.png)
> [!TIP]
Make sure to check the 'Prerelease' box if installing a dev build!
Make sure to check the "Prerelease" box if installing a dev build!
4. Install by adding the package to your project
1. Create a new solution for your bot.
2. Open the NuGet window (Tools > NuGet > Manage NuGet packages for
Solution).
![Step 2](images/install-rider-nuget-manager.png)
3. In the "Packages" tab, search for `Discord.Net`.
![Step 3](images/install-rider-search.png)
4. Install by adding the package to your project.
![Step 4](images/install-rider-add.png)
## Using Visual Studio Code
1. Create a new project for your bot
2. Add Discord.Net to your .csproj
> [!TIP]
Don't forget to add the package source to a [NuGet.Config file] if
you're installing from the developer feed.
1. Create a new project for your bot.
2. Add `Discord.Net` to your .csproj.
[!code-xml[Sample .csproj](samples/project.csproj)]
> [!TIP]
Don't forget to add the package source to a [NuGet.Config file](#configuring-nuget-without-visual-studio) if you're installing from the
developer feed.
[NuGet.Config file]: #configuring-nuget-without-visual-studio
# Compiling from Source
@@ -90,8 +93,8 @@ In order to compile Discord.Net, you require the following:
- [Visual Studio 2017](https://www.visualstudio.com/)
- [.NET Core SDK 1.0](https://www.microsoft.com/net/download/core#/sdk)
The .NET Core and Docker (Preview) workload is required during Visual Studio
installation.
The .NET Core and Docker (Preview) workload is required during Visual
Studio installation.
### Using Command Line
@@ -101,26 +104,27 @@ installation.
## Installing on .NET Standard 1.1
For applications targeting a runtime corresponding with .NET Standard 1.1 or 1.2,
the builtin WebSocket and UDP provider will not work. For applications which
utilize a WebSocket connection to Discord (WebSocket or RPC), third-party
provider packages will need to be installed and configured.
For applications targeting a runtime corresponding with .NET Standard
1.1 or 1.2, the builtin WebSocket and UDP provider will not work. For
applications which utilize a WebSocket connection to Discord
(WebSocket or RPC), third-party provider packages will need to be
installed and configured.
First, install the following packages through NuGet, or compile yourself, if
you prefer:
First, install the following packages through NuGet, or compile
yourself, if you prefer:
- Discord.Net.Providers.WS4Net
- Discord.Net.Providers.UDPClient
Note that `Discord.Net.Providers.UDPClient` is _only_ required if your bot will
be utilizing voice chat.
Note that `Discord.Net.Providers.UDPClient` is _only_ required if your
bot will be utilizing voice chat.
Next, you will need to configure your [DiscordSocketClient] to use these custom
providers over the default ones.
Next, you will need to configure your [DiscordSocketClient] to use
these custom providers over the default ones.
To do this, set the `WebSocketProvider` and optionally `UdpSocketProvider`
properties on the [DiscordSocketConfig] that you are passing into your
client.
To do this, set the `WebSocketProvider` and the optional
`UdpSocketProvider` properties on the [DiscordSocketConfig] that you
are passing into your client.
[!code-csharp[NET Standard 1.1 Example](samples/netstd11.cs)]
@@ -129,13 +133,14 @@ client.
## Configuring NuGet without Visual Studio
If you plan on deploying your bot or developing outside of Visual Studio, you
will need to create a local NuGet configuration file for your project.
If you plan on deploying your bot or developing outside of Visual
Studio, you will need to create a local NuGet configuration file for
your project.
To do this, create a file named `nuget.config` alongside the root of your
application, where the project solution is located.
To do this, create a file named `nuget.config` alongside the root of
your application, where the project solution is located.
Paste the following snippets into this configuration file, adding any additional
feeds as necessary.
Paste the following snippets into this configuration file, adding any
additional feeds as necessary.
[!code-xml[NuGet Configuration](samples/nuget.config)]

View File

@@ -13,42 +13,46 @@ diverse commands later, but for now, it is a good starting point.
Before you can begin writing your bot, it is necessary to create a bot
account on Discord.
1. Visit the [Discord Applications Portal]
2. Create a New Application
1. Visit the [Discord Applications Portal].
2. Create a New Application.
3. Give the application a name (this will be the bot's initial
username).
4. Create the Application
![Step 4](images/intro-create-app.png)
5. In the application review page, click **Create a Bot User**
![Step 5](images/intro-create-bot.png)
6. Confirm the popup
7. If this bot will be public, check 'Public Bot'.
**Do not tick any other options!**
4. Create the Application.
![Step 4](images/intro-create-app.png)
5. In the application review page, click **Create a Bot User**.
![Step 5](images/intro-create-bot.png)
6. Confirm the popup.
7. If this bot will be public, check "Public Bot." **Do not tick any
other options!**
[Discord Applications Portal]: https://discordapp.com/developers/applications/me
## Adding your bot to a server
Bots **can not** use invite links, they must be explicitly invited
Bots **cannot** use invite links, they must be explicitly invited
through the OAuth2 flow.
1. Open your bot's application on the [Discord Applications Portal]
1. Open your bot's application on the [Discord Applications Portal].
2. Retrieve the app's **Client ID**.
![Step 2](images/intro-client-id.png)
![Step 2](images/intro-client-id.png)
3. Create an OAuth2 authorization URL
`https://discordapp.com/oauth2/authorize?client_id=<CLIENT ID>&scope=bot`
4. Open the authorization URL in your browser
5. Select a server
4. Open the authorization URL in your browser.
5. Select a server.
6. Click on authorize.
>[!NOTE]
Only servers where you have the `MANAGE_SERVER` permission will be
present in this list.
![Step 6](images/intro-add-bot.png)
>[!NOTE]
Only servers where you have the `MANAGE_SERVER` permission will be
present in this list.
6. Click authorize
![Step 6](images/intro-add-bot.png)
## Connecting to Discord
@@ -57,10 +61,10 @@ do that now. (see the [Installing](installing.md) section)
### Async
Discord.Net uses .NET's Task-based Asynchronous Pattern ([TAP])
Discord.Net uses .NET's [Task-based Asynchronous Pattern (TAP)]
extensively - nearly every operation is asynchronous.
It is highly recommended that these operations be awaited in a
It is highly recommended that these operations are awaited in a
properly established async context whenever possible. Establishing an
async context can be problematic, but not hard.
@@ -70,27 +74,29 @@ async main.
[!code-csharp[Async Context](samples/intro/async-context.cs)]
As a result of this, your program will now start, and immidiately
jump into an async context. This will allow us later on to create a
connection to Discord, without needing to worry about setting up the
As a result of this, your program will now start and immidiately
jump into an async context. This will allow us to create a connection
to Discord later on without needing to worry about setting up the
correct async implementation.
>[!TIP]
If your application throws any exceptions within an async context,
they will be thrown all the way back up to the first non-async method.
Since our first non-async method is the program's Main method, this
they will be thrown all the way back up to the first non-async method;
since our first non-async method is the program's `Main` method, this
means that **all** unhandled exceptions will be thrown up there, which
will crash your application. Discord.Net will prevent exceptions in
event handlers from crashing your program, but any exceptions in your
async main **will** cause the application to crash.
[Task-based Asynchronous Pattern (TAP)]: https://docs.microsoft.com/en-us/dotnet/articles/csharp/async
### Creating a logging method
Before we create and configure a Discord client, we will add a method
to handle Discord.Net's log events.
To allow agnostic support of as many log providers as possible, we
log information through a Log event, with a proprietary LogMessage
log information through a `Log` event with a proprietary `LogMessage`
parameter. See the [API Documentation] for this event.
If you are using your own logging framework, this is where you would
@@ -99,10 +105,12 @@ the Console.
[!code-csharp[Async Context](samples/intro/logging.cs)]
[API Documentation]: xref:Discord.Rest.BaseDiscordClient#Discord_Rest_BaseDiscordClient_Log
### Creating a Discord Client
Finally, we can create a connection to Discord. Since we are writing
a bot, we will be using a [DiscordSocketClient], along with socket
a bot, we will be using a [DiscordSocketClient] along with socket
entities. See the [terminology](terminology.md) if you're unsure of
the differences.
@@ -110,22 +118,24 @@ To do so, create an instance of [DiscordSocketClient] in your async
main, passing in a configuration object only if necessary. For most
users, the default will work fine.
Before connecting, we should hook the client's log event to the
Before connecting, we should hook the client's `Log` event to the
log handler that was just created. Events in Discord.Net work
similarly to other events in C#, so hook this event the way that
you typically would.
Next, you will need to 'login to Discord' with the `LoginAsync` method.
Next, you will need to "login to Discord" with the `LoginAsync`
method.
You may create a variable to hold your bot's token (this can be found
on your bot's application page on the [Discord Applications Portal]).
![Token](images/intro-token.png)
>[!IMPORTANT]
Your bot's token can be used to gain total access to your bot, so
**do __NOT__ share this token with anyone!** It may behoove you to
store this token in an external file if you plan on distributing the
source code for your bot.
**do __NOT__ share this token with anyone else!** It may behoove you
to store this token in an external file if you plan on distributing
the source code for your bot.
We may now invoke the client's `StartAsync` method, which will
start connection/reconnection logic. It is important to note that
@@ -134,14 +144,9 @@ start connection/reconnection logic. It is important to note that
Any methods that rely on the client's state should go in an event
handler.
>[!NOTE]
Connection logic is incomplete as of the current build. Events will
soon be added to indicate when the client's state is ready for use;
(rewrite this section when possible)
Finally, we will want to block the async main method from returning
until after the application is exited. To do this, we can await an
infinite delay, or any other blocking method, such as reading from
infinite delay or any other blocking method, such as reading from
the console.
The following lines can now be added:
@@ -154,51 +159,55 @@ online in Discord.
>[!TIP]
Encountering a `PlatformNotSupportedException` when starting your bot?
This means that you are targeting a platform where .NET's default
WebSocket client is not supported. Refer to the [installing guide]
WebSocket client is not supported. Refer to the [installation guide]
for how to fix this.
[TAP]: https://docs.microsoft.com/en-us/dotnet/articles/csharp/async
[API Documentation]: xref:Discord.Rest.BaseDiscordClient#Discord_Rest_BaseDiscordClient_Log
[DiscordSocketClient]: xref:Discord.WebSocket.DiscordSocketClient
[installing guide]: installing.md#installing-on-net-standard-11
[installation guide]: installing.md#installing-on-net-standard-11
### Handling a 'ping'
>[!WARNING]
Please note that this is *not* a proper way to create a command.
Use the `CommandService` provided by the library instead, as explained
in the [Command Guide] section.
Now that we have learned how to open a connection to Discord, we can
begin handling messages that users are sending.
To start out, our bot will listen for any message where the content
is equal to `!ping`, and respond back with `Pong!`.
is equal to `!ping` and respond back with "Pong!".
Since we want to listen for new messages, the event to hook in to
Since we want to listen for new messages, the event to hook into
is [MessageReceived].
In your program, add a method that matches the signature of the
MessageReceived event - it must be a method (`Func`) that returns the
type `Task`, and takes a single parameter, a [SocketMessage]. Also,
`MessageReceived` event - it must be a method (`Func`) that returns
the type `Task` and takes a single parameter, a [SocketMessage]. Also,
since we will be sending data to Discord in this method, we will flag
it as `async`.
In this method, we will add an `if` block, to determine if the message
In this method, we will add an `if` block to determine if the message
content fits the rules of our scenario - recall that it must be equal
to `!ping`.
Inside the branch of this condition, we will want to send a message
back to the channel from which the message came - `Pong!`. To find the
channel, look for the `Channel` property on the message parameter.
back to the channel from which the message comes from - "Pong!". To
find the channel, look for the `Channel` property on the message
parameter.
Next, we will want to send a message to this channel. Since the
channel object is of type [SocketMessageChannel], we can invoke the
`SendMessageAsync` instance method. For the message content, send back
a string containing 'Pong!'.
a string containing "Pong!".
You should have now added the following lines:
[!code-csharp[Message](samples/intro/message.cs)]
Now, your first bot is complete. You may continue to add on to this
if you desire, but for any bot that will be carrying out multiple
commands, it is strongly encouraged to use the command framework, as
Now your first bot is complete. You may continue to add on to this
if you desire, but for any bots that will be carrying out multiple
commands, it is strongly recommended to use the command framework as
shown below.
For your reference, you may view the [completed program].
@@ -207,13 +216,14 @@ For your reference, you may view the [completed program].
[SocketMessage]: xref:Discord.WebSocket.SocketMessage
[SocketMessageChannel]: xref:Discord.WebSocket.ISocketMessageChannel
[completed program]: samples/intro/complete.cs
[Command Guide]: ../commands/commands.md
# Building a bot with commands
This section will show you how to write a program that is ready for
[commands](commands/commands.md). Note that this will not be explaining _how_
to write commands or services, it will only be covering the general
structure.
[Commands](../commands/commands.md). Note that we will not be
explaining _how_ to write Commands or Services, it will only be
covering the general structure.
For reference, view an [annotated example] of this structure.
@@ -224,4 +234,4 @@ should be to separate the program (initialization and command handler),
the modules (handle commands), and the services (persistent storage,
pure functions, data manipulation).
**todo:** diagram of bot structure
**todo:** diagram of bot structure

View File

@@ -7,32 +7,34 @@ title: Terminology
## Preface
Most terms for objects remain the same between 0.9 and 1.0. The major difference is that the ``Server`` is now called ``Guild``, to stay in line with Discord internally
Most terms for objects remain the same between 0.9 and 1.0. The major
difference is that the ``Server`` is now called ``Guild`` to stay in
line with Discord internally.
## Implementation Specific Entities
Discord.Net 1.0 is split into a core library, and three different
implementations - Discord.Net.Core, Discord.Net.Rest, Discord.Net.Rpc,
and Discord.Net.WebSockets.
Discord.Net 1.0 is split into a core library and three different
implementations - `Discord.Net.Core`, `Discord.Net.Rest`,
`Discord.Net.Rpc`, and `Discord.Net.WebSockets`.
As a bot developer, you will only need to use Discord.Net.WebSockets,
As a bot developer, you will only need to use `Discord.Net.WebSockets`,
but you should be aware of the differences between them.
`Discord.Net.Core` provides a set of interfaces that model Discord's
`Discord.Net.Core` provides a set of interfaces that models Discord's
API. These interfaces are consistent throughout all implementations of
Discord.Net, and if you are writing an implementation-agnostic library
or addon, you can rely on the core interfaces to ensure that your
addon will run on all platforms.
`Discord.Net.Rest` provides a set of concrete classes to be used
**strictly** with the REST portion of Discord's API. Entities in
this implementation are prefixed with `Rest`, e.g. `RestChannel`.
**strictly** with the REST portion of Discord's API. Entities in this
implementation are prefixed with `Rest` (e.g. `RestChannel`).
`Discord.Net.Rpc` provides a set of concrete classes that are used with
Discord's RPC API. Entities in this implementation are prefixed with
`Rpc`, e.g. `RpcChannel`.
`Discord.Net.Rpc` provides a set of concrete classes that are used
with Discord's RPC API. Entities in this implementation are prefixed
with `Rpc` (e.g. `RpcChannel`).
`Discord.Net.WebSocket` provides a set of concrete classes that are used
primarily with Discord's WebSocket API, or entities that are kept in
cache. When developing bots, you will be using this implementation. All
entities are prefixed with `Socket`, e.g. `SocketChannel`.
`Discord.Net.WebSocket` provides a set of concrete classes that are
used primarily with Discord's WebSocket API or entities that are kept
in cache. When developing bots, you will be using this implementation.
All entities are prefixed with `Socket` (e.g. `SocketChannel`).