Как написать робот для Telegram на java с использованием Eclipse

Эта статья — краткое руководство — как в среде Eclipse написать самый простой рабочий шаблон робота для телеграмма, который в последствии можно расширять и дописывать до полноценного бота.

  1. Открываем eclipe и создаем новый Java проект
  2. Качаем отсюда (выбирать «with-dependencies») библиотеку для создания Telegram роботов
  3. Добавляем эту библиотеку в проект
  4. Создаем класс test.SimpleBot со следующим содержимым:
  5. Открываем Telegram
  6. Открываем в браузере https://telegram.me/botfather
  7. Нажимаем на кнопку «Send message»: sendmsg
  8. Переходим Telegram и выбираем BotFather:
  9. Вводим /start
  10. Вводим /newbottbo1
  11. Теперь нужно будет написать имя вашего робота
  12. После выбора имени BotFather предложит выбрать имя пользователя вашего робота. Оно должно быть уникальным. После выбора имени пользователя, его нужно вписать в нашем классе вместо ИМЯ_ПОЛЬЗОВАТЕЛЯ_ВАШЕГО_БОТА.tbot2
  13. После выбора имени пользователя BotFather напишет, что ваш робот успешно сконфигурирован и выведет токен после слов «Use this token to access the HTTP API:». Полученный токен нужно вписать в классе вместо ВАШ_ТОКЕН.tbo3
  14. Теперь запускаем в Eclipse созданного робота.
  15. Чтобы протестировать работу робота нужно ввести в браузере https://telegram.me/ИМЯ_ВАШЕГО_РОБОТА
  16. Нажать на «Send message»
  17. Вернуться в Telegram где выбрать созданного робота
  18. Нажать на «Start», на любое сообщение робот должен отвечать «Я не знаю что ответить на это».

Собственно, в методе onUpdateReceived сравниваются отправленный пользователем текст с командами робота и отправляются соответствующие сообщения. Чтобы  изменить робота просто добавьте свои команды в этот метод.

