TelegramBot инструкция по созданию базового функционала для бота. (Часть 1)

Не так давно я предложил вам воспользоваться моим ботом для телеграмма.
Telegram Bot — помощник в планировании мероприятий
Получив много вопросов в личку, я понял, что вопрос создания ботов для Телеграм довольно популярен.
У меня спрашивали исходный код бота, просили поделиться конкретными примерами реализации тех или иных возможностей бота, просили подсказать тот или иной функционал по работе с ботом и сообщениями.

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

И сразу с козырей зайду 🙂
То, о чем просили в предыдущей статье.
Исходные коды по проекту вы можете найти тут
В ветке «master» будет финальная версия бота, которого мы вместе с вами и напишем, в процессе появления новых статей.

Полный исходники по этой статье будет находится в ветке «Part1-Base«

В данной части мы создадим с вами базовый шаблон, который способен будет:

  1. регистрировать бота на серверах Телеграмм
  2. получать сообщения, написанные боту
  3. реагировать на команду /start

Создаем стандартный maven проект

(я упущу мануалы по работе со средой разработки и базовые вещи из Java программирования. Все эти вещи достаточно легко гугляться.А если не будет получаться — пишите вопросы).

Давайте посмотрим, какие зависимости нам будут нужны в этом проекте.

В первую очередь это Lombok. Что это и зачем — можно почитать, например, тут
И обязательно добавим логгер. Я использую log4j и чуть дальше покажу вам как полезно его можно использовать при отладке данного приложения и более глубокого осмысления работы TelegramAPI.

<!-- https://mvnrepository.com/artifact/org.projectlombok/lombok -->         <dependency>             <groupId>org.projectlombok</groupId>             <artifactId>lombok</artifactId>             <version>1.18.10</version>             <scope>provided</scope>         </dependency> <!-- https://mvnrepository.com/artifact/log4j/log4j -->         <dependency>             <groupId>log4j</groupId>             <artifactId>log4j</artifactId>             <version>1.2.17</version>         </dependency> 

И, т.к. мы пишем бота для Телеграм, то и саму библиотеку от Telegram:

<dependency>             <groupId>org.telegram</groupId>             <artifactId>telegrambots</artifactId>             <version>3.5</version> </dependency>

Структуру pom файла можно посмотреть тут
Структуру файла pom.xml можно увидеть по этой ссылке.

Далее добавляем базовый класс Bot.java, который и будет реализовывать все наше взаимодействие с с сервисами Telegram. Работать мы будем с помощью LongPolling, т.к. этот метод не требует сертификатов шифрования и запускаться может с любой машины, которая имеет Java у себя на борту.
Для этого мы наследуемся от класса TelegramLongPollingBot и реализуем базовые методы:
public void onUpdateReceived(Update update)
public String getBotUsername()
public String getBotToken()

И от себя нам нужно будет добавить процедуру, которая будет подключать наш бот к TelegramAPI:
public void botConnect()

