Гайд Создание Discord-бота с использованием C# и библиотеки Discord.net

Пользователь
Статус
Оффлайн
Регистрация
25 Июл 2018
Сообщения
150
Реакции[?]
48
Поинты[?]
0
Приветствую вас, дорогие любители читов на каэсгоу. В сегодняшнем гайде я покажу как создать своего Discord-бота, используя C# и библиотеку Discord.net.

1. Установленная Visual Studio с набором для разработки классических .NET приложений
2. Доступ к интернету
3. Компьютер
4. Клавиатура
5, Компьютерная мышь
6. Монитор
7. [Желательно] Небольшой опыт работы с Visual Studio 2022/2019/2017 и C#
Прежде всего нам нужен сам бот, к которому мы будем подключаться

1. Переходим на
Пожалуйста, авторизуйтесь для просмотра ссылки.


2. Даём имя будущему боту и создаём приложение

3. В новом окне довольно много всего, в чём вы можете самостоятельно разобраться. Нас же интересует "OAuth2" и "Bot"

4. Переходим в "Bot" и по нажатию кнопку в правой части экрана создаём самого бота

5. В новом окне включаем эти две галочки

1630081115239.png

а также в "Bot Permissions" снизу выбираем "Administrator"

6. Теперь переходим в "OAuth2", ставим галочки "Bot" и "Administrator" и копируем ссылку для приглашения бота

7. Переходим по этой ссылке и добавляем бота на сервер. Поздравляю! На данный момент у нас есть бот, который всегда в оффлайне и ничего не делает. Давайте его оживим
Создаём консольное приложение .NET Core (кроссплатформенное, не .NET Framework). Думаю тут справится каждый, но если надо могу сделать гайд по установке Visual Studio и созданию проекта в ней.
Отлично! Теперь нам нужно установить необходимые пакеты для работы с библиотекой Discord.net. Клацаем правой кнопкой мыши по нашему проекту и ищем NuGet

В открывшемся окне устанавливаем Discord.Addons.Hosting. Discord.Net, Discord.Net.Core, Discord.Net.WebSocket, Discord.Net.Commands и Microsoft.Extensions.DependencyInjection, Microsoft.Extensions.Logging, Microsoft.Extensions.Hosting, Microsoft.Extensions.Configuration
1630081423196.png
Переходим в главный файл Program.cs
Для начала изменим наш код на этот:

C#:
        static async Task Main()
        {
            var builder = new HostBuilder()
                .ConfigureAppConfiguration(x =>
                {
                    var config = new ConfigurationBuilder()
                        .SetBasePath(Directory.GetCurrentDirectory())
                        .AddJsonFile("config.json", false, true)
                        .Build();

                    x.AddConfiguration(config);
                })
                .ConfigureLogging(x =>
                {
                    x.AddConsole();
                    x.SetMinimumLevel(LogLevel.Debug); // вместо Debug можно поставить другие уровни, но в нашем случае это самый оптимальный вариант
                })
                .ConfigureDiscordHost((context, config) =>
                {
                    config.SocketConfig = new DiscordSocketConfig
                    {
                        LogLevel = LogSeverity.Debug,
                        AlwaysDownloadUsers = false,
                        MessageCacheSize = 200
                    };

                    config.Token = context.Configuration["token"];
                })
                .UseCommandService((context, config) =>
                {
                    config.CaseSensitiveCommands = false;
                    config.LogLevel = LogSeverity.Debug;
                    config.DefaultRunMode = RunMode.Async;
                })
                .ConfigureServices((context, services) =>
                {
                    // чуть позже мы это раскоментируем
                    //services
                    //    .AddHostedService<CommandHandler>();
                })
                // думаю тут понятно
                .UseConsoleLifetime();


            var host = builder.Build();
            using (host)
            {
                // запускаем бота
                await host.RunAsync();
            }
        }
