Как сделать опрос в телеграм боте python
Перейти к содержимому

Как сделать опрос в телеграм боте python

  • автор:

Работа с опросами в модуле python-telegram-bot

Внимание! Пакеты python-telegram-bot версии 13.x будут придерживаться многопоточной парадигмы программирования (*на данный момент актуальна версия 13.15). Пакеты версий 20.x и новее предоставляют чистый асинхронный Python интерфейс для Telegram Bot API. Дополнительно смотрите основные изменения в пакете python-telegram-bot версии 20.x.

Базовый пример бота, который работает с опросами и построен на библиотеке python-telegram-bot . В примере задается лимит на количество участников/ответов (принимается только 3 ответа от 3-х пользователей), которые могут взаимодействовать с каждым опросом/викториной.

Команда /preview генерирует пользовательский закрытый опрос/викторину, очень похожую на ту, которую пользователь отправляет боту.

Хранение промежуточных данных опроса происходит в bot_data для последующего использования в функции ответа на опрос/викторину.

Пример бота, работающего с опросами, снабжен подробными комментариями.

import logging # импорт API Telegramm from telegram import ( Poll, ParseMode, KeyboardButton, KeyboardButtonPollType, ReplyKeyboardMarkup, ReplyKeyboardRemove, Update, ) # импорт расширений библиотеки from telegram.ext import ( Updater, CommandHandler, PollAnswerHandler, PollHandler, MessageHandler, Filters, ) # подключение логирования logging.basicConfig( format='%(asctime)s - %(name)s - %(levelname)s - %(message)s', level=logging.INFO ) logger = logging.getLogger(__name__) ### ОПРЕДЕЛЕНИЕ ФУНКЦИЙ ОБРАТНОГО ВЫЗОВА ### def start(update, _): """Информация о том, что может сделать этот бот""" update.message.reply_text( 'Введите `/poll` для участия в опросе, `/quiz` для участия в викторине или `/preview`' ' чтобы создать собственный опрос/викторину' ) def poll(update, context): """Отправка заранее подготовленного опроса""" # Вопрос опроса и его ответы. questions = "Как дела?" answer = ["Нормально", "Хорошо", "Отлично", "Супер!"] # Отправляем опрос в чат message = context.bot.send_poll( update.effective_chat.id, questions, answer, is_anonymous=False, allows_multiple_answers=True, ) # Сохраним информацию опроса в `bot_data` для последующего # использования в функции `receive_poll_answer` payload =  # ключом словаря с данными будет `id` опроса message.poll.id:  "questions": questions, "message_id": message.message_id, "chat_id": update.effective_chat.id, "answers": 0, > > # сохранение промежуточных результатов в `bot_data` context.bot_data.update(payload) def receive_poll_answer(update, context): """Итоги опроса пользователей""" answer = update.poll_answer poll_id = answer.poll_id try: questions = context.bot_data[poll_id]["questions"] except KeyError: # Это ответ на старый опрос return selected_options = answer.option_ids answer_string = "" # подсчет и оформление результатов for question_id in selected_options: if question_id != selected_options[-1]: answer_string += questions[question_id] + " и " else: answer_string += questions[question_id] context.bot.send_message( context.bot_data[poll_id]["chat_id"], f"update.effective_user.mention_html()> => answer_string>!", parse_mode=ParseMode.HTML, ) # изменение промежуточных результатов в `bot_data` context.bot_data[poll_id]["answers"] += 1 # Закрываем опрос после того, как проголосовали три участника if context.bot_data[poll_id]["answers"] == 3: context.bot.stop_poll( context.bot_data[poll_id]["chat_id"], context.bot_data[poll_id]["message_id"] ) def quiz(update, context): """Отправка заранее определенную викторину""" # Вопрос викторины и ответы questions = 'Сколько яиц нужно для торта?' answer = ['1', '2', '4', '20'] # посылаем сообщение с викториной, правильный ответ указывается # в `correct_option_id`, представляет собой индекс `answer` message = update.effective_message.reply_poll( questions, answer, type=Poll.QUIZ, correct_option_id=2 ) # Сохраним промежуточные данные викторины в `bot_data` для использования в `receive_quiz_answer` payload =  # ключом словаря с данными будет `id` викторины message.poll.id: "chat_id": update.effective_chat.id, "message_id": message.message_id> > context.bot_data.update(payload) def receive_quiz_answer(update, context): """Закрываем викторину после того, как ее прошли три участника""" # бот может получать обновления уже закрытого опроса, которые уже не волнуют if update.poll.is_closed: return if update.poll.total_voter_count == 3: try: quiz_data = context.bot_data[update.poll.id] except KeyError: # Это означает, что это ответ из старой викторины return context.bot.stop_poll(quiz_data["chat_id"], quiz_data["message_id"]) def preview(update, _): """Позволяет создать викторину или опрос пользователям чата""" # При использовании, без указания типа, позволяет пользователю # выбрать то, что он хочет создать - викторину или опрос button = [[KeyboardButton("Нажми меня!", request_poll=KeyboardButtonPollType())]] message = "Нажмите кнопку, для предварительного просмотра вашего опроса" # использование `one_time_keyboard=True` скрывает клавиатуру update.effective_message.reply_text( message, reply_markup=ReplyKeyboardMarkup(button, one_time_keyboard=True) ) def receive_poll(update, _): """ При получении ответа на пользовательский опрос/викторину, отвечаем на него закрытым опросом, копируя полученный опрос """ actual_poll = update.effective_message.poll # Нужно только `question` и `options`, все остальные # параметры не имеют значения для закрытого опроса update.effective_message.reply_poll( question=actual_poll.question, options=[o.text for o in actual_poll.options], # с `is_closed=True` опрос/викторина немедленно закрывается is_closed=True, reply_markup=ReplyKeyboardRemove(), ) def help_handler(update, _): """Отображение справочного сообщения""" update.message.reply_text("Используйте /quiz, /poll или /preview для тестирования этого бота.") if __name__ == '__main__': updater = Updater("TOKEN") dispatcher = updater.dispatcher # определяем соответствующие обработчики dispatcher.add_handler(CommandHandler('start', start)) # команда `/pool` dispatcher.add_handler(CommandHandler('poll', poll)) # обработчик ответа на опрос dispatcher.add_handler(PollAnswerHandler(receive_poll_answer)) # команда `/quiz` dispatcher.add_handler(CommandHandler('quiz', quiz)) # обработчик ответа на викторину dispatcher.add_handler(PollHandler(receive_quiz_answer)) # команда `/preview` dispatcher.add_handler(CommandHandler('preview', preview)) # обработчик создания пользовательского опроса/викторины dispatcher.add_handler(MessageHandler(Filters.poll, receive_poll)) dispatcher.add_handler(CommandHandler('help', help_handler)) # Запуск бота updater.start_polling() updater.idle() 
  • КРАТКИЙ ОБЗОР МАТЕРИАЛА.
  • Переход на асинхронный python-telegram-bot версии 20.x
  • Чистый интерфейс Python для Telegram Bot API
  • Команды и оповещения @BotFather в Telegram
  • Обработка сообщений модулем python-telegram-bot
  • Фильтры сообщений модуля python-telegram-bot
  • Хранение временных данных модулем python-telegram-bot
  • Настройки по умолчанию модуля python-telegram-bot
  • Планировщик сообщений модуля python-telegram-bot
  • Форматирование и отправка сообщений в python-telegram-bot
  • Работа с файлами/media, модуль python-telegram-bot
  • Меню из кнопок, модуль python-telegram-bot
  • Объект CallbackContext модуля python-telegram-bot
  • Подключения Telegram-бота через webhook
  • Обработка исключений модуля python-telegram-bot
  • Создание Inline-бота, модуль python-telegram-bot
  • Работа с опросами в модуле python-telegram-bot
  • Создание разговоров ConversationHandler в python-telegram-bot
  • Перезапуск телеграмм-бота в случае ошибки
  • Декоратор-обработчик сообщений в python-telegram-bot
  • Авторизация на сайте через Telegram Passport
  • Ведение публикаций в Telegram-канале с python-telegram-bot
  • UTF коды emoji/эмодзи для отправки в Telegram из Python