1 Комментарий

    • Бот будет работать все время пока ваша программу будет запущена. Естественно после закрытия Eclipse программа остановится.
      Я запускаю программу бота на отдельном сервере, который у меня постоянно работает.

    • В методе sendMsg, сразу после строчки «sendMessage.enableMarkdown(true);» добавить следующий код (пример клавиатуры из четырех кнопок).
      (И не забудьте обновить библиотеку, в статье по ссылке она обновлена)

    • inaword,

      После добавления вирт клавиатуры, все появилось и все вроде работает, но
      сыпет эксепшены:

      дек 06, 2016 12:00:28 PM org.telegram.telegrambots.logging.BotLogger severe
      SEVERE: BOTSESSION
      org.telegram.telegrambots.exceptions.TelegramApiRequestException: Error getting updates: [409] Conflict: terminated by other long poll or webhook
      at org.telegram.telegrambots.api.methods.updates.GetUpdates.deserializeResponse(GetUpdates.java:96)
      at org.telegram.telegrambots.updatesreceivers.DefaultBotSession$ReaderThread.run(DefaultBotSession.java:177)

      дек 06, 2016 12:00:28 PM org.telegram.telegrambots.logging.BotLogger severe
      SEVERE: BOTSESSION
      org.telegram.telegrambots.exceptions.TelegramApiRequestException: Error getting updates: [409] Conflict: terminated by other long poll or webhook
      at org.telegram.telegrambots.api.methods.updates.GetUpdates.deserializeResponse(GetUpdates.java:96)
      at org.telegram.telegrambots.updatesreceivers.DefaultBotSession$ReaderThread.run(DefaultBotSession.java:177)

      дек 06, 2016 12:00:28 PM org.telegram.telegrambots.logging.BotLogger severe
      SEVERE: BOTSESSION
      org.telegram.telegrambots.exceptions.TelegramApiRequestException: Error getting updates: [409] Conflict: terminated by other long poll or webhook
      at org.telegram.telegrambots.api.methods.updates.GetUpdates.deserializeResponse(GetUpdates.java:96)
      at org.telegram.telegrambots.updatesreceivers.DefaultBotSession$ReaderThread.run(DefaultBotSession.java:177)

      как убрать?

  1. update.getMessage();
    Получит сообщение если такое вообще есть. (это личка)
    А как быть с груп чатами? У меня он не отлавливает сообщения.
    — Бот в чате есть.
    — сообщения пробовал отправлять с «/»
    — пробовал переключить «/setprivacy» на «Disable»

    • Надо/setprivacy» на «Disable» и бота надо исключить из группы и заново добавить. Была такая же проблема.

    • Вся логика должна быть в методе onReceiveUpdate:
      1. Бот ожидает сообщение от пользователя
      2. Читает сообщение и если понимает его то отвечает

    • Уроков по Java очень много и много очень хороших и простых книг. Но если есть интересующие вас темы по каким-то слабо освещенным вопросам, то можно подумать…

  2. НЕ пашет.

    Exception in thread «main» com.google.inject.ConfigurationException: Guice configuration errors:

    1) No implementation for org.telegram.telegrambots.generics.BotSession was bound.
    while locating org.telegram.telegrambots.generics.BotSession

    1 error
    at com.google.inject.internal.InjectorImpl.getProvider(InjectorImpl.java:1045)
    at com.google.inject.internal.InjectorImpl.getProvider(InjectorImpl.java:1004)
    at com.google.inject.internal.InjectorImpl.getInstance(InjectorImpl.java:1054)
    at org.telegram.telegrambots.ApiContext.getInstance(ApiContext.java:25)
    at org.telegram.telegrambots.TelegramBotsApi.registerBot(TelegramBotsApi.java:83)
    at com.nastin.bot.SimpleBot.main(SimpleBot.java:19)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:147)

    • Да действительно. Библиотеку разработчики изменили. Статью обновил.
      В main добавьте самую первую строчку:

  3. Спасибо еще раз! Благодаря Вашему вступительному уроку по созданию бота на джаве, мне удалось двинуться дальше. Хотел у Вас спросить такое: сдеть заложенна схема общения с ботом вопрос-ответ. Как можно сделать так, что бы бот через определленый промежуток времени присылал уведомления?

    • К сожалению с инлайн режимом не работал, но думаю ответ кроется в этой строчке:
      update.getCallbackQuery().getData() — возвращает ответ.

      А вот пример.

    • Пример отправляет сообщение «Вам пришли новости» каждые пять секунд после того как пользователь ввел команду «/start».

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

    • Язык интерфейса меняется следующим образом:

      • Подписываетесь на робот @telerobot
      • Пишите ему: Locale Android (если у вас андройд) или Locale iOS — соответственно если iphone
      • Загрузите файл нажатием на сообщение с ним. Нажмите на знак с тремя точками в блоке сообщения и выберите «Apply localization file». Если у вас iPhone, то нажмите на файл выберите “Apply localization file”.
  4. inaword,

    Будьте добры напишите пожалуйте пример :

    для сценария
    погода — клик

    request:/weather

    response: current weather click Send /current, or weather for three days sends /weatherthree

    if(message == «/current»){

    sendMsg(message, current weather);
    } else if(message == «/weatherthree»)

    respone:enter your location

    request:moscow

    response:прогноз погоды

    Заранее огромное спасибо

    • Какую ошибку выдаёт? Вариантов не много — либо библиотека другой версии, либо вы забыли подключить библиотеку.

  5. Попробовал развернуть пример в NetBeans — работает! Только ссылка на гитхабовскую библиотеку уже битая.

    У меня следующая задача: клиенты пишут боту вопросы, эти вопросы бот перефутболивает операторам (point-to-point), операторы отвечают боту, бот возвращает ответы к соответствующим клиентам.

    Возникает вопрос с параллелизмом: если пишут сразу несколько клиентов, то не перемешаются ли сообщения (в одной сессии)? И как переслать ответ нужному клиенту — запоминать ID сообщения или чата?

  6. Добрый день, уважаемый автор.
    Большое вам спасибо за небольшой, но крайне информативный урок.
    Можете ещё подсказать куда копать в решении задачи написания собственного маленького клиента к телеграмму под android?
    Интернет даёт ссылку на официальную библиотеку tdlib (Telegram Database Library) но я никак не могу найти ни одного достаточно простого примера её использования.

  7. Добрый день, ругается на setOneTimeKeyboad, List и ArrayList. Видать не хватает какой-то библиотеки, хотя я установил самую последнюю версию. (это из кода с виртуальной клавиатурой, в сообщении выше)

    • setOneTimeKeyboad(false); — тут пропущена буква r в слове Keyboard. должно быть:
      setOneTimeKeyboard(false);
      Вы скопировали текст из комментария. Там поправлю.

      Насчет List и ArrayList — это стандартные коллекции из библиотеки Java. Добавьте импорты:

      import java.util.List;
      import java.util.ArrayList;

  8. Добрый день, запускаю и получаю ошибку. Интернет через прокси, может в этом дело?

    авг 16, 2017 5:19:34 PM org.apache.http.impl.execchain.RetryExec execute
    INFO: Retrying request to {s}->https://api.telegram.org:443
    org.telegram.telegrambots.exceptions.TelegramApiRequestException: Error executing setWebook method
    at org.telegram.telegrambots.bots.TelegramLongPollingBot.clearWebhook(TelegramLongPollingBot.java:56)
    at org.telegram.telegrambots.TelegramBotsApi.registerBot(TelegramBotsApi.java:120)
    at test.SimpleBot.main(SimpleBot.java:19)
    Caused by: java.net.SocketException: Socket is not connected: connect
    at java.net.DualStackPlainSocketImpl.connect0(Native Method)

  9. Вроде всё сделал по уроку, а выдаёт ошибку. В чём может быть причина?
    Exception in thread «main» java.lang.ClassNotFoundException: Main
    at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
    at java.lang.Class.forName0(Native Method)
    at java.lang.Class.forName(Class.java:264)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:123)

    код
    package test;

    import org.telegram.telegrambots.exceptions.TelegramApiException;
    import org.telegram.telegrambots.ApiContextInitializer;
    import org.telegram.telegrambots.TelegramBotsApi;
    import org.telegram.telegrambots.api.methods.send.SendMessage;
    import org.telegram.telegrambots.api.objects.Message;
    import org.telegram.telegrambots.api.objects.Update;
    import org.telegram.telegrambots.bots.TelegramLongPollingBot;

    public class SimpleBot extends TelegramLongPollingBot {

    public static void main(String[] args) {
    ApiContextInitializer.init();
    TelegramBotsApi telegramBotsApi = new TelegramBotsApi();
    try {
    telegramBotsApi.registerBot(new SimpleBot());
    } catch (TelegramApiException e) {
    e.printStackTrace();
    }
    }

    @Override
    public String getBotUsername() {
    return «———«;
    }

    @Override
    public String getBotToken() {
    return «—————————«;
    }

    @Override
    public void onUpdateReceived(Update update) {
    Message message = update.getMessage();
    if (message != null && message.hasText()) {
    if (message.getText().equals(«/help»))
    sendMsg(message, «Привет, я робот»);
    else
    sendMsg(message, «Я не знаю что ответить на это»);
    }
    }

    private void sendMsg(Message message, String text) {
    SendMessage sendMessage = new SendMessage();
    sendMessage.enableMarkdown(true);
    sendMessage.setChatId(message.getChatId().toString());
    sendMessage.setReplyToMessageId(message.getMessageId());
    sendMessage.setText(text);
    try {
    sendMessage(sendMessage);
    } catch (TelegramApiException e) {
    e.printStackTrace();
    }
    }

    }

  10. Подскажите как отправить документ в чат, пробовал аналогичным образом метод sendDocument создать, но ошибки:
    org.telegram.telegrambots.exceptions.TelegramApiRequestException: Error sending document: [400] Bad Request: wrong persistent file_id specified: Wrong character in the string
    at org.telegram.telegrambots.api.methods.send.SendDocument.deserializeResponse(SendDocument.java:165)
    at org.telegram.telegrambots.bots.DefaultAbsSender.sendDocument(DefaultAbsSender.java:163)
    at Bot.sendDocument(Bot.java:103)
    at Bot.onUpdateReceived(Bot.java:66)
    at org.telegram.telegrambots.updatesreceivers.DefaultBotSession$HandlerThread.run(DefaultBotSession.java:271)

  11. Привет,
    у меня есть бот который отвечает на запросы и есть кнопки внизу экрана(благодаря inaword). Мне требуется сделать что бы когда пользователь нажимал на кнопки, бот задавал вопросы, человек отвечает на несколько вопросов, и так что бы я потом получил все данные которые ввел пользователь.

    Спасибо.
    Статья агонь!

  12. Господа, только начал изучать Java, поэтому малость «подтормаживаю»… Нужна ваша помощь…!
    Есть такая вот «хотелка»…
    Требуется, чтобы бот получал от пользователей некие данные (числовые, целые), производил бы с ними некоторые операции и отправлял бы результат в определенную группу в Telegram… Например:
    Один из пользователей отправил боту такой набор данных —
    500 (Дима собрал 500 яблок в саду)
    15 (он распределил их по 15-ти корзинам)
    6 (в шести корзинах были отобраны только красные яблоки)
    4 (в четырех — только зелёные)
    5 (в пяти корзинах — смешанного цвета)

    Таких пользователей, к примеру — 7.
    Задача бота, например, сделать сумму по каждой из позиций и отправить в группу:
    1. Упорядоченные данные по каждому из пользователей
    2. Итог (сумму) по всем пользователям.

    Возможно? Реально? Насколько сложно? Где и что почитать? Может кто черкнёт какие «наброски»? Спасибо! И да, статейка годная!

  13. Привет, спасибо большое за столь информативную статью, но у меня есть вопрос: Как просто отправить сообщение с бота? Я имею ввиду вводишь код, перезагружаешь бота, и он отправляет сообщение. Все мои попытки проводили к тому, что бот отправлял сообщение только отвечая на реплику юзера.

  14. Я использую Ability и прокси. У меня нет теперь onReceiveUpdate. У меня есть такая штука где я подставляю инлайн клавиатуру и есть обработчик

    Consumer action = upd -> responseHandler.replyToButtons(getChatId(upd), upd.getCallbackQuery().getData());

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

  15. Может кто столкнулся таким же:
    java: cannot find symbol
    symbol: method sendMessage(org.telegram.telegrambots.meta.api.methods.send.SendMessage)

    То вот решение: https://ru.stackoverflow.com/questions/775401/telegram-bot-sendmessage-is-deprecated-in-java
    В кратце заменить sendMessage на execute . Кто более опытнее, добавьте может, пока только учусь, может мой совет не корректен 🙂

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