Создание Discord – бота на .NET Core с деплоем на VPS-сервер
Привет, Хабровчане!
Сегодня вы ознакомитесь со статьей, в которой будет рассказано, как создать бота, используя C# на .NET Core, и о том, как его завести на удаленном сервере.
Статья будет состоять из предыстории, подготовительного этапа, написания логики и переноса бота на удаленный сервер.
Надеюсь, данная статья поможет многим начинающим.
Предыстория
Все началось в одну бессонную осеннюю ночь, которую я проводил на Discord – сервере. Так как я относительно недавно к нему присоединился, я стал его изучать вдоль и поперёк. Обнаружив текстовый канал «Вакансии», я заинтересовался, открыл его, и отыскал среди не интересующих меня предложений, это:
«Программист (разработчик бота) Требования:
знание языков программирования;
способность к самообучению.
Пожелания:
умение разбираться в чужом коде;
знание функционала DISCORD.
Задачи:
разработка бота;
поддержка и сопровождение работы бота.
Ваша выгода:
Возможность поддержать и повлиять на приглянувшийся проект;
Приобретение опыта работы в команде;
Возможность продемонстрировать и улучшить имеющиеся навыки.»
Это мгновенно меня заинтересовало. Да, за данную работу не платили, но от тебя никаких обязательств не требовали, да и в портфолио лишним не будет. Поэтому я написал админу сервера, и он попросил написать бота, который будет показывать статистику игрока в World of Tanks.
Подготовительный этап
Discrod
Прежде, чем приступить к написанию нашего бота, его необходимо создать для Discord. Вам необходимо:
Заходим в «Мои приложения» и нажимаем на кнопку «Добавить новое приложение», дав имя приложения и выбрав его тип
Сохраняем ID приложения
Software
Тут уже имеется свобода выбора. Кто-то использует 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.