Опросы v2.0

Пятиминутка ненависти к telebot или Привет, aiogram!

Как вы знаете, во всех предыдущих уроках использовалась библиотека pyTelegramBotAPI, именуемая в коде telebot. В 2015-2017 годах, возможно, она ещё была актуальна, но прогресс не стоит на месте. А telebot, увы, стоит. Кривая реализация поллинга, проблемный next_step_handler, медленная поддержка новых версий Bot API и т.д.

В течение 2019 года я постепенно переносил своих ботов на другой фреймворк, который по многим пунктам превосходит pyTelegramBotAPI, и имя ему – aiogram. «Почему?», спросит меня уважаемый читатель. Что ж, приведу следующие аргументы:

  • это полноценный фреймворк, т.е. позволяет сделать больше полезных вещей;
  • асинхронный, что делает его быстрее в некоторых задачах;
  • поддерживается Python 3.7+ и выше, что сподвигнет обновить свой старенький интерпретатор и использовать новые возможности языка;
  • множество встроенных «помощников» (синтаксический «сахар»), улучшающих читабельность кода;
  • оперативные обновления (поддержка новых опросов появилась в тот же день, что и в самом Bot API);
  • русскоязычный чат поддержки и обсуждений, где сидит, в том числе, и сам разработчик фреймворка;
  • мой любимый пункт: нормально работающий поллинг.

