You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

first-bot.md 9.1 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248
  1. ---
  2. uid: Guides.GettingStarted.FirstBot
  3. title: Start making a bot
  4. ---
  5. # Making a Ping-Pong bot
  6. One of ways to get started with the Discord API is to write a basic
  7. ping-pong bot. This bot will respond to a simple command "ping."
  8. We will expand on this to create more diverse commands later, but for
  9. now, it is a good starting point.
  10. ## Creating a Discord Bot
  11. Before writing your bot, it is necessary to create a bot account via the
  12. Discord Applications Portal first.
  13. 1. Visit the [Discord Applications Portal].
  14. 2. Create a New Application.
  15. 3. Give the application a name (this will be the bot's initial username).
  16. 4. Create the Application.
  17. ![Step 4](images/intro-create-app.png)
  18. 5. In the application review page, click **Create a Bot User**.
  19. ![Step 5](images/intro-create-bot.png)
  20. 6. Confirm the popup.
  21. 7. If this bot will be public, check "Public Bot." **Do not tick any
  22. other options!**
  23. [Discord Applications Portal]: https://discordapp.com/developers/applications/me
  24. ## Adding your bot to a server
  25. Bots **cannot** use invite links; they must be explicitly invited
  26. through the OAuth2 flow.
  27. 1. Open your bot's application on the [Discord Applications Portal].
  28. 2. Retrieve the application's **Client ID**.
  29. ![Step 2](images/intro-client-id.png)
  30. 3. Create an OAuth2 authorization URL
  31. - `https://discordapp.com/oauth2/authorize?client_id=<CLIENT ID>&scope=bot`
  32. 4. Open the authorization URL in your browser.
  33. 5. Select a server.
  34. 6. Click on authorize.
  35. > [!NOTE]
  36. > Only servers where you have the `MANAGE_SERVER` permission will be
  37. > present in this list.
  38. ![Step 6](images/intro-add-bot.png)
  39. ## Connecting to Discord
  40. If you have not already created a project and installed Discord.Net,
  41. do that now.
  42. For more information, see @Guides.GettingStarted.Installation.
  43. ### Async
  44. Discord.Net uses .NET's [Task-based Asynchronous Pattern (TAP)]
  45. extensively - nearly every operation is asynchronous. It is highly
  46. recommended that these operations are awaited in a
  47. properly established async context whenever possible.
  48. To establish an async context, we will be creating an async main method
  49. in your console application, and rewriting the static main method to
  50. invoke the new async main.
  51. [!code-csharp[Async Context](samples/first-bot/async-context.cs)]
  52. As a result of this, your program will now start and immediately
  53. jump into an async context. This will allow us to create a connection
  54. to Discord later on without having to worry about setting up the
  55. correct async implementation.
  56. > [!WARNING]
  57. > If your application throws any exceptions within an async context,
  58. > they will be thrown all the way back up to the first non-async method;
  59. > since our first non-async method is the program's `Main` method, this
  60. > means that **all** unhandled exceptions will be thrown up there, which
  61. > will crash your application.
  62. >
  63. > Discord.Net will prevent exceptions in event handlers from crashing
  64. > your program, but any exceptions in your async main **will** cause
  65. > the application to crash.
  66. [Task-based Asynchronous Pattern (TAP)]: https://docs.microsoft.com/en-us/dotnet/articles/csharp/async
  67. ### Creating a logging method
  68. Before we create and configure a Discord client, we will add a method
  69. to handle Discord.Net's log events.
  70. To allow agnostic support of as many log providers as possible, we
  71. log information through a `Log` event with a proprietary `LogMessage`
  72. parameter. See the [API Documentation] for this event.
  73. If you are using your own logging framework, this is where you would
  74. invoke it. For the sake of simplicity, we will only be logging to
  75. the console.
  76. You may learn more about this concept in @Guides.Concepts.Logging.
  77. [!code-csharp[Async Context](samples/first-bot/logging.cs)]
  78. [API Documentation]: xref:Discord.Rest.BaseDiscordClient.Log
  79. ### Creating a Discord Client
  80. Finally, we can create a new connection to Discord.
  81. Since we are writing a bot, we will be using a [DiscordSocketClient]
  82. along with socket entities. See @Guides.GettingStarted.Terminology
  83. if you are unsure of the differences.
  84. To establish a new connection, we will create an instance of
  85. [DiscordSocketClient] in the new async main. You may pass in an
  86. optional @Discord.WebSocket.DiscordSocketConfig if necessary. For most
  87. users, the default will work fine.
  88. Before connecting, we should hook the client's `Log` event to the
  89. log handler that we had just created. Events in Discord.Net work
  90. similarly to any other events in C#.
  91. Next, you will need to "login to Discord" with the [LoginAsync]
  92. method with the application's "token."
  93. > [!NOTE]
  94. > Pay attention to what you are copying from the developer portal!
  95. > A token is not the same as the application's "client secret."
  96. ![Token](images/intro-token.png)
  97. > [!IMPORTANT]
  98. > Your bot's token can be used to gain total access to your bot, so
  99. > **do __NOT__ share this token with anyone else!** It may behoove you
  100. > to store this token in an external source if you plan on distributing
  101. > the source code for your bot.
  102. We may now invoke the client's [StartAsync] method, which will
  103. start connection/reconnection logic. It is important to note that
  104. **this method will return as soon as connection logic has been started!**
  105. Any methods that rely on the client's state should go in an event
  106. handler. This means that you should **not** directly be interacting with
  107. the client before it is fully ready.
  108. Finally, we will want to block the async main method from returning
  109. when running the application. To do this, we can await an infinite delay
  110. or any other blocking method, such as reading from the console.
  111. The following lines can now be added:
  112. [!code-csharp[Create client](samples/first-bot/client.cs)]
  113. At this point, feel free to start your program and see your bot come
  114. online in Discord.
  115. > [!TIP]
  116. > Encountering a `PlatformNotSupportedException` when starting your bot?
  117. > This means that you are targeting a platform where .NET's default
  118. > WebSocket client is not supported. Refer to the [installation guide]
  119. > for how to fix this.
  120. [DiscordSocketClient]: xref:Discord.WebSocket.DiscordSocketClient
  121. [LoginAsync]: xref:Discord.Rest.BaseDiscordClient.LoginAsync*
  122. [StartAsync]: xref:Discord.WebSocket.DiscordSocketClient.StartAsync*
  123. [installation guide]: xref:Guides.GettingStarted.Installation#installing-on-net-standard-11
  124. ### Handling a 'ping'
  125. > [!WARNING]
  126. > Please note that this is *not* a proper way to create a command.
  127. > Use the `CommandService` provided by the library instead, as explained
  128. > in the [Command Guide](xref:Guides.Commands.Intro) section.
  129. Now that we have learned to open a connection to Discord, we can
  130. begin handling messages that the users are sending. To start out, our
  131. bot will listen for any message whose content is equal to `!ping` and
  132. will respond back with "Pong!".
  133. Since we want to listen for new messages, the event to hook into
  134. is [MessageReceived].
  135. In your program, add a method that matches the signature of the
  136. `MessageReceived` event - it must be a method (`Func`) that returns
  137. the type `Task` and takes a single parameter, a [SocketMessage]. Also,
  138. since we will be sending data to Discord in this method, we will flag
  139. it as `async`.
  140. In this method, we will add an `if` block to determine if the message
  141. content fits the rules of our scenario - recall that it must be equal
  142. to `!ping`.
  143. Inside the branch of this condition, we will want to send a message,
  144. `Pong!`, back to the channel from which the message comes from. To
  145. find the channel, look for the `Channel` property on the message
  146. parameter.
  147. Next, we will want to send a message to this channel. Since the
  148. channel object is of type [ISocketMessageChannel], we can invoke the
  149. [SendMessageAsync] instance method. For the message content, send back
  150. a string, "Pong!".
  151. You should have now added the following lines,
  152. [!code-csharp[Message](samples/first-bot/message.cs)]
  153. Now that your first bot is complete. You may continue to add on to this
  154. if you desire, but for any bots that will be carrying out multiple
  155. commands, it is strongly recommended to use the command framework as
  156. shown below.
  157. > [!NOTE]
  158. > For your reference, you may view the [completed program].
  159. [MessageReceived]: xref:Discord.WebSocket.BaseSocketClient.MessageReceived
  160. [SocketMessage]: xref:Discord.WebSocket.SocketMessage
  161. [ISocketMessageChannel]: xref:Discord.WebSocket.ISocketMessageChannel
  162. [SendMessageAsync]: xref:Discord.WebSocket.ISocketMessageChannel.SendMessageAsync*
  163. [completed program]: samples/first-bot/complete.cs
  164. # Building a bot with commands
  165. @Guides.Commands.Intro will guide you through how to setup a program
  166. that is ready for [CommandService], a service that is ready for
  167. advanced command usage.
  168. For reference, view an [annotated example] of this structure.
  169. [annotated example]: samples/first-bot/structure.cs
  170. It is important to know that the recommended design pattern of bots
  171. should be to separate...
  172. 1. the program (initialization and command handler)
  173. 2. the modules (handle commands)
  174. 3. the services (persistent storage, pure functions, data manipulation)
  175. [CommandService]: xref:Discord.Commands.CommandService