Программирование бота на java

Пишем телеграм бота на Java от А до Я

У меня появилась идея написать серию статей по созданию полноценного проекта на Java для тех, у кого нет опыта работы. Я хочу научить и показать процесс разработки максимально детально, насколько это вообще можно. Шаг за шагом идти к намеченной цели.
Мы будем двигаться с двух сторон — я буду стараться научить, а вы будете стараться понять и воспроизвести у себя это.

Серия статей похожа на пошаговую инструкцию что нужно и делать и как чтобы добиться цели. Поэтому будет разумно вместе со мной пройти этот путь и написать такой же или похожий проект для себя.

Кому это будет интересно?

Целевая аудитория — все, кто знает Java SE. Все остальное я буду или описывать в рамках этой серии статей, или это уже описано мною в других статья ранее (например работу с Гитом я описал заранее и просто прикрепляю ссылку на него).
Разумеется, это может быть интересно и уже опытным людям. Отдельно буду благодарен за конструктивную критику моей реализации (это можно будет сделать через гитхаб, в рамках нового issue или написать в телеграм-канале).

Во время разработки проекта столкнемся с проблемами, посмотрим как их можно решить. Напишем документацию. Отрефакторим код. Покроем все качественными тестами. Настроим и добавим метрики по отслеживанию качества кода в CI процесс.

Читайте также:  Javascript как добавить атрибут

Что будем в этом проекте?
Понятно, что всем интересно поработать с какой-то технологией, базой данных, их интеграцией. Много будет уделено вниманию развертывания проекта. Его тестированию. Разработка ведется в открытом репозитории на гитхабе. Для этого дела, создал отдельную организацию, чтобы объединить все необходимые для работы проекта данные.
Поговорим о:
— Поговорим о том, как спроектировать проект, написать задачи для него. Порисуем схемы базы данных.
— SQL/MySQL — для этого отведена первая серия статей. Описание рассчитано на людей, которые вообще не имеют об этом понятия.
— Flyway — через flyway будем работать с версионированием базы данных
— SpingBoot — как каркас всего приложения. Здесь внутри затронем Scheduling для наших нужд.
— Docker / Docker-compose — при помощи докера и докер компоуза будем развертывать наше приложение. Вся необходимая инфраструктура будет разворачиваться при запуске одной строки(!!)
— Bash Script — напишем два простеньких баш скрипта, которые соберут воедино наш процесс развертывания
— Lombok — просто как удобная вещь для наших сущностей.
— Тестирование — отдельно хорошо поговорим о тестировании, о модульных тестах, интеграционных. О создании CI процесса для разработки, настройки этого процесса.

Что будет в итоге?
В итоге получим реальный проект, который будет работать. Его можно будет потрогать, каждый шаг его разработки будет тщательно описан.

Для освещения деятельности создал телеграм-канал: t.me/romankh3
В нем я размещаю свою open-source деятельность и львиная его доля на данный момент — это написание проекта от А до Я. Поэтому всех, кому будет интересно следить за проектом — приглашаю присоединиться.

Сразу хочу сказать, что это не реклама JavaRush. Просто так исторически сложилось, что я там публикую свои статьи для начинающих специалистов. Все материалы, которые будут нужны (статьи, исходники кода) — все в открытом доступе.

Если это интересно для тебя — присоединяйся.
Вот первая статья этой серии: javarush.ru/. ​ihy-proekt-dlja-portfolio
Остальные ссылки находятся в статьях.

Всем добра. Надеюсь этот проект поможет кому-то еще.

UPDATE: в спешке донести идею о том, что я создаю я как-то не подумал, что это все реклама. Спасибо в комментах написали, усвоил. Поэтому как только я закомчу свою серию статей (там всего будет где-то 20-25 полноценных статей) по телеграм-боту и проект уже будет готов — напишу сжато 2-3 части здесь, на хабре.

Источник

Telegram bot на Java? Быстро и легко

Публикаций по данной теме не мало, на самом хабре есть дюжина страниц с полезной информацией. Зачем я решил написать очередную статью о создании бота? Для начинающих в изучении java это хороший вариант познакомиться с Maven и Telegram API, для людей далеких от IT — возможность создать бота с нуля. Ниже я попытаюсь описать создание простейшего бота. Программа будет иметь несложный функционал, по моей задумке бот будет хранить в себе различные цитаты великих людей и по запросу пользователя, отправлять случайные из них. Что нам понадобится? Аккаунт в telegram и среда разработки, я использую Intellij IDEA. Описывать процесс установки не буду, в интернете есть достаточно подробные инструкции.

Шаг перый — регистрация бота в системе

Создание любого бота начинается с обращения к самому главному из них.

  1. Заходим в телеграмм и ищем @BotFather.
  2. Пишем ему команду /newbot
  3. Далее он спросит название будущего бота (грубо говоря, это заголовок в чате, который будут видеть пользователи) и его имя. Главное условие для имени — оно должно оканчиваться на ‘bot’.