Прокомментирую последний пункт: в настоящий момент почти все мои боты работают на aiogram-ном поллинге и не падают ежедневно, как в случае с pyTelegramBotAPI.

Введение получилось очень большим, поэтому давайте уже перейдём к делу.

Плацдарм для бота

Напишем элементарного эхо-бота на aiogram с поллингом, чтобы бегло ознакомиться с фреймворком. Прежде всего, добавим нужные импорты (предполагается, что мы используем Virtual Environment, подробнее о нём – в уроке №0):

#!venv/bin/python import logging from aiogram import Bot, Dispatcher, executor, types logging.basicConfig(level=logging.INFO) 

Теперь создадим объект бота. А за хэндлеры здесь отвечает специальный Диспетчер:

bot = Bot(token="12345678:AABcdeFGhIJkXyZ") dp = Dispatcher(bot) 

Далее напишем простейший хэндлер, повторяющий текстовые сообщения:

@dp.message_handler() async def echo(message: types.Message): await message.reply(message.text) 

Началась магия.
Во-первых, как я написал чуть выше, за хэндлеры отвечает диспетчер (dp).
Во-вторых, подхэндлерные функции в aiogram асинхронные (async def), вызовы Bot API тоже асинхронные, поэтому необходимо использовать ключевое слово await .
В-третьих, вместо bot.send_message можно для удобства использовать message.reply( ) без указания chat_id и message.id , чтобы бот сделал «ответ» (reply), либо аналог message.answer( ) , чтобы просто отправить в тот же чат, не создавая «ответ». Само выражение в хэндлере пустое, т.к. нас устроят любые текстовые сообщения.

if __name__ == "__main__": executor.start_polling(dp, skip_updates=True) 

Параметр skip_updates=True позволяет пропустить накопившиеся входящие сообщения, если они нам не важны.
Запускаем код, убеждаемся в его работоспособности, после чего удаляем хэндлер вместе с функцией echo, нам они больше не понадобятся, в отличие от остального кода.

Запрашиваем викторину у пользователя

В BotAPI 4.6 появилась новая кнопка для обычной (не инлайн) клавиатуры с типом KeyboardButtonPollType. При нажатии на неё в приложении Telegram появляется окно для создания опроса. В самой кнопке можно выставить ограничение по типу создаваемого объекта: опрос, викторина или что угодно. Опросы нас пока не интересуют, поэтому напишем обработчик команды /start , выводящий приветственное сообщение и обычную клавиатуру с двумя кнопками: “Создать викторину” и “Отмена”, причём вторая отправляет ReplyKeyboardRemove, удаляя первую клавиатуру.

