Как написать telegram бота на java

Корпорация "Центр"

Программируйте во имя добра

После того как Пашка Дуров с помощью Роскомнадзор провел грамотную маркетинговую кампанию Telegram, многие по достоинству оценили API, которое позволяет интегрироваться с этим мессенджером посредством ботов.
Да, как бы мы не относились к личности Павла и его эпатажным выходкам — механизм ботов в Telegram выглядит изящным, красивым и продуманным решением.
Поэтому грех будет не написать своего бота, а то у всех есть, а у нас. Как-то неудобно даже.
Если вы не боитесь своими действиями пополнить армию Скайнет и приблизить закат человечества от железной руки роботов — тогда за мной. Программируй ботов во имя добра!

Боты — это хорошо. Это очень хорошо. Telegram-бот — это некая программа, которая выглядит как пользователь и умеет взаимодействовать с пользователями и другими ботами в Telegram.

Вот по этой ссылке находится официальная документация API Telegram-ботов. Если вы находитесь в стране запрещенных ботов, то скорее всего, эта ссылка будет у вас недоступна. Но вы же знаете, что делать?=) В крайнем случае — есть документация и на русском языке.

Согласно документации, Telegram Bot API представляет собой основанный на HTTP интерфейс для разработчиков, заинтересованных в создании ботов. Конечно, использовать чистые HTTP-запросы не так удобно, но, к счастью, добрые люди уже написали хорошую библиотеку на Java, ее мы и возьмем.

Telegram-бот на Java для самых маленьких — от старта до бесплатного размещения на heroku

Если вы ни разу не писали Telegram-ботов на Java и только начинаете разбираться — эта статья для вас. В ней подробно и с пояснениями описано создание реального бота, автоматизирующего одну конкретную функцию. Можно использовать статью как мануал для создания скелета своего бота, а потом подключить его к своей бизнес-логике.

Предыстория

Когда моя дочь начала изучать арифметику, я между делом накидал алгоритм генерации простых примеров на сложение и вычитание вида «5 + 7 =», чтобы не придумывать и не гуглить для неё задания.

И тут на глаза попалась новость, что Telegram выпустил новую версию Bot API 5.0. Ботов я раньше не писал, и потому решил попробовать поднять бота как интерфейс для своей поделки. Все примеры, которые мне удалось найти, показались либо совсем простыми (нужные мне функции не были представлены), либо очень сложными для новичка. Также мне не хватало объяснений, почему выбран тот или иной путь. В общем, написано было сразу для умных, а не для меня. Потому я решил описать свой опыт создания простого бота — надеюсь, кому-нибудь это поможет быстрее въехать в тему.

Что в статье есть, чего нет

В статье есть про:

  • создание бекенда не-инлайн бота на Java 11 с использованием Telegram Bot Api 5.0;
  • обработка команд вида /dosomething ;
  • обработка текстовых сообщений, не являющихся командами (т.е. не начинающихся с "/");
  • отправку пользователю текстовых сообщений и файлов;
  • деплой и запуск бота на heroku.
  • использование функций ботов, не перечисленных выше (например, создание клавиатур — я их сначала добавил, но в итоге они мне просто не пригодились);
  • создание списка заданий;
  • работу с Word-документом;
  • обеспечивающие функции — логирование, тесты и т.п.;
  • общение с BotFather (создание бота, получение его токена и формирование списка команд подробно и понятно описано во многих источниках, вот первый попавшийся мануал).

Бизнес-функции бота

  • выдавать пользователю справочную текстовую информацию в ответ на команды /start , /help и /settings ;
  • обрабатывать и запоминать пользовательские настройки, направленные текстовым сообщением заданного формата. Настроек три — минимальное + максимальное число, используемые в заданиях, и количество страниц выгружаемого файла;
  • оповещать пользователя о несоблюдении им формата сообщения;
  • формировать Word-файл с заданиями на сложение, вычитание или вперемешку в ответ на команды /plus , /minus и /plusminus с использованием дефолтных или установленных пользователем настроек.

Порядок разработки

  • разобраться с зависимостями;
  • создать класс бота и реализовать обработку текстовых сообщений пользователя, не являющихся командами;
  • создать классы команд;
  • прописать запуск приложения;
  • задеплоить на heroku.

Зависимости