import lombok.AllArgsConstructor; import lombok.Getter; import lombok.NoArgsConstructor; import lombok.Setter; import org.apache.log4j.Logger; import org.telegram.telegrambots.TelegramBotsApi; import org.telegram.telegrambots.api.objects.Update; import org.telegram.telegrambots.bots.TelegramLongPollingBot; import org.telegram.telegrambots.exceptions.TelegramApiRequestException;  @AllArgsConstructor @NoArgsConstructor public class Bot extends TelegramLongPollingBot {     private static final Logger log = Logger.getLogger(Bot.class);      final int RECONNECT_PAUSE =10000;      @Setter     @Getter     String userName;     @Setter     @Getter     String token;      @Override     public void onUpdateReceived(Update update) {         // TODO: 11/18/2019 добавить обработку полученных сообщений         log.debug("new Update recieve");     }      @Override     public String getBotUsername() {         return userName;     }      @Override     public String getBotToken() {         return token;     }      public void botConnect() {         TelegramBotsApi telegramBotsApi = new TelegramBotsApi();         try {             telegramBotsApi.registerBot(this);             log.info("TelegramAPI started. Look for messages");         } catch (TelegramApiRequestException e) {             log.error("Cant Connect. Pause " + RECONNECT_PAUSE / 1000 + "sec and try again. Error: " + e.getMessage());             try {                 Thread.sleep(RECONNECT_PAUSE);             } catch (InterruptedException e1) {                 e1.printStackTrace();                 return;             }             botConnect();         }     } } 

В принципе все. Данный код умеет подключаться к серверам Телеграмм и при получении адресованных ему сообщений будет фиксировать в лог файл информацию, что он получил Update.
Давайте создадим класс, который и будет запускать наше приложение.
Этим займется класс App.java. Ссылка на файл: тут

package com.example.telegrambot;  import com.example.telegrambot.bot.Bot; import org.apache.log4j.Logger; import org.telegram.telegrambots.ApiContextInitializer;  public class App {     private static final Logger log = Logger.getLogger(App.class);      public static void main(String[] args) {         ApiContextInitializer.init();         Bot test_habr_bot = new Bot("test_habr_bot", "1012522162:AAHLvPVqKF48LdqnsvS3l5YrJfvFey6dBa0");         test_habr_bot.botConnect();     } }

Как вы видите, для работы бота нам понадобятся только «имя бота» и «токен», которые мы и передадим в конструкторе нашего класса Bot.

Имя и токен для бота вы можете получить у отца всех ботов :), написав ему в телеграмме.
Его ник: @BotFather
Общение с ним очень простое и лаконичное.

По команде

/newbot

В результате у вас должен получиться такой диалог:

Так же здесь пишут, что аккуратнее, никому не показывайте эту информацию, иначе кто-то другой сможет управлять вашим ботом 🙂

Вы скажите, что я не очень аккуратен… Возможно, но отец ботов позволяет нам менять токены и отзывать те, что попали в публичный доступ. Потому с попробовав подключиться с моими данными, вы получите такое сообщение:

2019-12-04 13:44:25,252[DEBUG][main ][ com.example.telegrambot.bot.Bot] - Bot token: 1012522162:AAF5D49N4NreEJfCk0aOsC-UnmIu_GLkoyc
2019-12-04 13:44:26,613[ERROR][main ][ com.example.telegrambot.bot.Bot] - Cant Connect. Pause 10sec and try again. Error: Error removing old webhook

Так что с моими данными вам подключиться не получится. Регистрируйте свои. Новые данные укажите в классе App.java

Теперь запустив метод main в классе App мы позволим нашему боту подключиться и ждать новых сообщений. О своих действиях и попытках он напишет нам в консоле.

Log4j

Помните, выше я говорил о полезности библиотеки log4j. И вот тут для любопытных открывается клондайк полезных данных.
В файле log4j.properties уже прописаны базовые настройки для логирования и конкретные уровни логирования для сторонних классов и для тех, которые работают в нашем боте.
log4j.rootLogger= error, file
log4j.logger.com.example.telegrambot.App = debug, stdout
log4j.logger.com.example.telegrambot.bot.Bot = debug, stdout

Базовый уровень логирования у нас указан как Error.
Для классов Bot и App указан вывод логов на уровне Debug.
Что это за уровни и чем отличаются — вы легко найдете в гугле.

Если хотите посмотреть, как и в каком порядке отрабатывает библиотека Телеграм все ваши действия — переключите режим общего логирования на уровень ниже: info или debug.
И при запуске приложения вы в консоли увидите, сколько всего интересного происходит в процессе подключения, работы. Сколько раз опрашиваются ваши функции с именем и токеном бота.

Уровни логирования меняются вот этой строчкой:
Чтобы получить логи по уровню info, ставите вот так:
log4j.rootLogger= info, file
Для уровня debug, вот так:
log4j.rootLogger= debug, file

И в заключении

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

@Override     public void onUpdateReceived(Update update) {         log.debug("Receive new Update. updateID: " + update.getUpdateId());          Long chatId = update.getMessage().getChatId();         String inputText = update.getMessage().getText();          if (inputText.startsWith("/start")) {             SendMessage message = new SendMessage();             message.setChatId(chatId);             message.setText("Hello. This is start message");             try {                 execute(message);             } catch (TelegramApiException e) {                 e.printStackTrace();             }         }     }

Как видно из кода бот делает следующее:

  • Получает апдейт и фиксирует в лог его айди номер.
  • Достает из переданного сообщения ID чата и собственно текст сообщения
  • Проверяет, не является ли этот текст командой «/start»
  • И в случае успешного сравнения создает сообщение в ответ и отправляет его в чат, с полученным ранее ID

Надеюсь вам было полезно и интересно.

В дальнейшем я покажу вам, как в моих ботах реализуется:

  • использование различных команд
  • привязка этих команд к обработчикам
  • многопоточность: независимое получение и отправка сообщений
  • форматирование отправляемых сообщений
  • работа с кнопками и колбеками
  • редактирование старых сообщений

На этой базе в паблик доступе у меня сейчас работают 2 моих бота.
Одного вы знаете — это помощник в планировании мероприятий.
А второй — Дерзкий киноман. Он очень любит фильмы и очень много о них знает. А еще больше он любит делится с вами своими знаниями. Он ведет свой канал в телеграмме, в котором сам решает, какие фильмы ему нравятся и предлагает их вам. Он умеет формировать индивидуальные подборки по жанрам и создавать подписку на персональные рекомендации. Он умеет находить такие шедевры, о которых вы никогда не слышали и даже не знали как такие фильмы вообще можно найти.
Например, как вы думаете, существуют ли фильмы с такой «дикой» комбинацией жанров, как: документальный, ужасы, комедия.
А вот бот по команде
фильм комедия документальный ужасы топ 2010-
Скажет, что таких фильмов с 2010 по текущий момент сняли аж 6 штук 🙂

Как работать с подобными командами, как разбирать строки и последовательности команд мы рассмотрим с вами в следующих публикациях.

Спасибо вам за внимание. Программируйте в удовольствие 🙂

FavoriteLoadingДобавить в избранное
Posted in Без рубрики

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

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