# Хэндлер на команду /start @dp.message_handler(commands=["start"]) async def cmd_start(message: types.Message): poll_keyboard = types.ReplyKeyboardMarkup(resize_keyboard=True) poll_keyboard.add(types.KeyboardButton(text="Создать викторину", request_poll=types.KeyboardButtonPollType(type=types.PollType.QUIZ))) poll_keyboard.add(types.KeyboardButton(text="Отмена")) await message.answer("Нажмите на кнопку ниже и создайте викторину!", reply_markup=poll_keyboard) # Хэндлер на текстовое сообщение с текстом “Отмена” @dp.message_handler(lambda message: message.text == "Отмена") async def action_cancel(message: types.Message): remove_keyboard = types.ReplyKeyboardRemove() await message.answer("Действие отменено. Введите /start, чтобы начать заново.", reply_markup=remove_keyboard) 

Клавиатура с кнопками

Сохраняем и предлагаем

В 11-м уроке я использовал библиотеку Vedis для сохранения состояний в файле, чтобы те не сбрасывались после перезагрузки бота. В этот раз мы будем сохранять всё в памяти, а выбор постоянного хранилища останется за читателем, чтобы не навязывать то или иное решение. Разумеется, данные в памяти сотрутся при остановке бота, но для примера так даже лучше.

Наше хранилище будет основано на стандартных питоновских словарях (dict), причём их будет два: первый словарь содержит пары (“id пользователя”, “массив сохранённых викторин”), а второй — пары (“id викторины”, “id автора викторины”). Зачем два словаря? В дальнейшем нам нужно будет по идентификатору викторины получать некоторую информацию о ней. Необходимые нам сведения лежат в первом словаре, но в виде значений, а не ключей. Поэтому нам пришлось бы проходиться по всем возможным парам ключ-значение, чтобы найти нужную викторину.

Для ускорения поиска мы заведём второй словарь, чтобы по идентификатору викторины сразу же найти идентификатор её автора, который, в свою очередь, является ключом в первом словаре. А дальше проход по небольшому массиву и вуаля! Наши данные получены. На словах звучит сложно, но на практике реализуется довольно быстро и с минимальной избыточностью. Если придумаете решение лучше — пишите, буду рад исправить текст.

Помимо определения викторины, нам нужно хранить некоторую дополнительную информацию. Поэтому давайте создадим файл quizzer.py , опишем наш класс Quiz со всеми нужными полями в конструкторе класса (обратите внимание, в конструктор передаются не все поля, т.к. часть из них будет заполнена позднее):

from typing import List class Quiz: type: str = "quiz" def __init__(self, quiz_id, question, options, correct_option_id, owner_id): # Используем подсказки типов, чтобы было проще ориентироваться. self.quiz_id: str = quiz_id # ID викторины. Изменится после отправки от имени бота self.question: str = question # Текст вопроса self.options: List[str] = [*options] # "Распакованное" содержимое массива m_options в массив options self.correct_option_id: int = correct_option_id # ID правильного ответа self.owner: int = owner_id # Владелец опроса self.winners: List[int] = [] # Список победителей self.chat_id: int = 0 # Чат, в котором опубликована викторина self.message_id: int = 0 # Сообщение с викториной (для закрытия) 

Если вы раньше не сталкивались с подсказками типов (type hints), код вида “chat_id: int = 0” может ввести в замешательство. Здесь chat_id — это имя переменной, далее через двоеточие int — её тип (число), а дальше инициализация числом 0. Python по-прежнему является языком с динамической типизацией, отсюда и название “подсказка типа”. В реальности это влияет только на восприятие кода и предупреждения в полноценных IDE типа PyCharm. Никто не мешает вам написать quiz_id: int = «чемодан» , но зачем так делать? Вернёмся в наш основной файл (я его далее буду называть bot.py ) и импортируем наш класс: from quizzer import Quiz . Также добавим в начале файла под определением бота два пустых словаря:

quizzes_database = <> # здесь хранится информация о викторинах quizzes_owners = <> # здесь хранятся пары "id викторины id её создателя" 

Теперь будем отлавливать викторины, приходящие в бота. Как только прилетает что-то, похожее на неё, извлекаем информацию и создаём две записи. В первом словаре храним параметры викторины, чтобы потом её воспроизвести, а во втором просто создаём пару викторина-создатель. Идентификаторы, составляющие ключ словаря, конвертируем в строки методом str() :

Раз уж мы сохраняем викторины, давайте теперь позволим пользователям их отправлять, причём через инлайн-режим. Есть одна загвоздка: в BotAPI через инлайн-режим нельзя напрямую отправлять опросы (нет объекта InlineQueryResultPoll), поэтому придётся доставать костыли. Будем возвращать обычное сообщение с URL-кнопкой вида https://t.me/нашбот?startgroup=id_викторины. Параметры startgroup и start — это т.н. “глубокие ссылки” (Deep Linking). Когда пользователь нажмёт на кнопку, он перейдёт по указанной выше ссылке, что, в свою очередь, благодаря параметру startgroup перекинет его к выбору группы, а затем, уже после подтверждения выбора, бот будет добавлен в группу с вызовом команды /start id_викторины .

Начнём разбираться с инлайн-режимом (не забудьте включить его у @BotFather). Когда пользователь вызывает нашего бота через инлайн, показываем все созданные им викторины, плюс кнопку “Создать новую”. Если ничего нет, то только кнопку.

Очень важно выставить флаг is_personal равным True (ответ на запрос будет уникален для каждого Telegram ID) и указать небольшое значение параметра cache_time , чтобы кэш инлайн-ответов оперативно обновлялся по мере появления новых викторин.
Теперь при вызове бота через инлайн мы увидим наши сохранённые викторины, а при выборе одной из них — сообщение с кнопкой, по нажатию на которую нам предложат выбрать группу для отправки сообщения. Как только группа будет выбрана, в неё будет автоматически добавлен бот с сообщением вида /start@имя_бота . Но ничего не происходит! Сейчас разберёмся.

Отправляем викторину и получаем ответы

Помните наш простой обработчик команды /start , возвращающий сообщение с кнопкой? Настало время переписать этот хэндлер. Первым делом, будем проверять, куда отправлено сообщение – в диалог с ботом или нет. Если в диалог, то всё остаётся по-прежнему: приветствие (на этот раз укажем, что викторина принудительно будет сделана неанонимной) и кнопка для создания викторины.

А вот если сообщение отправлено в группу, то применяем следующую логику: проверяем количество “слов” в сообщении. Одно всегда есть (команда /start ), но может быть и второе, невидимое в интерфейсе приложения Telegram – параметр, переданный в качестве параметра startgroup , в нашем случае это ID викторины. Если второго слова нет (количество слов = 1), то показываем сообщение с предложением перейти в личку к боту с принудительным показом кнопки /start .

В случае, если второе слово есть, то считаем его идентификатором и пробуем отправить викторину в ту же группу. При этом мы, по сути, воспроизводим её [викторину] заново, просто от своего имени: повторяем вопрос, варианты ответов и отключаем анонимный режим, т.к. нам нужно знать, кто победитель.

Очень важный момент: при отправке викторины, в объекте Message будет записан уже новый её идентификатор, который нужно подставить в наши словари. Далее по этому новому ID мы будем смотреть и считать ответы. Побочным эффектом такого подхода будет возможность использования конкретной викторины лишь однажды и в одном чате, если отправить сообщение из инлайна в другой чат, то зашитый в ссылке инлайн-кнопки ID будет недействительным.

Далее необходимо научиться как-то обрабатывать новые ответы. В свежем обновлении API добавилось два новых типа обновлений (updates, т.е. входящие события): PollAnswer и просто Poll . Первый срабатывает при получении новых ответов в викторинах и опросах, в последнем случае ещё и при отзыве голоса (массив голосов от пользователя будет пустой). Второй срабатывает при изменении состояния опроса в целом, т.е. не только при получении новых ответов/голосов, но и при смене состояния “открыт/закрыт” и др. Опять-таки, в обучающих целях мы задействуем хэндлеры на оба типа событий.