Инициализация закончена, BotFather отправит нам ссылку на нашего будущего бота и, самое главное, выдаст нам уникальный токен, необходимый для авторизации в системе. По сути бот готов, уже можно его найти в общем поиске по имени и начать ему писать, но логика у нас еще не готова

Шаг второй — создание проекта в среде разработки и добавление зависимостей

Создаем новый проект и в процессе настройки обязательно выбираем maven, он необходим для автоматизации сборки проектов. С помощью этого инструмента мы на порядок облегчим себе жизнь, добавление сторонних библиотек не составит труда.

Для использования Telegram API, cкачивать и подключать извне ничего не нужно, достаточно зайти в pom.xml в корневом каталоге и написать несколько строк. С помощью конструкции *** мы указываем среде разработки, какие библиотеки нужно загрузить и добавить в проект, в нашем случае это org.telegram. Остальную часть файла maven сгенерировал сам. Получаем такой файл:

  4.0.0 org.example TgBotQuote 1.0-SNAPSHOT 16 16   org.telegram telegrambots 5.3.0   

Шаг третий — логика

Наш бот будет уметь хранить и отправлять случайные фразы великих людей. Я создал три класса: Main, Bot, Storage, начнем с последнего, с хранилища. Создаем коллекцию quoteList, инициализируем в конструкторе и добавляем несколько фраз. Также создаем функцию, котораю выдает случайную фразу из нашего хранилища getRandQuote().

public class Storage < private ArrayListquoteList; Storage() < quoteList = new ArrayList<>(); quoteList.add("Начинать всегда стоит с того, что сеет сомнения. \n\nБорис Стругацкий."); quoteList.add("80% успеха - это появиться в нужном месте в нужное время.\n\nВуди Аллен"); quoteList.add("Мы должны признать очевидное: понимают лишь те,кто хочет понять.\n\nБернар Вербер"); > String getRandQuote() < //получаем случайное значение в интервале от 0 до самого большого индекса int randValue = (int)(Math.random() * quoteList.size()); //Из коллекции получаем цитату со случайным индексом и возвращаем ее return quoteList.get(randValue); >>

Далее, создаем класс Bot и наследум его от TelegramLongPollingBot, предварительно создав две константы BOT_TOKEN(токен выдал BotFather), BOT_NAME и экземпляр класса Storage. Среда попросит реализовать три метода от материнского класса getBotUserName(), getBotToken() и onUpdateReceived(). Первые два возращают имя бота и его токен соответственно, а последний вызывается при каждой отправке сообщения пользователем, он нас и интересует. Метод onUpdateReceived(Update update) получает на вход объект update, из которого мы можем получить сообщение, текст и id чата, необходмые для отправки ответного сообщения. Также я написал метод parseMessage(), который принимает текст сообщения пользователя, обрабатывает (сравнивает текст с возможными командами) и выдает ответ

Дабы не усложнять учебный процесс, ограничимся только двумя командами. При первом запуске любого бота автоматически отправляется команда /start . Советую всегда реализовывать ответ на это сообщение, в нашем случае это простое приветствие и краткое объяснение функционала. Вторая команда, которую умеет определять наш бот — /get. В ответ на сообщение мы обращаемся к нашему хранилищу storage и методом getRandQuote() получаем случайную цитату и отправляем ее дальше. На самом деле необязательно использовать косую черту и латиницу, количеством и функционалом команд вы ограничены только своим воображением

public class Bot extends TelegramLongPollingBot < //создаем две константы, присваиваем им значения токена и имя бота соответсвтенно //вместо звездочек подставляйте свои данные final private String BOT_TOKEN = "***"; final private String BOT_NAME = "***"; Storage storage; Bot() < storage = new Storage(); >@Override public String getBotUsername() < return BOT_NAME; >@Override public String getBotToken() < return BOT_TOKEN; >@Override public void onUpdateReceived(Update update) < try< if(update.hasMessage() && update.getMessage().hasText()) < //Извлекаем из объекта сообщение пользователя Message inMess = update.getMessage(); //Достаем из inMess id чата пользователя String chatId = inMess.getChatId().toString(); //Получаем текст сообщения пользователя, отправляем в написанный нами обработчик String response = parseMessage(inMess.getText()); //Создаем объект класса SendMessage - наш будущий ответ пользователю SendMessage outMess = new SendMessage(); //Добавляем в наше сообщение id чата а также наш ответ outMess.setChatId(chatId); outMess.setText(response); //Отправка в чат execute(outMess); >> catch (TelegramApiException e) < e.printStackTrace(); >> public String parseMessage(String textMsg) < String response; //Сравниваем текст пользователя с нашими командами, на основе этого формируем ответ if(textMsg.equals("/start")) response = "Приветствую, бот знает много цитат. Жми /get, чтобы получить случайную из них"; else if(textMsg.equals("/get")) response = storage.getRandQuote(); else response = "Сообщение не распознано"; return response; >> 

В главном классе создаем сессию и регистрируем бота