(НАВЕДИТЕСЬ НА ОШИБКУ ЕСЛИ ОНА ВОЗНИКАЕТ - СКОРЕЕ ВСЕГО ВЫ ПРОСТО НЕ ПОДКЛЮЧИЛИ В USING'АХ БИБЛИОТЕКИ, КОТОРЫЕ МЫ УСТАНАВЛИВАЛИ В НАЧАЛЕ ГАЙДА)

Но не спешите это запускать. Теперь нам нужно добавить файл конфигурации config.json, а также обработчик команд и сами команды.
Кликаем правой кнопкой мыши по проекту и создаём json файл и пишем в нем это:

JavaScript:
{
  "token": "ВАШ ТОКЕН",
  "prefix":  "!"
}
Чтобы получить токен переходим
Пожалуйста, авторизуйтесь для просмотра ссылки.

во вкладку "Bot" и нажимаем Copy. Вставляем его вместо "ВАШ ТОКЕН"

ВАЖНО! Клацаем по config.json (или как вы его там назвали) и переходим, в моем случае. в Properties. В открывшемся окне ставим вместо Do not copy -> Copy if newer

Теперь с помощью CTRL+F5 можно запустить нашего бота и он будет онлайн в дискорде до тех пор, пока вы не закроете приложение
В CommandHandler.cs:

C#:
public class CommandHandler : InitializedService
{
        private readonly IServiceProvider _provider;
        private readonly DiscordSocketClient _client;
        private readonly CommandService _service;
        private readonly IConfiguration _config;

        public CommandHandler(IServiceProvider provider, DiscordSocketClient client, CommandService service, IConfiguration config)
        {
            _provider = provider;
            _client = client;
            _service = service;
            _config = config;
        }

        public override async Task InitializeAsync(CancellationToken cancellationToken)
        {
            _client.MessageReceived += OnMessageRecevied;
            _service.CommandExecuted += OnCommandExecuted;
            await _service.AddModulesAsync(Assembly.GetEntryAssembly(), _provider);
        }

        private async Task OnCommandExecuted(Optional<CommandInfo> commandInfo, ICommandContext commandContext, IResult result)
        {
            if (result.IsSuccess)
            {
                return;
            }

            await commandContext.Channel.SendMessageAsync(result.ErrorReason);
        }

        private async Task OnMessageRecevied(SocketMessage socketMsg)
        {
            if (!(socketMsg is SocketUserMessage message)) return;
            if (message.Source != MessageSource.User) return;

            var argPos = 0;
            if (!message.HasStringPrefix(_config["prefix"], ref argPos) && !message.HasMentionPrefix(_client.CurrentUser, ref argPos)) return;

            var context = new SocketCommandContext(_client, message);
            await _service.ExecuteAsync(context, argPos, _provider);
        }
}
Наш бот теперь может обрабатывать команды, почти готово! Осталось лишь добавить файл с командами. Опять же для удобства создадим папку Modules и добавим в нее файл класса General.cs
Кстати, раскоментируем-ка кое-что в Program.cs:

C#:
                .ConfigureServices((context, services) =>
                {
                    services
                        .AddHostedService<CommandHandler>();
                })
В General.cs:
C#:
public class General : ModuleBase<SocketCommandContext>
{

}
Класс и всё необходимое создано, как же добавить команды?
Создадим команду, которая повторяет сообщение пользователя:

C#:
    public class General : ModuleBase<SocketCommandContext>
    {
        [Command("echo")]
        private async Task Echo(string msg)
        {
            await Context.Channel.SendMessageAsync(msg);
        }
    }
Или что-нибудь поинтереснее, например, вывод информации о пользователе:

C#:
        [Command("info")]
        private async Task Info(SocketGuildUser socketGuildUser = null)
        {
            if (socketGuildUser == null)
            {
                var embed = new EmbedBuilder()
                    .WithColor(Color.Orange)
                    .WithTitle(Context.User.Username)
                    .WithImageUrl(Context.User.GetAvatarUrl())
                    .AddField("User ID:", Context.User.Id, true)
                    .AddField("Created at", Context.User.CreatedAt, true);

                await Context.Channel.SendMessageAsync(embed: embed.Build());
            }
            else
            {
                var embed = new EmbedBuilder()
                    .WithColor(Color.Orange)
                    .WithTitle(socketGuildUser.Username)
                    .WithImageUrl(socketGuildUser.GetAvatarUrl())
                    .AddField("User ID:", socketGuildUser.Id, true)
                    .AddField("Created at:", socketGuildUser.CreatedAt, true);

                await Context.Channel.SendMessageAsync(embed: embed.Build());
            }
        }
1630081476155.png
На этом пока что всё. Подробнее о командах, методах и всём можно узнать просто покопавшись в коде или в
Пожалуйста, авторизуйтесь для просмотра ссылки.
Пожалуйста, авторизуйтесь для просмотра ссылки.

Пожалуйста, авторизуйтесь для просмотра ссылки.
 
Последнее редактирование:
Начинающий
Статус
Оффлайн
Регистрация
8 Фев 2021
Сообщения
19
Реакции[?]
14
Поинты[?]
0
Чел, как же ты вовремя с этим постом:hearteyes:
Буквально пару дней назад хотел изучить эту тему. Спасибо за материал
 
пупс, поцелуй
Участник
Статус
Оффлайн
Регистрация
28 Май 2019
Сообщения
1,052
Реакции[?]
322
Поинты[?]
14K
Крута, модна, полезна, молодежна :CoolCat:
 
Последнее редактирование:
Пользователь
Статус
Оффлайн
Регистрация
25 Июл 2018
Сообщения
150
Реакции[?]
48
Поинты[?]
0
Чтобы получить токен переходим
Пожалуйста, авторизуйтесь для просмотра ссылки.

во вкладку "Bot" и нажимаем Copy. Вставляем его вместо "ВАШ ТОКЕН"
ВАЖНО! Клацаем по config.json (или как вы его там назвали) и переходим, в моем случае. в Properties. В открывшемся окне ставим вместо Do not copy -> Copy if newer
Теперь с помощью CTRL+F5 можно запустить нашего бота и он будет онлайн в дискорде до тех пор, пока вы не закроете приложение
Newer —> Never
так там именно newer, а не never
 
пупс, поцелуй
Участник
Статус
Оффлайн
Регистрация
28 Май 2019
Сообщения
1,052
Реакции[?]
322
Поинты[?]
14K
Новичок
Статус
Оффлайн
Регистрация
1 Янв 2020
Сообщения
2
Реакции[?]
0
Поинты[?]
0
Ты все бибилиотеки подключил?
Discord.Addons.Hosting последней версии поставить не получилось, пишет что не поддерживается.
Установил 3.0.0 или 3.1.0, не помню. Ничего не изменилось. Просто удалил это и все заработало. (Бот в онлайне, на команды отвечает)
 
Новичок
Статус
Оффлайн
Регистрация
14 Ноя 2021
Сообщения
1
Реакции[?]
0
Поинты[?]
0
когда нажимаю ctrl+f5 то не получается его одивить, все равно оффлайн
 
Новичок
Статус
Оффлайн
Регистрация
23 Май 2022
Сообщения
1
Реакции[?]
0
Поинты[?]
0
Здравствуйте, я вроде бы все нугеты подключила, но у меня черкает красным и не предлагает подключить никакой юзинг
Пожалуйста, авторизуйтесь для просмотра ссылки.

Также черкает в наследовании - public class CommandHandler : InitializedService (предлагает создать новый класс и не предлагает подключить юзинги)
Тема очень старая, но возможно кто то прочитает и сможет мне помочь, заранее спасибо
 
Новичок
Статус
Оффлайн
Регистрация
22 Июн 2017
Сообщения
1
Реакции[?]
0
Поинты[?]
0
Здравствуйте, я вроде бы все нугеты подключила, но у меня черкает красным и не предлагает подключить никакой юзинг
Пожалуйста, авторизуйтесь для просмотра ссылки.

Также черкает в наследовании - public class CommandHandler : InitializedService (предлагает создать новый класс и не предлагает подключить юзинги)
Тема очень старая, но возможно кто то прочитает и сможет мне помочь, заранее спасибо
Просто нужно использовать все библиотеки
Лично я сделал так, но бот при запуске кода все равно в онлайн не переходит почему то.


using System;
using System.Reflection;
using System.Security.Permissions;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.DependencyInjection;
using Discord.Net;
using Discord;
using Discord.Addons.Hosting;
using Discord.WebSocket;
using Discord.Commands;
 
Последнее редактирование:
Новичок
Статус
Оффлайн
Регистрация
10 Фев 2022
Сообщения
1
Реакции[?]
0
Поинты[?]
0
Здравствуйте, я вроде бы все нугеты подключила, но у меня черкает красным и не предлагает подключить никакой юзинг
Пожалуйста, авторизуйтесь для просмотра ссылки.

Также черкает в наследовании - public class CommandHandler : InitializedService (предлагает создать новый класс и не предлагает подключить юзинги)
Тема очень старая, но возможно кто то прочитает и сможет мне помочь, заранее спасибо
Пожалуйста, авторизуйтесь для просмотра ссылки.
 
Новичок
Статус
Оффлайн
Регистрация
27 Июн 2022
Сообщения
1
Реакции[?]
0
Поинты[?]
0
Здравствуйте, я вроде бы все нугеты подключила, но у меня черкает красным и не предлагает подключить никакой юзинг
Пожалуйста, авторизуйтесь для просмотра ссылки.

Также черкает в наследовании - public class CommandHandler : InitializedService (предлагает создать новый класс и не предлагает подключить юзинги)
Тема очень старая, но возможно кто то прочитает и сможет мне помочь, заранее спасибо
InitializedService больше не поддерживается в новой версии Discord.Addons.Hosting. Вместо него используйте DiscordClientService. См:
Пожалуйста, авторизуйтесь для просмотра ссылки.
 
Начинающий
Статус
Оффлайн
Регистрация
25 Июн 2022
Сообщения
3
Реакции[?]
0
Поинты[?]
0
Отличный гайд. Но вот в консоли при написании любой команды вижу это:

Error code:
fail: Discord.Commands.CommandService[0]
      Command:
      Discord.Commands.CommandException: Error occurred executing "info" for ?MyNick?#8766 in This discord server/talk.
       ---> Discord.Net.HttpException: The server responded with error 401: 401: Unauthorized
         at Discord.Net.Queue.RequestBucket.SendAsync(RestRequest request)
         at Discord.Net.Queue.RequestQueue.SendAsync(RestRequest request)
         at Discord.API.DiscordRestApiClient.SendInternalAsync(String method, String endpoint, RestRequest request)
         at Discord.API.DiscordRestApiClient.SendJsonAsync[TResponse](String method, String endpoint, Object payload, BucketId bucketId, ClientBucketType clientBucket, RequestOptions options)
         at Discord.API.DiscordRestApiClient.CreateMessageAsync(UInt64 channelId, CreateMessageParams args, RequestOptions options)
         at Discord.Rest.ChannelHelper.SendMessageAsync(IMessageChannel channel, BaseDiscordClient client, String text, Boolean isTTS, Embed embed, AllowedMentions allowedMentions, MessageReference messageReference, MessageComponent components, ISticker[] stickers, RequestOptions options, Embed[] embeds, MessageFlags flags)
         at Support_0._0._1.Modules.General.Info(SocketGuildUser socketGuildUser) in B:\Support 0.0.1\Support 0.0.1\Support 0.0.1\Modules\General.cs:line 31
         at Discord.Commands.ModuleClassBuilder.<>c__DisplayClass6_0.<<BuildCommand>g__ExecuteCallback|0>d.MoveNext()
      --- End of stack trace from previous location ---
         at Discord.Commands.CommandInfo.ExecuteInternalAsync(ICommandContext context, Object[] args, IServiceProvider services)
         --- End of inner exception stack trace ---
dbug: Discord.Commands.CommandService[0]
      Command: Executed "info" for ?MyNick?#8766 in This discord server/talk
В основном ссылается на await Context.Channel.SendMessageAsync(embed: embed.Build());
С токеном всё в порядке.
 
Последнее редактирование:
Начинающий
Статус
Оффлайн
Регистрация
19 Янв 2023
Сообщения
3
Реакции[?]
0
Поинты[?]
0
Помогите пж , перерыскал везде но не нашел .core конльное приложение у меня на английском языке _Console App (.Net Core)
 
Сверху Снизу