Раздел навигации

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

Добро пожаловать!

Зарегистрировавшись у нас, вы сможете обсуждать, делиться и отправлять личные сообщения другим участникам нашего сообщества.

Зарегистрироваться!
  • Если Вы желаете помогать развитию проекта, готовы заполнять раздел(-ы) и подсказывать другим пользователям на портале, есть возможность попасть в команду редакторов. Для этого следует обратиться в техническую поддержку
Активный
Пользователь
Регистрация
22 Май 2022
Сообщения
11
Приветствую вас. В сегодняшнем гайде я покажу как создать своего Discord-бота, используя C# и библиотеку Discord.net.

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

Прежде всего нам нужен сам бот, к которому мы будем подключаться

1. Переходим на https://discord.com/developers/applications

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

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

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

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

1653195577581.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
1653195637365.png

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#:

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());
            }
        }
1653196100008.png

На этом пока что всё. Подробнее о командах, методах и всём можно узнать просто покопавшись в коде или в документации

 
.NET software developer
Пользователь
Регистрация
20 Мар 2022
Сообщения
76
Создаём консольное приложение .NET Core (кроссплатформенное, не .NET Framework)
Почему именно .NET Core? Можно и новенький .NET, хоть .NET Standard использовать. Более того, Discord.NET больше нацелен под .NET 5-ой и 6-ой версии, потому использовать лучше .NET, да и новее он. Лично я пишу бота на .NET 5.

И еще, желательно комментировать если не каждую функцию, то большинство из библиотеки, всё таки это в виде урока.

Кстати, по поводу бонуса, еще можно приложить официальный Discord-сервер, на котором можно задавать вопросы: https://discord.com/invite/dnet
P.S. спрашивать придется на английском языке, "Ни слова по-русски".
 
Активный
Пользователь
Регистрация
22 Май 2022
Сообщения
11
Почему именно .NET Core? Можно и новенький .NET, хоть .NET Standard использовать. Более того, Discord.NET больше нацелен под .NET 5-ой и 6-ой версии, потому использовать лучше .NET, да и новее он. Лично я пишу бота на .NET 5.

И еще, желательно комментировать если не каждую функцию, то большинство из библиотеки, всё таки это в виде урока.

Кстати, по поводу бонуса, еще можно приложить официальный Discord-сервер, на котором можно задавать вопросы: https://discord.com/invite/dnet
P.S. спрашивать придется на английском языке, "Ни слова по-русски".
Привет, старая версия бота, а так да согласен
 
Сверху