Java Development
December 6, 2022

Дневник WEB 2.5 разработчика — Price Bot

Предисловие

В этой статье я на своем страдальном примере расскажу, как создавать Telegram-ботов на Java, покажу внутренности бота и опишу, что-зачем-почему нужно.

Все будет описано языком полуобывателя, термины "метод", "поля" и т.д. могут быть неправильно употреблены, в Java-терминологии я не очень силен.

Автор — https://t.me/jetix37eth

Я (пока что) учусь на направлении, связанным с криптографией, шифрованием и всем, что с этим связано.

На предмете нам дали задачу на семестр — написать бота на любую тематику. Мне очень хотелось создать криптобота (парсер цен, транзакций EVM-кошельков и пересылку Twitter-сообщений), но первым говорить о своей идее не было желания, так как не хотелось связывать свою университетскую личность с криптосферой.

Как же мне суперповезло, когда мой напарник выдвинул идею написать бота-парсера цен криптовалют. Радости моей не было предела.

Мы рассказали о своей идее преподу, создали репозиторий, и понеслась...

Maven

Сначала мы создали файл pom.xml со следующими данными:

Основа

Строки под цифрой 1 задаются при создании проекта в IDEA (IDE для Java), нужны в первую очередь для промышленной разработки, чтобы челы не запутались в файлах и версиях.

Зависимости

Далее формируются зависимости — различные библиотеки и прочее. Зависимости под цифрой 1 нужны для работы с json запросами (их ставил мой напарник).

Зависимость под цифрой 2 — это API для работы с Telegram-ботами. У меня ушло 4 часа, чтобы понять, как импортировать эти библиотеки, это было больно во время и весело после.

Логика бота

Логика бота — самое вкусное во всей этой истории.

Метод botResponds получает на вход userAnswer (запрос от пользователя), возвращает String-значение, получаемое из методов в (2).

Метод price получает один аргумент, поэтому нами (мной) было принято стратегически-авантюрное решение создать массив из двух строк, в котором будет лежать разделенная по пробелу строка userAnswer.

Далее мы смотрим на то, какую команду ввел пользователь и с помощью switch вызываем ее. Если команда введена неверно, то бот вернет ему сообщение: "Я пока еще не знаю эту команду, для помощи используйте /help".

Стоит упомянуть, что за недолгое время разработки метод был переписан с нуля четыре раза.

startCommand — все очень просто: выводит стартовое сообщение на экран.

price (который по-хорошему должен называться priceCommand) — предоставляет пользователю цену монеты.

Мы (зачем-то, надо это убрать) создаем Stringовую переменную userCoin — тикер монеты, которую ввел пользователь (BTC, ETH и т.д.).

Создаем объект Parser (который пилил мой напарник, об этом далее) и получаем цену монеты. Если такой монеты нет (почему в боте нет 99% монет — будет далее), то бот выведет сообщение: "Такой монеты нет в моей базе данных".

helpCommand и unknownCommand — выводят помощь и ошибку об отсутствии команды, дешево и сердито.

Консольная версия

Консольная версия нужна была в первое время, когда у нас не было бота в Telegram. Вообще, бота можно было оставить и в консоли, telegram — это отдельная задача, за которую причитаются баллы.

Scanner нужен для считывания данных от пользователя с клавиатуры (про package org.example было сказано в Maven).

Создаем объект botlogic, чтобы использовать его методы в коде. Зачем мы делаем public ConsoleBot(), я сказать не могу (скорее всего напарник что-то делал и намудрил).

Метод dialog запускает нашего бота. Выводим приветственное сообщение и до посинения общаемся с пользователем, передавая его ответы в botlogic.botResponds.

inputHandler, который вы видите в коде — это пережиток прошлого, который должен быть удален в скором времени, без него консольный бот прекрасно работает.

Telegram-версия

Версия бота для Telegram (можно было еще в Алису и прочие интерфейсы интегрировать бота, но Telegram — классика).

Сначала идет куча импортов, чтобы наш бот работал (некоторые из них вроде не нужны, надо будет убрать).

Создаем класс TelegramBot, который наследуется от TelegramLongPolling Bot.

Импортируем бот токена, который нам генерирует BotFather в Telegram (хардкодить токен бота — самоубийство, приходится его прятать в системные переменные). Также создаем объект botlogic для использования логики бота.

Переопределяем метод onUpdateReceived. Если от пользователя есть сообщение, то мы вызываем команду, которую он запросил и выводим ответ через sendMessageText.

sendMessageText посылает сообщение пользователю по его userId. Если какое-то палево и бот не может отправить сообщение, то он выдает исключение.

Переопределяем два метода: getBotUsername и getBotToken. Ничего интересного.

Парсер

Импортируем библиотеки, которые ранее объявили в Maven.

Создаем Coin-метод, который получает тикер от пользователя.

Самое интересное: в качестве источника данных мы используем Yo-мать-его-Bit. Почему мы используем YoBit, а не Coinmarketcap или CoinGecko, надо спрашивать у моего напарника.

Далее мы пытаемся извлечь из YoBit цену актива и возвращаем ее пользователю. Если на YoBit нет такой монеты (там нет ни $BNB, ни $ATOM), то бот возвращает null, что, в свою очередь, выведет пользователю "Такой монеты нет в моей базе данных".

Coin

66 строк объявлений полей и методов, которые на данный момент не используются.

Запуск бота

Main.java — класс, в котором инициализируется наш бот.

Импортируем библиотеки для работы с Telegram (если мы хотим работать с консольной версией, то эти импорты не нужны).

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

Заключение

Основная задача бота — это не создать универсальное приложение для криптанов, а получить допуск к зачету.

Писав эту статью, я заметил несколько лишних строк кода, которые в идеале убрать, а по факту — на допуск к зачету это не влияет.

Ссылку на бота (на данный момент) не публикую, так как мы не ставили его на сервак, пока что впадлу, да и не имеет смысла по обозначенной выше причине.

Бот работает, а большего нам и не надо.