Тема ботов была изъезжена до дыр уже многими блогами, постами, блогпостами и прочими кодерами. Однако в большинстве своём это боты на условных Python/JS/PHP, в которых обычно можно сделать как получится и всё вроде как даже заработает. Я же в своё время (почти) ушел из этих языков в мир строгой типизации и объектной ориентированности Java, а позже и в Kotlin. На момент, когда мне было интересно написать своего первого бота, на рынке github из интересных присутствовала только библиотека pengrad/java-telegram-bot-api, однако лично для меня она имела один фатальный недостаток: она на тот момент полностью дублировала Telegram Bot API, то есть фактически являлась прокладкой, которая кроме взаимодействия через Java классы больше ничего не давала.
Так я пришел к идее написать свою библиотеку для Telegram Bot API. Первая покрывающая основной API версия заняла у меня месяц, но выходили обновления, пользователи предлагали идеи по улучшению, да и мне часто не нравилось делать какие-то вещи руками на постоянной основе. В итоге, библиотека развивается по сей день, там есть удобный API, свой DSL, но что главное — она не утратила свою исходную идею о том, чтобы строго типизировать работу с Telegram Bot API.
Создаём Telegram-бота с нуля на Python. Урок #1. Echo-bot.
Как вообще работают боты в Telegram
У ботов в телеграме есть масса ограничений. На красивые циферки очень часто можно посмотреть тут, но если вкратце (ссылка на BotFather, чтобы дальше не повторяться) (скорее всего, будет пополняться для расширения кругозора):
- По-умолчанию бот не видит сообщения других пользователей в группах до прямого обращения к боту командой (это можно поменять через group privacy настройку в BotFather)
- По-умолчанию боты не инлайновые. Инлайновые боты — это как бот для гифок, то есть когда вы вводите ник бота, добавляете пробел и он вам предлагает варианты. После нажатия на вариант отправляется сообщение в чат с контентом, предложенным ботом (тоже включается через настройку в BotFather)
- Кроме того, после включения инлайн-режима для бота, нужно будет отдельно включить поддержку инлайн-режима для локаций, когда бот может выдать результаты на основе геолокации пользователя
В среднем же пайплайн разработки бота выглядит следующим образом:
- Идея
- Создание тестового бота через BotFather с помощью /newbot
- Кодинг, исправление ошибок
- Хостинг
Итак, бот
- Топаем к BotFather и создаём бота через /newbot
- Для простоты открываем этот шаблон на гитхабе и создаём из него свой проект
Далее можно проследовать в Readme шаблона и настроить проект, а можно просто начать кодить в вашем файле App.kt . Итак, что же у нас есть из коробки:
suspend fun main(args: Array) < val bot = telegramBot(args.first()) // 1 val scope = CoroutineScope(Dispatchers.Default) // 2 bot.buildBehaviour(scope) < // 3 val me = getMe() onCommand(«start», requireOnlyCommandInMessage = true) < reply(it, «Hello, I am $») > >.join() // 4 >
- Создаём бота. Можно заменить args.first() на явную передачу вашего токена, полученного при создании бота через BotFather
- Создание CoroutineScope . Почитать о корутинах в котлине можно тут, но если вкратце — они позволяют производить работу с ботом асинхронно
- Начало самого интересного. В коллбэке для buildBehaviour мы будем составлять логику нашего бота в этом туториале
- Заставляем нашу программу не заканчиваться после составления логики бота и его запуска
Теперь давайте заменим код в логике бота на следующий:
Разработка Telegram Bot на Python. (1. Создание эхо-бота)
onContentMessage < // 1 execute( // 2 it.content.createResend(it.chat.id) // 3 ) >
Готово ? Давайте теперь разберёмся, что же тут происходит:
- Данный метод позволяет нам отдельно получать сообщения с некоторым контентом: медиа, локации, текст и т.д.
- execute — основной метод всей библиотеки. Этот метод отправляет запрос в систему телеграма. Скорее всего, напрямую вы будете использовать его очень редко, но знать о нём полезно
- Магия с createResend заключается в том, что практически любой контент в телеграме может быть переотправлен. По этой причине в библиотеке были сделаны методы переотправки контента — они автоматически формируют запрос на отправку сообщения с тем же контентом
Теперь можно сделать что-то по-интересней. Давайте научимся реагировать на команды:
onCommand(«start») < // 1 reply(it, «Привет, я пока что умею не так много, но скоро всему научусь!») // 2 >onCommand(«help»)
- Этот коллбэк будет вызываться каждый раз при отправке /start , но важно знать, что он будет вызываться при наличии в сообщении только этой команды
- Отвечаем текстовым сообщением. it тут обозначает само сообщение
Ну и напоследок давайте попробуем переписать часть с onContentMessage так, чтобы попутно сохранять части текстовых сообщений:
fun save(sources: List) < // работа с сохранением частей текста println(sources.makeString()) // 3 >onContentMessage < it.content.asTextContent() ?.let < content ->// 1 save(content.textSources) // 2 > execute(it.content.createResend(it.chat.id)) >
- asTextContent() проверяет, является ли контент сообщения текстом и вызывает let , если да
- content.textSources создаст список TextSource объектов, с этим списком потенциально можно:
- Сохранять (у TextSource есть сериализатор для kotlinx.serialization )
- Копировать, перемещать, модифицировать
- Использовать для форматирования — сурсы могут быть превращены в стандартные текстовые части телеграма
Заключение
Итак, мы создали бота, который:
- Умеет отвечать на простые команды /start и /help
- Умеет переотправлять полученные сообщения отправителю
- Отбирает текстовые сообщения и производит операции с их контентом
Далее остаётся только развивать бота насколько хватит фантазии. Например, можно выделить модули в функции/плагины, как я это сделал в своём PlaguBotе.
Для более подробной информации о проекте можно посмотреть его основную страницу, вики, проект с примерами и заглянуть в наш телеграм канал.
Источник: savepearlharbor.com
Задание 61. Бот для телеграмма
Задание: реализовать программу-бота для телеграмма, которая будет отвечать на запросы пользователя (обычного человека, использующего телеграмм) и предоставлять для него полезную информацию.
Тема-пример этой статьи Бот-эхо :
- Бот отвечает таким же сообщением, какое пользователь отправил
- Бот шлет Привет! Как дела? в 22:39 каждый день
Тема на оценку Бот-Remembrall :
- Боту можно отправить сообщение о чем-то важном, например 20:00 загамать в доту , 5 марта сделать дз по информатике
- Бот предупредит о важном событии в указанное время (или за день до даты)
- Придумать какую-нибудь дополнительную полезную функциональность
- Опционально Напоминание может содержать геотег (метку на карте)
- Опционально Предупреждать за N минут до звонка ( N — настраиваемое)
- Опционально Да что угодно!
- Генератор мемов (пользователь выбирает картинку и указывает текст для наложения)
- Оповещатель о новых сообщениях в vkontakte
- Выдаватель новых/случайных анекдотов/новостей из указанной пользователем группы vkontakte
Другие темы возможны по согласованию со мной.
В инструкции описано как сделать бота на Java , но Python для данной задачи на мой взгляд подходит лучше, так что любой другой язык для этого задания разрешен. Здесь есть ссылки для многих языков.
Дедлайн:
1) Про ботов
Общая идея в том, что вы регистрируете своего бота в телеграмме, затем запускаете программу, которая будет определять логику бота. Эта программа подключиться к серверам телеграмма, и если кто-то отправит сообщение вашему боту — сервера телеграмма оповестят об этом вашу программу. Программа соответственно может сообщать серверам телеграмма о том, какие действия совершает бот, например отправка овтетного сообщения.
2) Регистрация бота
Чтобы ваша программа-бот могла взаимодействовать с серверами телеграмма — ее нужно зарегистрировать, т.е. получить для нее идентификатор, чтобы сервера телеграмма могли понимать с кем они работают.
Для этого надо открыть https://telegram.me/botfather и нажать SEND MESSAGE , это откроет BotFather в установленном Телеграмме.
Теперь надо попросить у него выдать для нас идентификатор (и сделать это с уважением):
- /start
- /newbot
- Указать имя бота, например PolarNickTestBot
- Указать username оканчивающийся на _bot , например polar_nick_test_bot
- В ответ вам будет выслан HTTP API (в дальнейшем ключ бота ), что-то вроде 332239602:AAHGJSrMvTxVm239c3JJzHaz239mXyEE9tI
3) Библиотека Telegram API
Все взаимодействие с серверами телеграмма обернуто в нескольких удобных библиотеках, в рамках данной статьи предлагается использовать данную библиотеку — TelegramBots.
Создайте пустой проект, назвав его например TelegramEcho .
Скачайте отсюда файл telegrambots—jar-with-dependencies.jar .
Теперь эту библиотеку надо подключить к проекту:
- File->Project Structure->Libraries
- Зеленый плюсик сверху слева -> Java
- Указать скачанный файл, нажать Ok
4) Простой echo-bot
Создаем какой-нибудь класс и пишем в нем main -функцию — точку входа в приложение:
public static void main(String[] args)
Наследуем наш класс от TelegramLongPollingBot . Например:
public class MyTelegramBot extends TelegramLongPollingBot
Не забываем все ошибки Cannot resolve symbol решать через Alt+Enter->Import class .
В данном случае появится в том числе ошибка Class must either be declared abstract or implement abstract method. . Надо реализовать эти методы, по аналогии с тем как мы это делали при обработки нажатия кнопок/движения мышек/получения сообщений в задании 41 ( Alt+Enter -> Implement methods ).
В main -функции надо инициализировать библиотеку и запустить наш бот:
ApiContextInitializer.init(); TelegramBotsApi telegramBotsApi = new TelegramBotsApi(); try telegramBotsApi.registerBot(new MyTelegramBot()); > catch (TelegramApiException e) e.printStackTrace(); >
Теперь надо действительно реализовать те абстрактные методы, которые нам достались в наследство. Два из них заполняются тривиально — теми значениями, которые вы указали или получили на шаге 2 (в процессе регистрации бота):
Осталось делать что-нибудь, когда бот получает сообщения. Это делается в onUpdateReceived :
Message message = update.getMessage(); // Получаем текст входящего сообщения System.out.println(«New message: » + message.getText()); // Пишем в консоль о том, какое сообщение было получено
Но просто записывать в консоль полученное сообщение не интересно. Давайте ответим пользователю этим же сообщением в ответ:
SendMessage sendMessage = new SendMessage(); // Создаем объект, в котором опишем сообщение, которое хотим послать в ответ sendMessage.setChatId(message.getChatId().toString()); // Укажем, что отправить это сообщение следует в чате, из которого мы получили сообщение sendMessage.setText(«Echo: » + message.getText()); // Укажем текст сообщения try sendMessage(sendMessage); // Отправим сообщение > catch (TelegramApiException e) e.printStackTrace(); // Это обработка исключительных ситуаций — на случай если что-то пойдет не так >
Еще например можно было бы отправлять это сообщение как “ответ” на входящее сообщение:
5) Дополнительные материалы
Взаимодействие с vkontakte: для этого есть библиотека, которая оборачивает взаимодействие с API. С помощью этой библиотеки можно написать бота для vkontakte.
Забор информации с произвольного сайта: для этого надо выкачивать соответствующую html-страницу, и из нее извлекать информацию. Помочь может например библиотека jsoup. Примеры работы с этой библиотеки можно нагуглить, например это.
6) Отправка задания
ВАЖНО Обратите внимание, что API-ключ бота дает доступ и контроль над ботом. Поэтому если кто-то получит доступ к этому ключу — он сможет перехватить контроль над ботом. Поэтому при отправки кода мне или кому-либо еще — обязательно удалите API-ключ бота из исходников.
Отправляйте выполненное задание ввиде zip-архива src папки, и пожалуйста:
- Тему письма называйте правильно, например: Задание 61 16-1 Полярный Коля
- Правильно названный zip-архив (или 7zip), внутри которого папка src с .java файлами, пример названия: 61_16_1_polyarniy_nikolay.zip
Источник: www.polarnick.com
Прыжок до небес: запускаем телеграм бота на Python в serverless облаке
Одним из современных архитектурных подходов в области облачных вычислений является так называемый Serverless. Этот способ запуска приложений в облаке освобождает разработчиков от нужды администрировать сервер и заботиться о чем-то, кроме кода.
Очевидно, что для такой задачи, как телеграм бот, этот подход очень удобен.
В этой статье описаны все шаги для запуска бота в Yandex.Cloud Functions. Опоры на код я не делаю. Наша основная задача сейчас — настроить запуск в облаке.
Создадим бота
Настройка Yandex.Cloud
Для работы с Яндекс.Облаком перейдите на сайт https://cloud.yandex.ru/ и войдите в свой аккаунт. Если вы все сделали правильно, вы увидите рабочий дашборд.
Cloud Functions
- Перейдите в раздел Cloud Functions
- Создайте новую функцию c названием, например, python-tg-bot .
- Укажите язык python и выберите самую последнюю версию (python3.8 на момент написания этой статьи).
- В настройках функции загрузите код бота. Скачать архив можно по ссылке. Параметры укажите как на картинке. В переменные окружения добавьте поле BOT_TOKEN и вставьте токен, полученный в самом начале. После обязательно нажмите Создать версию, чтобы запустить функцию.
- Запомним идентификатор функции (первая строка)
API-Gateway
Чтобы мы смогли получить доступ к нашей функции, нужно настроить API-Gateway.
- Перейдите в раздел API-Gateway
- Создайте новый шлюз и настройте его. Скопируйте конфигурацию и замените YOUR_FUNCTION_ID на идентификатор функции, полученный ранее.
openapi: 3.0.0 info: title: for-python-tg-bot version: 1.0.0 paths: /: post: x-yc-apigateway-integration: type: cloud-functions function_id: YOUR_FUNCTION_ID operationId: tg-webhook-function
- Запомним ссылку, по которой можно вызвать нашу функцию
Устанавливаем webhook
Теперь нужно сообщить телеграму, куда отправлять информацию о новых сообщениях.
- Установите библиотеку pip install pyTelegramBotAPI
- Запустите питоновский скрипт:
import telebot bot = telebot.TeleBot(«YOUR_TOKEN») bot.remove_webhook() bot.set_webhook(«YOUR_URL»)
Тестируем
Сделали «эхо-бота». Что дальше?
Как говорилось в начале, такой способ запустить бота очень легок для разработчика, но что же делать, если нам нужна база данных или сложные api-запросы к другим ресурсам. Все это можно реализовать в Yandex.Cloud. Например, с помощью сервисов Yandex Database (тоже serverless) или Object Storage. Отдельные сервисы можно запустить, как отдельные функции. В следующей статье, я расскажу о том, как подключить базу данных Yandex Database к боту.
Именно возможность создавать все по кусочкам и уверенность в том, что однажды настроенный модуль будет работать всегда, отличает serverless подход от простого «давайте свалим все в одну виртуальную машину».
Тарифы Yandex.Cloud
До октября 2021 года на сервисы экосистемы бессерверных вычислений будут действовать специальные тарифы. В рамках этих тарифов определенный объем услуг не будет тарифицироваться. Объем рассчитан так, чтобы у вас была возможность разработать и запустить небольшой сервис, сайт или приложение.
- Yandex API Gateway Каждый месяц не тарифицируются первые 100 000 запросов к API-шлюзам.
- Yandex Cloud Functions Каждый месяц не тарифицируются:
- первые 1 000 000 вызовов функций;
- первые 10 ГБ×час выполнения функций.
- первые 1 000 000 операций (в единицах RU);
- первый 1 ГБ/месяц хранения данных.
- Репозиторий с кодом бота
- Yandex.Cloud
- Описание тарифа free tier
Ну и напоследок напоминаю вам о нашем новом проекте vkserfing bot.
Источник: mailsgun.ru