Футбольный телеграм бот на Python (1/4): Подготовка и настройка бота
В этой серии статей мы напишем телеграм бота на python. Он работает с внешним API, запрашивает результаты футбольных матчей и выводить их в сообщении.
Когда локальная версия будет готова, разместим бота на сервере. Вместо Heroku, я выбрал отдельную виртуальную машину, что бы бот не засыпал. Это ближе к реальности.
Вся разработка разбита на этапы:
Рабочая версия бота запущена в телеграме до конца февраля @FonlineBOT. Бот отключен.
Вводные данные
Материал рассчитан на уровень Начинающий+, нужно понимать как работают классы и функции, знать основы базы данных и async/await. Если знаний мало, крайне желательно писать код в Pycharm, бесплатная версия подходит.
Используйте указанные версии библиотек, что бы проект работал без изменений. При установке иных версий вы можете получать ошибки, связанные с совместимостью.
Локальная установка библиотек для бота и Redis
Для начала нужно создать проект «fonlinebot» с виртуальным окружение. В Pycharm это делается так:
Затем установить библиотеки в виртуальном окружении. Сразу понадобятся 4: для бота, работы с redis, ускорения и emoji в сообщениях.
Установка Redis локально
Redis — это резидентная база данных (такая, которая хранит записи прямо в оперативной памяти) в виде пар ключ-значение. Чтение и запись в память происходит намного быстрее, чем в случае с дисками, поэтому такой подход отлично подходит для хранения второстепенных данных.
Как создать Telegram-бота с помощью библиотеки python-telegram-bot
Делимся инструкцией, как написать бота с помощью библиотеки python-telegram-bot за считанные минуты. На примере гайда от программиста Давида Мастроматтео.
Установка python-telegram-bot
Для создания бота понадобится пакет python-telegram-bot — оболочка для API от Telegram. Написать бота с помощью этой библиотеки очень просто, так как она полностью совместима с Python 3.6+.
$ pip install python-telegram-bot –upgrade
Создание бота
У BotFather можно запросить много других интересных вещей. Например, изменить изображение профиля бота.
Программирование бота
Приступим к программированию:
Добавьте несколько обработчиков:
Сейчас в коде прописаны функции обратного вызова, которые используют полученные данные для отправки сообщений пользователю.
Тестирование
Теперь можно протестировать бота. Запустите его.
В параметре update можно найти полезную информацию о пользователе, например, его имя.
Эти функции можно записать так:
Когда зададите последний вопрос и будете знать день рождения, создайте переменную даты и сохраните ее в context.user_data[] словаре.
Если пользователь вводит недопустимое значение, то получает ответ, что оно неверно. Значение переменной STATE не меняется, поэтому пользователь застревает на этом вопросе, пока не ответит правильно.
Создание команды
Напишите функцию расчета биоритма:
В примере представлены две разные функции: одна для обработки команды, а другая для расчета биоритма. Таким образом удается разделить ответственность этих функций.
Полный код бота
Пришло время проверить его:
Поздравляем! Telegram-бот на Python полностью готов.
Бот, созданный для примера, был сохранен. Его можно протестировать по имени пользователя @mastro35_mastrobot.
Знакомство с aiogram¶
Установка¶
Для начала давайте создадим каталог для бота, организуем там virtual environment (далее venv) и установим библиотеку aiogram.
Проверим, что установлен Python версии 3.7 (если вы знаете, что установлен 3.8 и выше, можете пропустить этот кусок):
В этой главе используется aiogram версии 2.9.2, но перед началом работы рекомендую заглянуть в канал релизов библиотеки и проверить наличие более новой версии. Подойдёт любая более новая, начинающаяся с цифры 2, поскольку в будущем ожидается релиз aiogram 3.0 с заметными изменениями и без обратной совместимости.
Чтобы избежать неприятностей, зафиксируемся на 2.9.2 и далее будем обновляться вручную.
Обратите внимание на префикс «venv» в терминале. Он указывает, что мы находимся в виртуальном окружении с именем «venv». Проверим, что внутри venv вызов команды python указывает на всё тот же Python 3.7:
Последней командой deactivate мы вышли из venv, чтобы он нам не мешал.
Первый бот¶
Давайте создадим файл bot.py с базовым шаблоном бота на aiogram:
Первое, на что нужно обратить внимание: aiogram — асинхронная библиотека, поэтому ваши функции тоже должны быть асинхронными, а перед вызовами методов API нужно ставить ключевое слово await, т.к. эти вызовы возвращают корутины.
Асинхронное программирование в Python
Не стоит пренебрегать официальной документацией!
Прекрасный туториал по asyncio доступен на сайте Python.
Если вы в прошлом работали с какой-то другой библиотекой для Telegram, например, pyTelegramBotAPI, то концепция хэндлеров (обработчиков событий) вам сразу станет понятна, разница лишь в том, что в aiogram хэндлерами управляет диспетчер.
Диспетчер регистрирует функции-обработчики, дополнительно ограничивая перечень вызывающих их событий через фильтры. После получения очередного апдейта (события от Telegram), диспетчер выберет нужную функцию обработки, подходящую по всем фильтрам, например, «обработка сообщений, являющихся изображениями, в чате с ID икс и с длиной подписи игрек». Если две функции имеют одинаковые по логике фильтры, то будет вызвана та, что зарегистрирована раньше.
Чтобы зарегистрировать функцию как обработчик сообщений, нужно сделать одно из двух действий:
1. Навесить на неё декоратор, как в примере выше. С различными типами декораторов мы познакомимся позднее. 2. Напрямую вызвать метод регистрации у диспетчера.
Рассмотрим следующий код:
Давайте запустим с ним бота:
Функция cmd_test2 не работает, т.к. диспетчер о ней не знает. Исправим эту ошибку и отдельно зарегистрируем функцию:
Снова запустим бота:
Обработка ошибок¶
Аналогично пишутся обработчики и на другие исключения. Таким образом, если одна и та же непредвиденная ситуация может возникнуть в различных хэндлерах, то можно вынести её обработку в отдельный хэндлер ошибок. Кода будет меньше, а оставшийся станет читабельнее.
Синтаксический сахар¶
Более того, для большинства типов сообщений есть вспомогательные методы вида «answer_
Всё хорошо, но если вдруг вы захотите поделиться с кем-то кодом, то придётся каждый раз помнить об удалении из исходников токена бота, иначе придётся его перевыпускать у @BotFather. Чтобы обезопасить себя, давайте перестанем указывать токен прямо в коде, а вынесем его как переменную окружения.
Замените следующие строчки из начала файла:
Запустите снова бота и убедитесь, что он работает. Получившийся код можно смело сохранять в PyCharm в File Templates.
На этом мы закончим знакомство с библиотекой, а в следующих главах рассмотрим другие «фишки» aiogram и Telegram Bot API.
Как написать telegram-бота на python с помощью библиотеки telebot
Как написать telegram-бота на python с помощью библиотеки telebot
Установка и настройка
Для начала давайте скачаем сам python. Сделать это можно на официальном сайте. Не забудьте поставить галочку add to PATH во время установки! После установки python’a нам понадобится хороший редактор кода. На помощь приходит компания JetBrains со своим бесплатным PyCharm. Мы уже близко, осталось скачать библиотеку telebot. Для этого заходим в командную строку и пишем:
Если всё прошло успешно, мы можем продолжать!
Думаю все знают о блокировки telegram в России и единственным решением как всегда остаётся vpn. Лично я рекомендую NordVPN.
Bot Father
В поиске telegram находим Bot Farher’a и создаем своего бота с помощью команды /newbot. Затем вводим имя и юзернейм. Обратите внимание, что юзернейм должен оканчиваться на bot!
Пишем telegram-бота на python с помощью библиотеки telebot часть 1
Как вы видите нам выдали специальный api токен, с помощью которого вы сможете управлять своим ботом (в моём случае это: 776550937:AAELEr0c3H6dM-9QnlDD-0Q0Fcd65pPyAiM). Свой токен Вы можете запомнить, но я рекомендую его записать.
Настал момент, которого ждали все. Открываем PyCharm и создаем новый проект.
Тут рекомендую поставить всё как у меня (название, конечно можно изменить). После создания проекта, давайте создадим файл, в котором будет наш код. Кликните правой кнопкой по папке с вашем проектом, затем New → Python File. Отлично, начнем писать код. Импортируем библиотеку telebot, с помощью:
Теперь нужно создать переменную bot. На самом деле имя переменной может быть каким угодно, но я привык писать bot.
Напишем декоратор bot.message_handler(), с помощью которого наш бот будет реагировать на команду /start. Для этого в круглых скобках пишем commands=[‘start’]. В итоге у нас должно получиться это:
Если Вы попробуете запустить своего бота (ПКМ->Run), то у вас ничего не выйдет. Во первых в конце кода мы должны прописать bot.polling(). Это нужно для того, чтобы бот не выключился сразу, а работал и проверял, нет ли на сервере нового сообщения. А во вторых наш бот если уж и будет проверять наличие сообщений, то всё равно ничего ответить не сможет. Пора это исправлять! После нашего декоратора создаем функцию start_message, которая будет принимать параметр message (название функции может быть любым). Далее давайте реализуем отправку сообщения от самого бота. В функции пропишем bot.send_message(message.chat.id, ‘Привет, ты написал мне /start’). Смотрите, что у Вас должно получиться:
Отлично, наш бот работает! Чтобы он отвечал не только на команды, но и на сообщения, создадим новый декоратор bot.message_handler(), а в круглые скобочки напишем content_types=[‘text’]. Вообще существует множество видов контента, к примеру location, photo, audio, sticker и т.д. Но нам же нужно отвечать на текст, верно? Поэтому создаём функцию send_text, принимающую параметр message. В функции пропишем условие:
Вот что у вас должно получиться:
Отлично, с текстом мы разобрались, но как же отправить к примеру стикер? Всё просто! У каждого стикера есть свой id, соответственно зная id мы сможем его отправить. Получить id стикера можно двумя способами. Первый (простой) — через специального бота «What’s the sticker id?»
Ну и второй способ, для тех, кто не ищет лёгких путей. Создаем новый декоратор bot.message_handler(), вот только в скобочки пишем content_types=[‘sticker’]. Далее всё как обычно. Создаем функцию, принимающую параметр message, а вот в ней пропишем print(message). Запускаем бота.
Смотрите, как только я отправил стикер, он сразу же вывел информацию в консоль, и в самом конце будет наш id стикера (file_id). Давайте сделаем так, чтобы когда пользователь отправил боту «я тебя люблю», то бот ему ответил стикером. Создавать новый декоратор не нужно, мы просто допишем условие, которое было до этого. Вот только вместо bot.send_message() пропишем bot.send_sticker(), а вместо текста напишем id стикера.
Поздравляю, всё получилось! Думаю как отправить аудио, фото, и геолокацию, вы разберетесь сами. Я же хочу показать вам, как сделать клавиатуру, которую бот покажет вам при старте. Это уже будет сделать сложнее. Создаем переменную keyboard1, в которую запишем telebot.types.ReplyKeyboardMarkup(). Эта функция вызывает клавиатуру. Далее создадим ряды, но помните, что рядов может быть не больше 12! Для того, чтобы их создать, пишем keyboard1.row(). В круглые скобочки запишите всё что хотите, лично я напишу «Привет» и «Пока». Теперь, чтобы вызвать клавиатуру, допишем reply_markup=keyboard1 к функции отправки сообщения при старте. Вот, что у вас должно получиться:
Вы видите, что клавиатура какая-то большая. Чтобы это исправить, нужно просто в ReplyKeyboardMarkup() прописать True. Ну а если вы хотите, чтобы клавиатура скрывалась, как только пользователь нажал на нее, то напишите еще один True. Подробнее прочитать, что означают эти True вы можете в официальной документации.
Ну а на этом всё! Конечно, это не все возможно ботов в telegram, но основные возможности я вам показал. Спасибо за внимание.
Что такое message?
Наверное многие, кто писал бота по моей предыдущей статье задались вопросом, что такое message и почему к примеру, чтобы отправить сообщение мы должны указать message.chat.id в параметрах функции send_message? Для того, чтобы узнать это давайте выведем message в консоль:
Теперь когда мы вводим команду /start, наш бот присылает огромное кол-во информации. Все, что мы сейчас получили — это ответ в формате json. Json — это простой формат для хранения структурированных данных. Все выводится в формате: ‘ключ’: значение. Давайте посмотрим на то, что получил я:
К примеру из всей этой информации мы хотим получить id чата, из которого я отправлял сообщение. Для этого обратимся к ключу chat.
Смотрите, у ключа chat есть еще несколько ключей: first_name, last_name, username… и у каждого из них есть свои значения. Теперь обратимся к ключу id:
Как вы видите для того чтобы получить нужное значение необходимо просто записать название ключей через точку. А теперь смотрим на ответ от сервера:
Все идет как надо! Мы получили id чата, собственно как и хотели! А теперь получим имя отправителя. Тут, как вы заметили нужно использовать ключ from_user.
Теперь достанем значение у ключа first_name:
Ну вот и все! За пару секунд мы смогли получить id чата и мое имя в telegram. И еще раз, для тех кто не понял:
Чтобы получить значение ключа first_name, нам нужно сначала обратиться к ключу chat, а только потом уже к first_name!
Теперь смотрите, для того, чтобы отправить сообщение в какой-либо чат нам необходимо указать несколько параметров в функцию send_message. Первый параметр — это chat_id, собственно сам id чата. Второй — text, текст сообщения. И как вы догадались, вместо того, чтобы писать message.chat.id, мы можем написать свои данные! Вот так можно прислать сообщение самому себе, если указать в параметрах свой id:
Ну а когда мы пишем message.chat.id, мы подразумеваем, что бот отправит сообщение в чат, из которого его вызвали.
Заключение
Ну а на этом всё! Надеюсь вы поняли как получать данные от сервера, обрабатывать их и использовать где нужно. Спасибо за внимание.
Как написать Telegram бота: практическое руководство
В статье я приведу пример написания онлайн бота с использованием Python и Django фреймворка. То есть мы «запилим» полноценное веб-приложение, которое будет крутиться на удалённом хосте и принимать команды от пользователей. Весь исходный текст доступен в моём github репозитории.
Как создать Telegram бота?
Для начала нам необходимо зарегистрировать в Telegram нашего будущего бота. Это делается следующим образом:
После создания бота, обратите внимание на строку с текстом:
Use this token to access the HTTP API:
За которой следует т.н. token по которому мы будем манипулировать нашим ботом. Помимо функции создания telegram бота, BotFather также имеет ряд других возможностей:
и так далее. Полное описание доступных команд можно увидеть на первом скриншоте.
Приступаем к кодированию
Как я ранее уже упоминал, мы будем писать веб-приложение на Django. Но стоит отметить, что это делать необязательно. Можно обойтись и обычным Python скриптом, правда в этом случае необходимо будет периодически опрашивать Telegram на предмет новых запросов от пользователей бота (используя метод getUpdates) и увеличивая offset для получения самых последних данных без повторений. В Telegram существует два взаимоисключающих метода получения команд/сообщений для вашего бота.
Установка Webhook заключается в передаче боту специального URL адреса на который будет поступать POST запрос каждый раз, когда кто-то начнёт посылать сообщения боту. Именно этот вариант мы и будем использовать для взаимодействия между ботом и его пользователем. Для того, чтобы задать URL, необходимо использовать API метод setWebhook. Отмечу, что URL должен начинаться с https, то есть иметь защищённое SSL соединение с валидным сертификатом. Telegram разрешает использовать самоподписанный сертификат, правда для этого необходимо в методе setWebhook передавать также публичный ключ в PEM формате (ASCII base64). Либо же можно получить валидный бесплатный SSL сертификат от Let’s Encrypt.
Подробнее о getUpdates и setWebhook можно почитать соответственно здесь и тут.
Самый простой вариант взаимодействия с Telegram ботом на Python выглядит следующим образом:
Переменной token присваиваем значение токена, полученного при создании бота через BotFather. В итоге после выполнения этих команд мы получим:
Поздравляю! Мы вызывали самый простой API запрос getMe, который возвращает информацию о боте: username, id, first_name.
Добавим нашего бота к себе в контакт-лист и пошлём ему первую стандартную команду /start
Процесс общения с telegram ботом происходит по HTTPS; для передачи данных используется JSON. Метод getUpdates возвращает список/массив из объектов типа Update. Внутри Update находится объект Message. Для стандартного взаимодействия с ботом нас фактически интересует именно объект Message, у которого мы считываем атрибут text, хранящий в себе текст, переданный боту и объект chat, в котором лежит информация о пользователе, инициировавшем общение с нашим Telegram ботом. Также имеется параметр update_id, который служит в качестве offset параметра при вызове метода getUpdates. То есть update_id+1 вернёт все сообщения, поступившие после последнего update_id, при этом все предыдущие сообщения будут удалены.
На этапе написания простейшего Telegram бота нам этих вызовов достаточно. Приступим к написанию Django приложения для обслуживания наших пользователей.
Простая функция парсинга RSS фида Planet Python выглядит вот так:
Здесь я использую python библиотеку requests для работы с HTTP в самом простейшем варианте без обработки ошибок. Django «вьюшка» выглядит следующим образом:
Я предполагаю, что вы уже клонировали мой репозиторий, настроили окружение и установили все необходимые зависимости: Django, requests, telepot. Если же вы не знаете как это сделать, то совсем скоро я напишу цикл статей о разработке веб-приложений на Python, включая разбор экосистемы: разработка, настройка, деплой. Если вам это интересно, то отпишитесь, пожалуйста, в комментариях к этой статье. Хочется получить обратную связь 🙂
После запуска runserver, URL на который необходимо посылать запрос выглядит следующим образом:
А давайте-ка отправим команду feed для получения списка новостей из Planet Python:
На скриншотах видно, что бот адекватно отреагировал на нашу команду вывести список последних 10 постов.
Следующим шагом является деплой нашего Django приложения на удалённый хост и последующий вызов метода setWebhook для передачи URL на который будет посылаться POST запрос от сервиса Telegram каждый раз при поступлении команд боту от пользователей. Об этом мы поговорим в следующей заметке.
? Присоединяйтесь к рассылке
Понравился контент? Пожалуйста, подпишись на рассылку.