Для управления зависимостями использовался Apache Maven. Нужные зависимости — собственно Telegram Bots и Lombok, использовавшийся для упрощения кода (заменяет стандартные java-методы аннотациями).

Вот что вышло в

Класс бота и обработка текстовых сообщений

Мой класс Bot унаследован от TelegramLongPollingCommandBot , который, в свою очередь, наследуется от более распространённого в примерах TelegramLongPollingBot . Он хорош тем, что в нём уже реализованы приём и обработка команд — то есть сообщений, начинающихся с "/". Можно создавать отдельные классы команд (подробнее о них ниже), инициализировать их в конструкторе бота и уже в них писать логику их обработки.

В классе Bot таким образом остаётся только логика обработки текстовых сообщений, не являющихся командами. В моём случае это пользовательские настройки или мусорные сообщения, не соответствующие формату. Для лаконичности логику их обработки тоже стоит вынести в отдельный вспомогательный класс, вызывая его метод из переопределенного метода processNonCommandUpdate(Update update) класса Bot .

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

Получился вот такой

Классы команд

Все классы команд наследуются от BotCommand .

Команды в моём боте делятся на 2 группы:

  • Сервисные — возвращают справочную информацию;
  • Основные — формируют файл с заданиями.

Начнём с более простых Сервисных команд. В абстрактный суперкласс вынесен метод отправки пользователю ответа, а в классах команд формируется текст ответа.

Абстрактный суперкласс Сервисных команд

Приложение

В методе main инициализируется TelegramBotsApi , в котором и регистрируется Bot.

Как написать telegram бота на java

Как сделать бота для telegram на java?

Как вы выбираете кандидата, кому доверить задание? Я задался этим вопросом, после того, как отклонили мое предложение о разработке бота для "вконтакте". Это задело мое самолюбие. На работе я делаю куда более сложные вещи, чем разработка ботов. Как доказать тому человеку, который находится по ту сторону экрана, который незнает меня и не доверяет, что я могу сделать простейшего бота информатора? Ответ есть — сделать этого бота и задокументировать процесс его создания. Статья расчитана на новичков, желающих познакомится с новым стандартом java 15 и простейшим ботостроением. Итак, нам понадобятся:

  • IntelliJ IDEA CE
  • Java JDK_15_PREVIEW
  • Библиотека для взаимодействия с телеграмом

С какими трудностями мы столкнемся? Для меня, самым сложным было настроить среду разработки для работы с джавой 15 превью версии. Нужно отдельно настроить gradle и выставить в настройках запуска проекта аргумент "—enable-preview".

Рис. 1

Начнем по порядку с создания проекта: Рис. 1 Создание нового проекта

Нажимаем на кнопку "New Project". Следом увидим вот такое меню:

Рис. 2

Рис. 2 Выбор типа проекта

За основу я взял сборщик проектов Gradle. Выбираем Java и затем кнопку Next

Рис. 3

Рис. 3 Задаем имя проекта

Теперь нужно дать имя проекту. В моем случае это "telegram-bot-example-java"

Рис. 4

Рис.4 Ждем, пока проект проиндексируется

Какое-то время идея и gradle будут загружаться. Кстати, я уже допустил одну ошибку в конфигурации проекта, заметили, какую? Вернемся к этому позже.

Рис. 5

Рис.5 Создание структуры java packages

Кликаем правой кнопкой по папке "src/main/java" -> New -> Package -> "org.example.tgbot"

Рис. 6

Рис. 6 Создаем точку входа в программу

Теперь самое главное, без чего программа не запустится — точка входа и метод "main". Выбираем "org.example.tgbot" -> New -> Java Class. Называем новый класс Main.

Рис. 7

Рис. 7 Файл Main.java

Вот такой код должен быть в файле "Main.java". Обратите внимание на две зеленые стрелки рядом с определением класса и метода "main". Если вы их видите, значит сделали все правильно и IDEA может запустить ваш проект.

Рис. 8

Рис. 8 Тестовый запуск

Проверим, что все ок, запустив проект.

Рис. 9

Рис. 9 Успешный запуск

Корпорация "Центр"

Если все хорошо, вы должны увидеть "done". У меня он есть, значит, можно продолжать.

Рис. 10

Рис. 10 Проверяем новую фичу java 15