Начнём с PollAnswer . Когда прилетает событие с новым ответом на викторину, прежде всего достаём её ID, по ней ищем автора во втором словаре. Если находим, то гуляем по всем викторинам этого пользователя и ищем совпадение по ID самой викторины, т.е. в точности обратное действие, только уже в первом словаре. Когда обнаружится нужная викторина, то проверяем, верный ответ или нет (сравниваем с correct_option_id ), и если да, то записываем ID пользователя в список победителей. Если количество победителей при этом достигает двух, то останавливаем викторину.

Остановка викторины (метод stop_poll( )) вызовет срабатывание хэндлера на тип обновлений Poll с условием is_closed is True . Снова извлекаем нужный нам экземпляр класса Quiz, вытаскиваем ID победителей и вызываем метод get_chat_member, после чего, используя aiogram-ный вспомогательный метод get_mention , формируем ссылку на каждого из победителей в HTML-разметке и создаём поздравительное сообщение. Викторины у нас одноразовые, поэтому подчищаем за собой словари, дабы не раздувать объекты в памяти.

Код готов. Закинем викторину в группу и попросим друзей правильно ответить, а сами ответим неправильно. После первого правильного ответа:

2 ответа, только один правильный

После второго правильного ответа:

3 ответа, 2 правильных, опрос закрыт

На этом всё! Если у вас возникли вопросы, не стесняйтесь задавать их в нашем чатике, а если вы нашли ошибку/опечатку, либо есть чем дополнить материал, то добро пожаловать на GitHub (ну, или всё так же в чате). Полный код урока можно найти здесь.

Как добавить опрос в телеграмм боте?

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

@bot.message_handler(commands=['poll']) def poll(message): con = sqlite3.connect('users.db') with con: cur = con.cursor() cur.execute("SELECT id FROM data_base") while True: row = cur.fetchone() if row is None: break bot.send_poll(row[0], 'Question', options=['1', '2', '3']) 

Отслеживать

Elvin Gadirov

задан 22 окт 2021 в 19:04

Elvin Gadirov Elvin Gadirov

1 2 2 бронзовых знака

приведите пример кода с которым у вас трудности

18 ноя 2021 в 13:27

добавил код и написал развернутый вопрос.

19 ноя 2021 в 17:24

0

Сортировка: Сброс на вариант по умолчанию

Знаете кого-то, кто может ответить? Поделитесь ссылкой на этот вопрос по почте, через Твиттер или Facebook.

  • python
  • python-3.x
  • telegram
  • telebot
  • python-telegram-bot

Чат-боты в Telegram на Python и Aiogram: пишем первого бота

Большой гайд по работе с Aiogram на примере эхо‑бота — чат‑бота, который повторяет за пользователем его фразы. Весь код — внутри статьи.

Иллюстрация: Polina Vari для Skillbox Media

Антон Яценко

Антон Яценко
Изучает Python, его библиотеки и занимается анализом данных. Любит путешествовать в горах.

Компании используют чат-ботов в Telegram для разных задач: рассылают новости о текущих акциях, принимают платежи или даже организуют службы технической поддержки. Обычные пользователи тоже применяют их для своих бытовых нужд — ведут учёт личных финансов или оформляют посты в социальных сетях.

Благодаря этой статье вы научитесь с нуля создавать чат-ботов с помощью Python и библиотеки Aiogram. Мы напишем эхо-бота, который отвечает на сообщения пользователя точно такими же сообщениями. Это первая часть урока по Aiogram — во второй части мы добавим боту кнопки и новые фичи.

Содержание

  • Библиотеки для создания бота
  • Краткое описание Aiogram
  • Создаём эхо-бота
  • Шаг 1. Устанавливаем Python
  • Шаг 2. Создаём виртуальное окружение
  • Шаг 3. Создаём бота
  • Шаг 4. Подключаем Aiogram
  • Шаг 5. Пишем код для эхо-бота
  • Шаг 6. Запускаем бота и проверяем работу
  • Что дальше?