public class Main < public static void main(String args[]) < try < TelegramBotsApi telegramBotsApi = new TelegramBotsApi(DefaultBotSession.class); telegramBotsApi.registerBot(new Bot()); >catch (TelegramApiException e) < e.printStackTrace(); >> >

Жмем run. После запуска заходим в мессенджер, находим нашего бота, начинаем чат и вуаля, бот готов к общению. Прямо из среды разработки наша программа доступна к использованию в telegram. Основная цель на статью выполнена — мы познакомились со структурой программы, с основными методами, быстро и легко получили рабочий шаблон бота, на основе которого теперь вы можете поробовать написать своего элементарного робота. Теперь хотелось бы сделать его чуточку удобнее. Ну и разнообразить наш контент не помешало бы

Шаг четвертый — добавляем клавиатуру

Для этого в классе Bot создадим экземпляр класса ReplyKeyboardMarkup, грубо говоря это шаблон ответов, который мы прикрепляем к нашему сообщению. Он состоит из объектов KeyboardRow, которые в свою очередь представяют ряды кнопок. Все это я реализовал в отдельном методе и вызвал его в конструкторе класса Bot

void initKeyboard() < //Создаем объект будущей клавиатуры и выставляем нужные настройки replyKeyboardMarkup = new ReplyKeyboardMarkup(); replyKeyboardMarkup.setResizeKeyboard(true); //подгоняем размер replyKeyboardMarkup.setOneTimeKeyboard(false); //скрываем после использования //Создаем список с рядами кнопок ArrayListkeyboardRows = new ArrayList<>(); //Создаем один ряд кнопок и добавляем его в список KeyboardRow keyboardRow = new KeyboardRow(); keyboardRows.add(keyboardRow); //Добавляем одну кнопку с текстом "Просвяти" наш ряд keyboardRow.add(new KeyboardButton("Просвяти")); //добавляем лист с одним рядом кнопок в главный объект replyKeyboardMarkup.setKeyboard(keyboardRows); >

Нам хватит всего одной кнопки для реализации задумки. Нет ни каких проблем методом add() добавить необходимое количество рядов и клавиши на них. Вы можете создавать различные клавиатуры, скрывать и показывать их пользователю в разных ситуациях. Также существует второй класс для создания клавиатур — InlineKeyboard, позволяющий делать более сложные действия, но мы оставим первый вариант

Теперь, в методе onUpdateReceived() к исходящему от нас сообщению добавляем клавиатуру.

outMess.setReplyMarkup(replyKeyboardMarkup);

Так как нажатие на кнопку отправляет в чат то, что на ней написано, немного изменим наш обработчик. Теперь бот понимает сообщение «Просвяти» и реагирует на него, как на команду /get

else if(textMsg.equals("/get") || textMsg.equals("Просвяти")) response = storage.getRandQuote();

После запуска мы видим, что все прекрасно работает. Изучение telegram API в этой публикации на этом заканчивается. Я только поверхностно рассказал об основных возможностях этой библиотеки, для более подробных знаний есть достаточно подробная документацию. Стоило бы закончить статью, но чего-то нашему боту не хватает — разнообразия в контенте. Три цитаты это слишком несерьезно — значит пишем парсер

Шаг пятый — пишим простой парсер

Что такое парсер? Парсер — программа, которая извлекает и анализирует данные с веб страниц. Данный шаг не относится к непосредсвенному написанию ботов, поэтому вдаваться в подробности не буду, этой теме можно посвятить отдельную статью.

Для начала в файле pom.xml прописываем еще одну зависимость. Библиотека jsoup позволяет нам работать с веб страницами, располагает очень удобными методами для обращения к определенным элементам на сайтах.

Взяв первый попавшийся сайт с цитатами, я приступил к написанию парсера. Для этого в классе Storage я написал метод parser(String strURL), который принимает на вход ссылку искомой страницы. Изучив страницу сайта через исходный код в браузере, я нашел блок, в котором находятся цитаты — «su-note-inner su-u-clearfix su-u-trim».

void parser(String strURL) < String classNmae = "su-note-inner su-u-clearfix su-u-trim"; Document doc = null; try < //Получаем документ нужной нам страницы doc = Jsoup.connect(strURL).maxBodySize(0).get(); >catch (IOException e) < e.printStackTrace(); >//Получаем группу объектов, обращаясь методом из Jsoup к определенному блоку Elements elQuote = doc.getElementsByClass(classNmae); //Достаем текст из каждого объекта поочереди и добавляем в наше хранилище elQuote.forEach(el -> < quoteList.add(el.text()); >); >

Осталось только где-то вызвать наш метод. Сделал это я в конструкторе класса Storage, чтобы наполнить нашу коллекцию на этапе запуска программы и инициализации объектов. Код, в котором мы вручную добавляли цитаты в хранилище, я удалил. Вместо них — метод вызова парсера, которому мы передаем ссылку на сайт.

parser("https://citatnica.ru/citaty/mudrye-tsitaty-velikih-lyudej");

Запускаем! Теперь вместо скудного запаса из трех высказываний, бот знает 200 цитат и это только с одной страницы.

Источник

Оцените статью