У нас уже есть несколько статей и проектов с ботами для телеграма, но это были учебные проекты — мы на них учились, но реальной пользы они не приносили. Настало время это исправить и написать полноценного рабочего бота в помощь нашей редакции.
Какую задачу решаем
Проблема: сейчас у нас есть новостная редакция — её сотрудники каждый день читают новости в интернете и отбирают интересные. Но новостей много, а сотрудников мало, поэтому иногда интересные новости проходят мимо нас.
Что можно сделать: сказать всем, что если нашли интересную новость — присылайте её нам напрямую, в личные сообщения в телеграме. Но если новостей окажется слишком много, то у редактора новостей в личке начнётся ад.
Решение: сделать телеграм-бота, которому можно отправить сообщение, а он перешлёт его куда нужно. Чтобы не плодить личные сообщения от бота, можно сделать так:
- Сделать внутренний чат новостной редакции
- Добавить в него бота
- Настроить бота так, чтобы он отправлял сообщения пользователей в этот чат.
Что в итоге: когда у отдела новостей есть время, они заглядывают в этот чат и видят, кто что написал и что из этого можно взять в работу. Лишние сообщения не приходят, личные чаты не засоряются.
Сложный вариант — написать своего бота и поставить его на сервер (мы не стали так делать)
Кажется, что если мы — издание про технологии и у нас есть программисты и свои виртуальные серверы, то проще всего будет написать бота на питоне и отправить на сервер. Но на самом деле с таким подходом есть много сложностей:
- нужно найти программиста на питоне, который сможет написать код;
- этот код потом нужно поддерживать, если понадобится добавить новые функции;
- нужно подготовить сервер к постоянной фоновой работе python-кода;
- следить за тем, чтобы бот работал круглосуточно, а если падал, то сам умел перезапускаться;
- следить за самим сервером и в случае чего — перезапускать его и все программы на нём.
Всё это требует внимания, времени и квалификации. В итоге простая задача превращается в целый рабочий процесс с отдельным человеком, который отвечает за бесперебойную работу сервера и всего, что на нём крутится.
👉 Свой бот на своём сервере — это правильный подход, если у вас в компании уже настроен подобный процесс и есть отдельная команда, которая за это отвечает. В маленькой команде разворачивать всю эту систему ради одного бота — перебор.
Простой вариант — использовать конструктор
Мы уже писали про онлайн-конструкторы ботов и собирали тестового бота в одном из них. С таким подходом мы решаем большинство проблем из первого варианта:
- не нужно следить за сервером, потому что за это отвечает сервис с конструктором;
- не нужно искать программиста с необходимой квалификацией;
- чем меньше кода, тем проще поддерживать готовый продукт.
Но появляются и свои риски и особенности:
- сервис может закрыться, и бот перестанет работать;
- если нужно добавить что-то, что не предусмотрено сервисом, то либо это будет сложно и громоздко, либо вообще не получится сделать.
👉 Что касается оплаты, то платить за ежемесячную подписку за сервис в среднем получается дешевле, чем платить системному администратору и программисту за настройку и поддержку всех программ.
Это наш выбор.
Логика проекта
- Создаём нового бота и добавляем его в чат.
- Получаем нужные параметры для настройки бота.
- Создаём бота в конструкторе.
- Настраиваем чат для полноценной работы в редакции.
Сделаем всё по очереди.
Создаём нового бота и добавляем его в чат
Регистрируем нового бота через @BotFather — делаем это точно так же, как в материале про бота на питоне. Мы создали бота @Eto_v_Kod_bot и назвали его «Это в Код»:
Теперь создаём публичный чат и добавляем в него бота. Публичный чат нам нужен, чтобы получить ID чата, потом сделаем его приватным. Именно в этот чат бот будет пересылать полученные сообщения.
Узнаём ID чата
В телеграме у каждого чата есть свой ID — уникальный идентификатор, с помощью которого можно отличать один чат от другого. Чтобы наш бот пересылал сообщения в нужный чат, узнаем его ID. Для этого сначала пишем боту любое сообщение (неважно, что он ещё не работает), а затем делаем такую магию — переходим в браузере по адресу
https://api.telegram.org/bot<ВАШ_ТОКЕН>/getUpdates
👉 Перед тем, как это делать, отключите бота от конструктора или выключите его там в настройках, иначе магия не сработает.
Это значит, что мы должны:
- Взять наш токен.
- Подставить его вместо <ВАШ_ТОКЕН>.
- Скопировать всё, что получилось.
- Вставить результат в адресную строку и перейти по этому адресу.
Например, в нашем случае адрес будет такой:
https://api.telegram.org/bot1738394823:
AAF4h6dkgjKH88lKanJ899lpH-Jqkd5k2399sjKo/getUpdates
Когда мы перейдём по этому адресу, браузер нам напишет что-то такое:
{"update_id":8393,"message":{"message_id":3,"from":{"id":7474,"first_name":"AAA"},"chat":{"id"-1034423424553:,"title":"Eto_v_Kod"},"date":25497,"new_chat_participant":{"id":71,"first_name":"NAME","username":"Eto_v_Kod"_bot"}}}
Нам нужно то, что написано после chat id: -1034423424553
— это и есть ID нашего чата, дефис перед числом тоже важен.
👉 Теперь чат снова можно сделать приватным, на ID это не повлияет.
Собираем бота в конструкторе — стартовый экран
Мы используем конструктор BotMother — мы уже рассказывали, как с ним работать и собрать своего тестового бота. Если что-то по ходу описания будет непонятно, почитайте сначала ту статью.
Стартовый экран — это то, что выполняет бот по команде /start. Сделаем на стартовом экране выбор из двух кнопок: отправить новость и отправить статью:
Теперь нам нужно сделать так, чтобы при нажатии на каждую из этих кнопок бот делал то, что нам нужно. Для этого создаём два экрана: «Предложить новость» и «Предложить статью» и настраиваем действия по кнопкам:
Собираем экраны «Предложить новость» и «Предложить статью»
Логика экрана будет такой:
- Пишем текст с пояснением, что нужно сделать — написать текст новости или дать ссылку на неё.
- Сохраняем ответ в отдельной переменной news1.
- Отправляем в наш новостной чат сообщение от бота с именем посетителя, который написал новость, и текст самой новости.
- Чтобы сообщения не слипались, вдогонку отправляем в тот же чат отбивку — линию-разделитель из нескольких дефисов.
- Если мы дошли до последнего пункта и всё прошло без ошибок — показываем посетителю экран «Всё хорошо», а если на каком-то этапе была ошибка — сразу перебрасываем его на экран «Что-то не так».
Сначала посмотрим на готовый экран, а потом разберём его по шагам:
Каждую отправку мы сделали через запрос POST к API телеграма. Когда сервер телеграма получает специальным образом подготовленный запрос, он выполняет какое-то действие — это называется работа по API и про это у нас есть отдельная статья.
В нашем случае все запросы используют метод sendMessage, у которого всегда есть два параметра:
- ID получателя.
- Текст сообщения.
В общем виде команда выглядит так:
https://api.telegram.org/bot<ТОКЕН_БОТА>/
sendMessage?chat_id=<ID_чата>&text=<Сообщение>
Мы уже знаем токен бота и ID чата, куда хотим отправить сообщение — это ID нашего чата, который мы выяснили до этого. Подставляем эти значения и получаем команду:
https://api.telegram.org/bot1738394823:
AAF4h6dkgjKH88lKanJ899lpH-Jqkd5k2399sjKo
/sendMessage?chat_id=-1034423424553&text=<Сообщение>
Первым сообщением мы отправляем имя того, кто предложил новость, и сам текст новости, поэтому сообщение будет выглядеть так:
Новость, отправил @{{this_user.username}} → {{news1}}
Здесь {{this_user.username}}
и {{news1}}
— это переменные. Первая переменная стандартная в конструкторе BotMother, а вторую сделали мы сами на этом же экране. Полный текст запроса выглядит так:
https://api.telegram.org/bot1738394823:
AAF4h6dkgjKH88lKanJ899lpH-Jqkd5k2399sjKo/sendMessage?
chat_id=-1034423424553&text=Новость, отправил
@{{this_user.username}} → {{news1}}
Сделаем по аналогии вторую команду, которая присылает отбивку в чат, чтобы отделить одну новость от другой:
https://api.telegram.org/bot1738394823:
AAF4h6dkgjKH88lKanJ899lpH-Jqkd5k2399sjKo/
sendMessage?chat_id=-1034423424553&text=------------
👉 Вместо двух запросов на отправку сообщения можно было использовать функцию API телеграма forvardMessage, которая просто пересылает сообщения. Для этого нам понадобился бы порядковый номер сообщения в переписке. Если бы мы писали бота на питоне, с этим бы не было никаких проблем, но в этом конструкторе проще сделать отправкой, как у нас.
Точно так же собираем экран «Предложить статью»:
Собираем экраны успеха и ошибки
Чтобы было что показывать пользователям в случае успеха и ошибки, соберём два новых экрана. Экран успеха будем показывать только в конце последнего действия — это значит, что всё выполнилось хорошо. Переход на экран ошибки добавим к каждому действию в запросе, которое реагирует на ошибку.
В конце обоих экранов добавим переход на стартовый экран. Так пользователь сможет сразу отправить ещё одну новость или статью без лишних команд боту:
Финальная схема
У нас получился очень простой бот, который решает главную задачу редакции на этом этапе: бот пересылает все сообщения пользователей в один чат, чтобы все внешние материалы собирались в одном месте.
Что дальше
Нажимаем кнопку «Сохранить» в конструкторе, и всё — бот готов к работе. Теперь можно добавить картинку и описание.