Библиотеки для создания бота

Для создания телеграм-ботов на Python существует несколько десятков библиотек. Они различаются популярностью, размером комьюнити и функциональностью. Рассмотрим самые популярные.

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

Python-telegram-bot. Одна из первых библиотек для создания ботов. Отличается от Aiogram синхронным подходом к работе, то есть при ожидании ответа от пользователя выполнение кода останавливается.

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

Что нужно знать об Aiogram перед написанием кода

Перед тем как приступить к написанию нашего бота, остановимся подробнее на одной технической особенности Aiogram.

Как уже было сказано ранее, одно из главных достоинств библиотеки — полная асинхронность. Она использует синтаксис async/await, который позволяет программе выполнять несколько задач одновременно и эффективно управлять потоком выполнения.

Вот простой пример функции, использующей механизм async/await:

Другой плюс Aiogram — в большом наборе инструментов и хуков, которые можно использовать для добавления дополнительных функций и настроек бота. Библиотека обеспечивает полный доступ ко всем возможностям Telegram API, включая отправку и получение сообщений, управление клавиатурой, обработку медиафайлов (фотографий, видео, документов) и многое другое.

Вот несколько полезных источников, которые помогут разобраться в библиотеке и следить за её обновлениями:

  • официальная документация,
  • репозиторий библиотеки на GitHub,
  • русскоязычный телеграм-чат, посвящённый Aiogram,
  • англоязычный чат, посвящённый Aiogram,
  • канал с новостями библиотеки,
  • тестовый бот на основе Aiogram.

Создаём эхо-бота

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

Для этого нам необходимо:

  • установить Python и настроить виртуальное окружение;
  • зарегистрировать бота в специальном телеграм-канале @BotFather;
  • установить библиотеку Aiogram;
  • написать код эхо-бота, связав его по API с Telegram.
Шаг 1

Устанавливаем Python

На macOS или Linux. Python установлен в эти операционные системы изначально. Чтобы проверить его наличие, откройте терминал и введите команду:

На Windows требуется установка Python. Сделать это проще всего по нашей инструкции.

Шаг 2

Создаём виртуальное окружение

После установки и проверки Python требуется установить виртуальное окружение с помощью virtualenv. Это специальный инструмент, который позволяет изолировать друг от друга проекты в разработке, независимо устанавливая для них библиотеки и пакеты. Удобно, когда вы работаете над разными приложениями одновременно.

virtualenv устанавливается через терминал:

Открываем его, жмём кнопку «Запустить» и вводим команду /newbot:

Теперь напишем название и юзернейм для нашего бота. Назовём его echo_skillbox_bot (теперь это имя занято, так что вам надо будет придумать своё). В ответ придёт наш токен, который мы будем использовать для подключения к API Telegram.

Этот токен мы сохраняем — он потребуется нам в будущем.

Шаг 4

Подключаем Aiogram

Для установки Aiogram воспользуемся менеджером пакетов PIP. Вводим в терминал:

Находим нашего бота в Telegram по имени @echo_skillbox_bot и запускаем его, нажав на кнопку Начать. В ответ на это или на команду /start нам придёт приветственное сообщение:

Попробуем написать что-то:

Как мы видим — всё работает. Бот возвращает нам наши сообщения.

Что дальше?

Расширять функциональность бота, указывая для разных команд пользователя разные ответы. Например, добавить раздел помощи, который будет появляться по команде /help. Или настроить запуск кода на виртуальном сервере, чтобы бот работал независимо от вашего компьютера.

Во второй части статьи мы добавим к нашему боту кнопки и новые возможности. Так что обязательно заходите и читайте 🙂

Больше интересного про код в нашем телеграм-канале. Подписывайтесь!

Читайте также:

  • С# для новичков: развеиваем мифы и пишем простого чат-бота
  • «Я удивился, когда написал код, а он заработал»: как живёт начинающий Python-разработчик
  • Учимся верстать: что такое CSS

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

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