Створення Discord - бота на .NET Core з деплоєм на VPS-сервер
Привіт, Хабровчани!
Сьогодні ви ознайомитеся зі статтею, в якій буде розказано, як створити бота, використовуючи C# на .NET Core, та про те, як його завести на віддаленому сервері.
Стаття складатиметься з передісторії, підготовчого етапу, написання логіки та перенесення бота на віддалений сервер.
Сподіваюся, ця стаття допоможе багатьом початківцям.
Передісторія
Все почалося однієї безсонної осінньої ночі, яку я проводив на Discord - сервері. Так як я відносно недавно до нього приєднався, я почав його вивчати вздовж і впоперек. Виявивши текстовий канал «Вакансії», я зацікавився, відкрив його, і відшукав серед пропозицій, що мене не цікавлять, це:
«Програміст (розробник робота) вимоги:
знання мов програмування;
здатність до самонавчання.
побажання:
вміння розумітися на чужому коді;
знання функціоналу DISCORD.
завдання:
розробка робота;
підтримка та супровід роботи бота.
Ваша вигода:
Можливість підтримати і вплинути на проект, що сподобався;
Набуття досвіду роботи у команді;
Можливість продемонструвати та покращити наявні навички.»
Це миттєво мене зацікавило. Так, за цю роботу не платили, але від тебе жодних зобов'язань не вимагали, та й у портфоліо зайвим не буде. Тому я написав адміну сервера, і він попросив написати бота, який показуватиме статистику гравця у World of Tanks.
Підготовчий етап
Дискрод
Перш ніж приступити до написання нашого бота, його необхідно створити для Discord. Вам необхідно:
Заходимо в «Мої програми» та натискаємо на кнопку «Додати новий додаток», надавши ім'я програми та вибравши його тип
Зберігаємо ID програми
Софтвер
Тут вже є свобода вибору. Хтось використовує Visual Studio, хтось Rider, хтось взагалі потужний, і пише код у Vim (все ж таки справжні програмісти використовують тільки клавіатуру, вірно?). Однак, щоб не реалізовувати Discord API, можна використовувати неофіційну бібліотеку для C# "DSharpPlus". Його можна встановити з NuGet, або самому зібравши вихідники з репозиторію.
Для тих, хто не знає, або забув, як встановити програми з NuGet.Інструкція для Visual Studio
Переходимо у вкладку Проект - Управління пакетами NuGet;
Натискаємо на огляд та у полі пошуку вводимо “DSharpPlus”;
Вибираємо та встановлюємо framework;
PROFIT!
Підготовчий етап закінчено, можна переходити до написання робота.
Написання логіки
Всю логіку програми розглядати не будемо, я лише покажу, як працювати з перехопленням повідомлень ботом, і як працювати з Wargaming API.
Робота з Discord бот відбувається через функцію static async Task MainTask (string [] args);
Щоб викликати цю функцію, в Main необхідно прописати
Де token – токен вашого робота.
Потім, через лямбду, прописуємо необхідні команди, які має виконувати бот:
discord.MessageCreated += async e =>
{
string message = e.Message.Content;
if (message.StartsWith("&"))
{
await e.Message.RespondAsync(“Hello, ” + e.Author.Username);
}
};
Де e.Author.Username – отримання нікнейму користувача.
Таким чином, коли ви відправите будь-яке повідомлення, яке починається з &, бот буде вітати вас.
В кінці цієї функції необхідно прописати await discord.ConnectAsync(); та await Task.Delay(-1);
Це дозволить виконувати команди на фоні, не займаючи основного потоку.
Тепер потрібно розібратися з Wargaming API. Тут все просто - пишете CURL-запити, отримуєте відповідь у вигляді JSON - рядки, витягуєте звідти необхідні дані та робите над ними маніпуляції.
Приклад роботи з WargamingAPI
public Player FindPlayer(string searchNickname)
{
//https://api.worldoftanks.ru/wot/account/list/?application_id=y0ur_a@@_id_h3r3search=nickname
urlRequest = resourceMan.GetString("url_find_player") + appID + "&search=" + searchNickname;
Player player = null;
string resultResponse = GetResponse(urlRequest);
dynamic parsed = JsonConvert.DeserializeObject(resultResponse);
string status = parsed.status;
if (status == "ok")
{
int count = parsed.meta.count;
if (count > 0)
{
player = new Player
{
Nickname = parsed.data[0].nickname,
Id = parsed.data[0].account_id
};
}
else
{
throw new PlayerNotFound("Игрок не найден");
}
}
else
{
string error = parsed.error.message;
if (error == "NOT_ENOUGH_SEARCH_LENGTH")
{
throw new PlayerNotFound("Минимум три символа требуется");
}
else if (error == "INVALID_SEARCH")
{
throw new PlayerNotFound("Неверный поиск");
}
else if (error == "SEARCH_NOT_SPECIFIED")
{
throw new PlayerNotFound("Пустой никнейм");
}
else
{
throw new Exception("Something went wrong.");
}
}
return player;
}
Увага! Всі токени та ID додатків зберігати у відкритому вигляді суворо не рекомендується! Як мінімум – Discord банить такі токени, коли вони потрапляють до всесвітньої мережі, як максимум – бот починає користуватися зловмисниками.
Деплой на VPS – сервер
Після того, як ви закінчили з ботом, його потрібно розмістити на сервері, який постійно працює 24/7. Це пов'язано з тим, що коли працює ваша програма, то працює і бот. Як тільки ви вимикаєте програму, засинає і ваш бот.
Багато VPS серверів існує на цьому світі, як на Windows, так і на Linux, однак у більшості випадків, на Linux у рази дешевше розміщувати.
На Discord - сервері мені порадили vscale.io, і я відразу створив на ньому віртуальний сервер на Ubuntu і залив бота. Я не описуватиму, як працює даний сайт, а відразу перейду до налаштування бота.
Насамперед, вам необхідно встановити необхідний софт, який запускатиме нашого бота, написаного на .NET Core. Як це зробити, описано тут.
Далі, вам необхідно залити бота на Git – сервіс, на кшталт GitHub і йому подібні та схилювати на VPS – сервер, або іншими шляхами завантажити вашого бота. Майте на увазі, що у вас буде тільки консоль, GUI не буде. Зовсім.
Після того, як ви завантажили ваш бот, вам необхідно його запустити. Для цього вам необхідно:
Відновити всі залежності: dotnet restore
Побудувати програму: dotnet build name_project.sln -c Release
Перейти до DLL;
dotnet name_of_file.dll
Вітаю! Ваш бот запущено. Однак, бот, на жаль, займає консоль, і вийти з VPS - сервера так просто не вийде. Також, у разі перезавантаження сервера, доведеться по-новому запускати бота. Тут є кілька виходів із ситуації. Всі вони пов'язані із запуском при старті сервера:
Додати запуск скрипту /etc/init.d
Створити сервіс, який запускатиметься при старті.
Детально зупинятися на них не бачу сенсу, досить докладно описано в інтернеті.
Висновки
Я радий, що взявся за це завдання. Це був мій перший досвід розробки бота, і радий, що отримав нові знання C#, і роботи з Linux.