Итак, вот мы дошли до ошибки, о которой я упоминал выше. В чем тут дело? Тип "record" был добавлен в java 15 и в превью версии должен присутствовать. Но я при запуске указал джаву восьмой версии. Что теперь делать? Можно сделать новый проект и указать правильную версию. Или можно исправить текущий проект. Сделать новый слишком просто, поэтому я исправлю этот (на самом деле нет, я попробовал, это не решило проблему).

Рис. 11

Рис. 11 Настройки проекта

Исправляем проблему. Нужно поменять версию джавы.Открываем настройки проекта.

Рис. 12

Рис. 12 Настройки версии java

Выбираем "Project SDK" -> 15. Если у вас ее нет, можно скачать ниже, в выпадающем списке. В "Project language level" выбираем "15 (Preview) — Sealed types, records, patterns, local enums and interfaces". Сохраняем настройки.

Рис. 13

Рис. 13 Record тип работает

Теперь все ок, можно наконец-то взяться за программирование? Увы, нет. IDEA распознает новые фичи, но кроме нее есть еще gradle, который не сможет скомпилировать этот код. Чтобы это проверить, создаим рядом с "Main.java "еще один файл — "Bot.java" в котором будет происходить обработка сообщений.

Рис. 14

Рис. 14 Bot.java

У gradle будут проблемы со сборкой этого файла, а именно — из за 11 строки. Модификатор "sealed", как и "record", является экспериментальным. Проверим, соберем проект.

Рис. 15

Рис. 15 Gradle error

Еще немного борьбы и мы запустим этот код. Нужно настроить сборку gradle и добавить аргумент "—enable-preview" при запуске.

Рис. 16

Рис. 16 Gradle java 15 settings

Нужно добавить новую секцию, в которой будут задаваться флаги сборки "—enable-preview" и "-Xlint:Preview". Второй флаг не обязательный, нужен для отображения новых warnings. В комментарии пример, как можно задать все флаги одной строкой. Кроме этого, нужно добавить строку "jvmArgs([‘—enable-preview’])" в секцию "test". На этом с gradle закончили.

Рис. 17

Рис. 17 Настройки сборки

Далее, нужно добавить аргумент для виртуальной машины java. Отрываем настройки.

Рис. 18

Рис. 18 Открыть меню "Add VM options"

После чего у вас появится поле редактирование опций виртуальной машины.

Рис. 19

Рис. 19 Редактор опций виртуальной машины

В пустое поле вписываем "—enable-preview". Также проверьте, что у вас стоит "java 15". Сохраняем настройки и собираем проект. У меня сборка и запуск прошли успешно. Теперь настроим прием сообщений и ответы.

Рис. 20

Рис. 20 Bot.java

Добавляем следующий код в файл "Bot.java". В нем два метода, хотя можно было обойтись и одним, выбранная мною библиотека присилает обновления в виде массива, а не по одному. Ах да, я забыл показать, как добавить эту библиотеку.

Рис. 21

Рис. 21 Добавляем зависимость в "build.gradle"

В секцию "dependencies" добавьте строку "implementation ‘com.github.pengrad:java-telegram-bot-api:5.0.1’" как показано на рисунке (13 строка). И финальный штрих, обновляем Main класс, чтобы запустить бота.

Рис. 22

Рис. 22 Новый Main класс

Здесь я читаю BOT_TOKEN из переменных среды, это значит, ее нужно как то добавить. Это можно сделать глобально в системе или задать в IDEA. Я выбираю второй вариант.

Рис. 23

Рис. 23 Снова открываем "Edit configurations"

Рис. 24

Рис. 24 Редактирование переменных среды

В поле "Environment variables" вставьте строку "BOT_TOKEN=123", где 123 — ваш токен. А я вставлю свой 🙂 Сохраняем настройки и запускаем проект.

Рис. 25

Рис. 25 Бот успешно запущен

Бот работает! Пруф:

Рис. 25

Рис. 25 Телеграм чат

Скорее всего, если вы захотите проверить моего бота, он вам не ответит. Потому что программа, которую мы написали, запущена локально, у меня на компьютере. Чтобы бот работал 24/7, программу нужно разметить на удаленном сервере (или просто держать компьютер всегда включенным всесте с запущенной программой). Это материал для другой статьи. Я также могу рассказать, как сделать ответы на команды в чате, отображать динамическую информацию, информировать клиентов. Или как написать бота на scala >_<. Пишите в комментариях, что у вас не получилось. До встречи в других статьях!

Корпорация "Центр"

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *