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

Время на прочтение
4 мин

Количество просмотров 867K

На Хабре, да и не только, про ботов рассказано уже так много, что даже слишком. Но заинтересовавшись пару недель назад данной темой, найти нормальный материал у меня так и не вышло: все статьи были либо для совсем чайников и ограничивались отправкой сообщения в ответ на сообщение пользователя, либо были неактуальны. Это и подтолкнуло меня на написание статьи, которая бы объяснила такому же новичку, как я, как написать и запустить более-менее осмысленного бота (с возможностью расширения функциональности).

Часть 1: Регистрация бота

Самая простая и описанная часть. Очень коротко: нужно найти бота @BotFather, написать ему /start, или /newbot, заполнить поля, которые он спросит (название бота и его короткое имя), и получить сообщение с токеном бота и ссылкой на документацию. Токен нужно сохранить, желательно надёжно, так как это единственный ключ для авторизации бота и взаимодействия с ним.

Часть 2: Подготовка к написанию кода

Как уже было сказано в заголовке, писать бота мы будем на Python’е. В данной статье будет описана работа с библиотекой PyTelegramBotAPI (Telebot). Если у вас не установлен Python, то сперва нужно сделать это: в терминале Linux нужно ввести

sudo apt-get install python python-pip

Если же вы пользуетесь Windows, то нужно скачать Python с официального сайта .

После, в терминале Linux, или командной строке Windows вводим

pip install pytelegrambotapi

Теперь все готово для написания кода.

Часть 3: Получаем сообщения и говорим «Привет»

Небольшое отступление. Телеграмм умеет сообщать боту о действиях пользователя двумя способами: через ответ на запрос сервера (Long Poll), и через Webhook, когда сервер Телеграмма сам присылает сообщение о том, что кто-то написал боту. Второй способ явно выглядит лучше, но требует выделенного IP-адреса, и установленного SSL на сервере. В этой статье я хочу рассказать о написании бота, а не настройке сервера, поэтому пользоваться мы будем Long Poll’ом.

Открывайте ваш любимый текстовый редактор, и давайте писать код бота!

Первое, что нужно сделать это импортировать нашу библиотеку и подключить токен бота:

import telebot;
bot = telebot.TeleBot('%ваш токен%');

Теперь объявим метод для получения текстовых сообщений:

@bot.message_handler(content_types=['text'])
def get_text_messages(message):

В этом участке кода мы объявили слушателя для текстовых сообщений и метод их обработки. Поле content_types может принимать разные значения, и не только одно, например

@bot.message_handler(content_types=['text', 'document', 'audio'])

Будет реагировать на текстовые сообщения, документы и аудио. Более подробно можно почитать в официальной документации

Теперь добавим в наш метод немного функционала: если пользователь напишет нам «Привет», то скажем ему «Привет, чем я могу помочь?», а если нам напишут команду «/help», то скажем пользователю написать «Привет»:

if message.text == "Привет":
    bot.send_message(message.from_user.id, "Привет, чем я могу тебе помочь?")
elif message.text == "/help":
    bot.send_message(message.from_user.id, "Напиши привет")
else:
    bot.send_message(message.from_user.id, "Я тебя не понимаю. Напиши /help.")

Данный участок кода не требует комментариев, как мне кажется. Теперь нужно добавить в наш код только одну строчку (вне всех методов).

bot.polling(none_stop=True, interval=0)

Теперь наш бот будет постоянно спрашивать у сервера Телеграмма «Мне кто-нибудь написал?», и если мы напишем нашему боту, то Телеграмм передаст ему наше сообщение. Сохраняем весь файл, и пишем в консоли

python bot.py

Где bot.py – имя нашего файла.

Теперь можно написать боту и посмотреть на результат:

image

Часть 4: Кнопки и ветки сообщений

Отправлять сообщения это несомненно весело, но ещё веселее вести с пользователем диалог: задавать ему вопросы и получать на них ответы. Допустим, теперь наш бот будет спрашивать у пользователя по очереди его имя, фамилию и возраст. Для этого мы будем использовать метод register_next_step_handler бота:

name = '';
surname = '';
age = 0;
@bot.message_handler(content_types=['text'])
def start(message):
    if message.text == '/reg':
        bot.send_message(message.from_user.id, "Как тебя зовут?");
        bot.register_next_step_handler(message, get_name); #следующий шаг – функция get_name
    else:
        bot.send_message(message.from_user.id, 'Напиши /reg');

def get_name(message): #получаем фамилию
    global name;
    name = message.text;
    bot.send_message(message.from_user.id, 'Какая у тебя фамилия?');
    bot.register_next_step_handler(message, get_surnme);

def get_surname(message):
    global surname;
    surname = message.text;
    bot.send_message('Сколько тебе лет?');
    bot.register_next_step_handler(message, get_age);

def get_age(message):
    global age;
    while age == 0: #проверяем что возраст изменился
        try:
             age = int(message.text) #проверяем, что возраст введен корректно
        except Exception:
             bot.send_message(message.from_user.id, 'Цифрами, пожалуйста');
      bot.send_message(message.from_user.id, 'Тебе '+str(age)+' лет, тебя зовут '+name+' '+surname+'?')

И так, данные пользователя мы записали. В этом примере показан очень упрощённый пример, по хорошему, хранить промежуточные данные и состояния пользователя нужно в БД, но мы сегодня работаем с ботом, а не с базами данных. Последний штрих – запросим у пользователей подтверждение того, что все введено верно, да не просто так, а с кнопками! Для этого немного отредактируем код метода get_age

def get_age(message):
    global age;
    while age == 0: #проверяем что возраст изменился
        try:
             age = int(message.text) #проверяем, что возраст введен корректно
        except Exception:
             bot.send_message(message.from_user.id, 'Цифрами, пожалуйста');
      keyboard = types.InlineKeyboardMarkup(); #наша клавиатура
      key_yes = types.InlineKeyboardButton(text='Да', callback_data='yes'); #кнопка «Да»
      keyboard.add(key_yes); #добавляем кнопку в клавиатуру
      key_no= types.InlineKeyboardButton(text='Нет', callback_data='no');
      keyboard.add(key_no);
      question = 'Тебе '+str(age)+' лет, тебя зовут '+name+' '+surname+'?';
      bot.send_message(message.from_user.id, text=question, reply_markup=keyboard)

И теперь наш бот отправляет клавиатуру, но если на нее нажать, то ничего не произойдёт. Потому что мы не написали метод-обработчик. Давайте напишем:

@bot.callback_query_handler(func=lambda call: True)
def callback_worker(call):
    if call.data == "yes": #call.data это callback_data, которую мы указали при объявлении кнопки
        .... #код сохранения данных, или их обработки
        bot.send_message(call.message.chat.id, 'Запомню : )');
    elif call.data == "no":
         ... #переспрашиваем

Остаётся только дописать в начало файла одну строку:

from telebot import types

Вот и всё, сохраняем и запускаем нашего бота:

image

#Руководства

  • 14 сен 2022

  • 0

Разбираемся, как написать чат-бота с помощью библиотеки aiogram. Весь код — внутри статьи.

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

Антон Яценко

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

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

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

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

aiogram

Современная библиотека, набирающая популярность. Работает с асинхронным подходом к выполнению кода. Это позволяет не останавливать работу бота в ожидании ответа пользователя. У aiogram подробная документация и большое русскоязычное комьюнити. В этой и последующих статьях цикла мы будем работать как раз с этой библиотекой.

python-telegram-bot

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

TeleBot

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

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

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

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

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

python --version

Если Python установлен, то терминал покажет его версию:

Скриншот: aiogram / Skillbox Media

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

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

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

sudo pip3 install virtualenv

После этого необходимо создать директорию для проекта, внутри которой будет работать виртуальное окружение:

mkdir telegram_bot
cd telegram_bot

Команда mkdir создаст папку telegram_bot, а команда cd переведёт нас в неё. Теперь в этой директории будут храниться файлы проекта, связанные с нашим ботом.

Развернём виртуальное окружение внутри папки telegram_bot:

virtualenv venv -p python3

Теперь его активируем. Если этого не сделать, то оно не будет работать.

source venv/bin/activate

Виртуальное окружение запущено, и мы готовы перейти к следующему шагу.


Для создания бота необходимо воспользоваться Telegram и ботом @BotFather. Откройте мессенджер и введите название бота в поисковой строке:

Скриншот: aiogram / Skillbox Media

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

Скриншот: aiogram / Skillbox Media

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

Скриншот: aiogram / Skillbox Media

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


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

pip install aiogram

Важно! Библиотека устанавливается в созданное ранее виртуальное окружение, связанное с папкой telegram_bot. Если вы решите создать нового бота в другой директории на компьютере, то установку будет необходимо провести заново, иначе aiogram не будет работать.


Писать код на Python лучше всего в IDE, а не в окне терминала. В проекте ниже мы будем использовать бесплатный редактор Visual Studio Code, но вы можете воспользоваться любым удобным для вас инструментом.

Откроем IDE и создадим файл main.py. Для этого проекта нам потребуется только он. Импортируем из aiogram нужные классы и модуль:

from aiogram import Bot, Dispatcher, executor, types

Разберёмся, что каждый из них делает. Начнём с классов:

  • Bot определяет, на какие команды от пользователя и каким способом отвечать;
  • Dispatcher позволяет отслеживать обновления;
  • Executor запускает бота и выполняет функции, которые следует выполнить.

Модуль types позволит нам использовать базовые классы для аннотирования, то есть восприятия сообщений. Например, мы будем использовать types.Message, позволяющий работать с приёмом текстовых сообщений пользователя. Подробно об этом можно прочесть в документации.

Импортируем наш токен, который поможет коммуницировать с API Telegram:

API_TOKEN = '5602787567:AAGYv7NrSjwyW7qPs_yvu70C060zrcfZDbQ' #В одинарных кавычках размещаем токен, полученный от @BotFather.

Теперь необходимо инициализировать объекты bot и Dispatcher, передав первому наш токен. Если их не инициализировать, то код не будет работать.

bot = Bot(token=API_TOKEN)
dp = Dispatcher(bot)

Настроим приветственное окно для нового пользователя, которое будет появляться при нажатии команды /start. Для этого создаём message_handler и прописываем функцию ответа:

@dp.message_handler(commands=['start']) #Явно указываем в декораторе, на какую команду реагируем. 
async def send_welcome(message: types.Message):
   await message.reply("Привет!nЯ Эхо-бот от Skillbox!nОтправь мне любое сообщение, а я тебе обязательно отвечу.") #Так как код работает асинхронно, то обязательно пишем await.

Теперь при нажатии на кнопку Начать или при вводе команды /start пользователь будет получать от бота приветственное сообщение.

Разберёмся в коде:

  • message_handler — это декоратор, который реагирует на входящие сообщения и содержит в себе функцию ответа. Декоратор — это «обёртка» вокруг функций, позволяющая влиять на их работу без изменения кода самих функций. В нашем случае мы управляем функцией, считая команды пользователя;
  • commands=[‘start’] — это команда, которая связана с декоратором и запускает вложенную в него функцию;
  • async def send_welcome — создаёт асинхронную функцию, которая принимает в себя сообщение пользователя message, определяемое через тип Message. Саму функцию можно назвать любым образом. Мы выбрали send_welcome, чтобы название было понятным и осмысленным;
  • await message.reply — определяет ответ пользователя, используя await из-за асинхронности работы библиотеки.

Теперь создадим событие, которое будет обрабатывать введённое пользователем сообщение:

@dp.message_handler() #Создаём новое событие, которое запускается в ответ на любой текст, введённый пользователем.
async def echo(message: types.Message): #Создаём функцию с простой задачей — отправить обратно тот же текст, что ввёл пользователь.
   await message.answer(message.text)

Так как бот должен реагировать на любое текстовое сообщение от пользователя, то скобки в @dp.message_handler мы оставляем пустыми. Параметр message не отличается от использованного в предыдущих шагах.

Для ответа мы также используем метод message, указывая, что возвращаем исходный текст, принятый в message.

Остаётся последний этап — настроить получение сообщений от сервера в Telegram. Если этого не сделать, то мы не получим ответы бота. Реализовать получение новых сообщений можно с помощью поллинга. Он работает очень просто — метод start_polling опрашивает сервер, проверяя на нём обновления. Если они есть, то они приходят в Telegram. Для включения поллинга необходимо добавить две строчки:

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

Всё, теперь код нашего бота полностью готов:

from aiogram import Bot, Dispatcher, executor, types
 
API_TOKEN = '5602787567:AAGYv7NrSjwyW7qPs_yvu70C060zrcfZDbQ'
 
bot = Bot(token=API_TOKEN)
dp = Dispatcher(bot)
 
@dp.message_handler(commands=['start'])
async def send_welcome(message: types.Message):
   await message.reply("Привет!nЯ Эхо-бот от Skillbox!nОтправь мне любое сообщение, а я тебе обязательно отвечу.")
 
@dp.message_handler()
async def echo(message: types.Message):
   await message.answer(message.text)
 
if __name__ == '__main__':
   executor.start_polling(dp, skip_updates=True)

Сохраняем его в нашей папке telegram_bot под именем main.py.


Для запуска бота нам необходим терминал. Открываем его и переходим в нашу папку telegram_bot. После этого вводим команду:

python3 main.py

В ответ терминал пришлёт сообщение, что обновления успешно пропущены:

Скриншот: aiogram / Skillbox Media

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

Скриншот: aiogram / Skillbox Media

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

Скриншот: aiogram / Skillbox Media

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

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

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

Учись бесплатно:
вебинары по программированию, маркетингу и дизайну.

Участвовать

Научитесь: Профессия Python-разработчик
Узнать больше

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

В данной статье будет рассказано о том, как написать простой бот на Python. А еще – рассмотрены особенности соответствующего ЯП, преимущества и недостатки упомянутого «виджета». Примеры будут приведены на основе Telegram. Здесь bot – это весьма распространенное явление.

Бот – это…

Это специализированный робот-помощник. Он помогает выполнять любые рутинные занятия. Боты способны реализовывать программные коды, которые будут отвечать за активацию разных команд со стороны пользователей.

Переписка с таким ПО осуществляется непосредственно через чат. Клиент дает боту команды, которые он обрабатывает и выполняет в режиме 24/7. Ключевая задача “робота» – дать ответ на вопрос клиента, опираясь на заданную программу. С помощью оных удается экономить не только время, но и остальные ресурсы.

Умения

Бот Телеграмм умеет многое. Сегодня к спектру его навыков относят следующие моменты:

  • проведение обучения;
  • развлечение публики;
  • предложение и запуск «мини-игр»;
  • работа с поисковыми системами в пределах Сети;
  • скачивание данных – фото, видео, аудио, документов;
  • выступать в качестве напоминалки;
  • участие в групповых чатах для решения заранее определенного спектра задач (пример – согласование оптимального времени встречи);
  • комментирование постов и статей;
  • использование функций управления умным домом и другими подобными устройствами.

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

Преимущества и недостатки

Как и любое другое ПО, bot – это «виджет», который имеет ряд сильный и слабых сторон. Их предстоит учитывать каждому, кто хочет подключить соответствующего «помощника» в своем чате/диалоге.

Сильные стороны

К преимуществам ботов Телеграм относят:

  • круглосуточную помощь – функционирование bots прекратят только в случае аварий на серверах, которые случаются крайне редко;
  • удобство и простоту использования – для большинства команд достаточно выбрать из предложенного списка подходящую операцию;
  • мгновенное получение ответа;
  • отсутствие требований к мощности задействованного устройства – это связано с тем, что для работы ботов используются возможности сторонних серверов;
  • высокий уровень безопасности;
  • отсутствие необходимости инициализации дополнительного ПО для запуска рассматриваемого вида «помощника».

Ботов применять удобно и интересно. Они упрощают жизнь и владельцу чата/компании, и непосредственным клиентам/участникам диалога.

Слабые стороны

Минусы у такого ПО тоже есть, но они не слишком весомые:

  • составлять bot должен программист – тот, кто далек от данной сферы деятельности, будет долго разбираться в принципах коддинга;
  • писать бота лучше на одном языке – через Питон;
  • нужно заранее хорошо продумать навигационное меню – тем, кто раньше не имел дела с подобным контентом, может потребоваться немало времени для этого.

Бот должен быть полезным, отвечать потребностям ЦА, а также целям владельца чата. Составить его удастся «с нуля» за 15-30 минут. Особенно если придерживаться определенного алгоритма действий.

Почему Питон

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

Бот, написанный на Python, будет отличаться скоростью, безопасностью и стабильностью. Сам ЯП предусматривает следующие преимущества:

  • функциональность;
  • разделение итоговой кодификации на блоки, что позволяет значительно повысить ее читаемость;
  • поддержка длинной арифметики;
  • кроссплатформенность;
  • огромное количество библиотек, которые смогут выручить в любое время;
  • понятный синтаксис.

Это – идеальный вариант для веб-разработки, приложений для мессенджеров и мелких проектов. Крупные и масштабные игры на чистом Python составить не получится. Для этого предстоит подучить Java или C++.

Составление софта

Bot – это просто и удобно. Телеграм позволяет внедрять и искать такие «виджеты» без особого труда. Хорошего бота удастся составить менее чем за час. Главное – придерживаться определенного алгоритма действий.

Принцип

Перед непосредственной разработкой необходимо разобраться в том, как все будет работать. Bot для «Телеги» функционирует по определенным принципам. Пример будет рассмотрен на компьютере и Telegram-клиенте.

Стоит обратить внимание на следующее:

  1. На компьютере есть интерпретатор Python. Также на устройство необходимо поставить сервер Телеграмма и клиент.
  2. Внутри интерпретатора будет функционировать программа-бот. Она будет отвечать за весь софт: в оной прописана логика и шаблоны, а также возможные операции.
  3. Внутри приложения, написанного через Питон, имеется библиотека, отвечающая за связь с сервером Telegram. В нее нужно вшить секретный ключ. Это поможет указать серверу клиента, что программа связана с конкретным ботом.
  4. Когда клиент с «Телегой» осуществляет запрос гороскопа, bot осуществляет выгрузку на сервер, а сервер – выводит результат на компьютер.
  5. Запрос будет проходить обработку через утилиту на Python, дает ответ на сервер Телеграмма.
  6. Сервер передает необходимый результат непосредственному пользователю.

Bot внедряется без особого труда. Описанный принцип действий актуален не только для гороскопов. Он подойдет для bot любого вида в мессенджере.

Краткий план – пошагово

Чтобы bot Телеграм работал, можно представить процедуру его подключения так:

  1. Провести регистрацию нового бота в мессенджере.
  2. Установить Питон-библиотеку для работы с Telegram.
  3. Добавить библиотеку в программу с гороскопом.
  4. Научить bot реагировать на сообщения в пределах чата.
  5. Прописать там же кодификацию, которая отвечает за кнопки выбора знака зодиака.
  6. Сделать так, чтобы при клике по кнопке отображался гороскоп выбранного варианта.

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

Регистрация

Для того, чтобы зарегистрировать нового бота в Телеграмме, нужно:

  1. Открыть соответствующий мессенджер.
  2. При помощи командной строки найти @BotFather. Он несет ответ за регистрацию нового bot.
  3. Кликнуть по надписи Start, а также указать команду / newbot.
  4. Система задаст поочередно вопросы о названии бота и его ника. Имя должно быть уникальным. С первого раза установить его не всегда получается.

На этом первый этап подготовки завершен. Можно двигаться дальше.

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

Следующий этап – это установка подходящей библиотеки Python. Работать с «Телегой» можно через telebot. Второй вариант – это инициализация Webhook. Первый вариант проще, поэтому заострим внимание на нем:

  1. Запустить командную строку от имени администратора на устройстве.
  2. Набрать команду pip install pytelegrambotapi.
  3. Подтвердить обработку операции.
  4. Чтобы приложение понимало бота, в самое начало кода требуется добавить: import telebot;
  5. Bot = telebot.TeleBot(«токен»);.
  6. Вместо слова «токен» вставить настоящий токен, выданный @BotFather.
  7. Открыть программу гороскопа и добавить ее.

Перед тем, как импортировать приложение гороскопа, необходимо его написать. Сделать его требуется на Питоне.

Гороскоп программа

Вот так будет выглядеть код приложения, который отвечает за отображение информации о гороскопах. Создается контент в программной среде Питона:

Сразу после формирования ПО можно приступить к следующему этапу настройки.

Реакции

Bot должен реагировать на слово «Привет». После него будет выдана реакция на соответствующую фразу. Чтобы все работало нормально, необходимо добавить после строчек импорта новый метод. Он отвечает за соответствующую операцию:

@bot.message_handler(content_types=['text'])
def get_text_messages(message):
  if message.text == "Привет":
      bot.send_message(message.from_user.id, "Привет, сейчас я расскажу тебе гороскоп на сегодня.")
  elif message.text == "/help":
      bot.send_message(message.from_user.id, "Напиши Привет")
  else:
      bot.send_message(message.from_user.id, "Я тебя не понимаю. Напиши /help.")

Теперь нужно:

  • Добавить после метода строку типа: bot.polling(none_stop=True, interval=0).
  • После ее добавления у бота будет постоянно проверяться наличие новых сообщений.
  • Прописать код, который предполагает работу с кнопками. Сначала осуществляется вывод всех знаков зодиака. При клике по конкретной – отображается гороскоп оного.

  • Добавить обработчик кнопок. Он будет реагировать на слово zodiac. При написании оного в программе отобразится случайный текст:
# Обработчик нажатий на кнопки
@bot.callback_query_handler(func=lambda call: True)
def callback_worker(call):
# Если нажали на одну из 12 кнопок — выводим гороскоп
if call.data == "zodiac": 
# Формируем гороскоп
msg = random.choice(first) + ' ' + random.choice(second) + ' ' + random.choice(second_add) + ' ' + random.choice(third)
# Отправляем текст в Телеграм
bot.send_message(call.message.chat.id, msg)
  • Можно убрать кодификацию, которая ранее отвечала за вывод знаков зодиака в консоли. После очистки получится приложение:


На этом рассматриваемый «помощник» окончен. Теперь все должно нормально работать. Остается запустить его в Телеграме и получить тот или иной результат.

Команды управления

«Помощник» имеет разные функции и команды. Они пишутся через знак «слеш» («/») прямо в сообщении чата. Вот основные операции:

  • /start – начать работу помощника;
  • /help – вывод помощи на экран;
  • /settings – открыть настройки.

Некоторые подобные «дополнения» способны понимать команды на русском языке. Пример – запрос у робота Антона, который «подрабатывает» в Гидрометцентре. Если при общении с ним прописать «Погода Калининград», будет выведен соответствующий результат.

Почему «молчит»

Иногда бывает так, что «помощник» не отвечает. Такое наблюдается при вводе любой команды/выбора подходящего варианта из меню. Данное явление может происходить по нескольким причинам:

  1. Проблемы и неполадки на сервере. Пример – сбой или полный отказ оного от функционирования.
  2. Ошибки при написании кодификации. Распространенное явление среди новичков.
  3. Ввод команды, которую Телеграм бот на Python не понимает. В этом случае можно воспользоваться Google для поиска подходящих операций и их форматов.

Иногда помогает полное отключение и перезапуск «помощника».

Как быстро освоить Python

Питон и его возможности можно выучить в ВУЗе, техникуме или самостоятельно поисках материалы в Сети. Вот видео по боту в «Телеге». Самообразование – один из лучших, но долгих методов обучения.

А чтобы надписи типа examples, def get, main() и другие не доставляли хлопот, стоит пройти дистанционные курсы. Их преимущества:

  1. Доступность. Обучение можно проводить в любом месте и в любое время, имя под рукой интернет.
  2. Разнообразие направлений. Есть предложения для новичков и опытных программеров.
  3. Срок обучения – до 12 месяцев. За это время пользователь сможет освоить даже несколько направлений.
  4. Хорошо продуманная программа, подпитанная практикой и кураторством опытных разработчиков.

По завершении процесса пользователь получит сертификат, подтверждающий навыки и познания в выбранной области.

Напишем простой диалоговый Telegram-бот на Python, который в дальнейшем можно дополнить различными функциями, и задеплоим его.

Примечание Вы читаете улучшенную версию некогда выпущенной нами статьи.

  1. Настройка
  2. Hello, bot!
  3. Docker
  4. Деплой на AWS
  5. Заключение

Настройка

Откройте Telegram, найдите @BotFather и начните беседу. Отправьте команду /newbot и следуйте инструкциям. Вы получите:

  • свой токен;
  • адрес Telegram API (https://api.telegram.org/bot);
  • ссылку на документацию.

Обязательно сохраните токен, так как это ключ для взаимодействия с ботом.

Примечание Хранение токена должно быть локальным: ни в коем случае не выгружайте его в общий доступ, например в GitHub-репозиторий .

Далее начните беседу. Введите в поисковой строке имя бота и нажмите /start. Отправьте любое сообщение: оно станет первым обновлением, которое получит Телеграм бот.

Установка Python

Для написания Telegram-бота на Python, нужно установить сам язык. Если вы пользуетесь Windows, скачать Python можно с официального сайта. Версия важна. Нам подойдет Python не ниже версии 3.7. Если же у вас Linux или macOS, то, скорее всего, у вас стоит Python 3.6. Как обновиться, можете почитать здесь.

Тем, кто только начал изучение этого языка, будет также полезна дорожная карта Python-разработчика.

Установка pip

Это менеджер пакетов. В версиях выше Python 2.7.9 и Python 3.4, а также на macOS/Linux он уже есть. Проверить это можно командой pip --version в терминале. Если же по каким-то причинам он отсутствует, установить его можно при помощи команды:

$ sudo apt-get install python-pip

Установка aiogram

Установить данный фреймворк для Telegram Bot API с помощью pip:

pip install aiogram

Hello, bot!

Давайте напишем простенькую программу приветствия. Для начала следует импортировать библиотеки и создать экземпляры Телеграм бота и диспетчера:

from aiogram import Bot, types
from aiogram.dispatcher import Dispatcher
from aiogram.utils import executor
TOKEN = "ваш токен от бота здесь"
bot = Bot(token=TOKEN)
dp = Dispatcher(bot)

Теперь напишем обработчик текстовых сообщений, который будет обрабатывать входящие команды /start и /help:

@dp.message_handler(commands=['start', 'help'])
async def send_welcome(msg: types.Message):
    await msg.reply_to_message(f‘Я бот. Приятно познакомиться,
                               {msg.from_user.first_name}’)

Добавим ещё один обработчик для получения текстовых сообщений. Если бот получит «Привет», он также поздоровается. Все остальные сообщения будут определены, как нераспознанные:

@dp.message_handler(content_types=['text'])
async def get_text_messages(msg: types.Message):
   if msg.text.lower() == 'привет':
       await msg.answer('Привет!')
   else:
       await msg.answer('Не понимаю, что это значит.')

Запускаем Telegram бота, написанного на Python, следующим образом:

if __name__ == '__main__':
   executor.start_polling(dp)

Примечание Так мы задаём боту непрерывное отслеживание новых сообщений. Если бот упадёт, а сообщения продолжат поступать, они будут накапливаться в течение 24 часов на серверах Telegram, и в случае восстановления бота прилетят ему все сразу.

Ну вот и всё, простенький бот в Телеграмме на языке Python готов.

Docker

Сейчас мало кто не слышал про Docker, но если вдруг не слышали — вот хорошая статья. Для нашего проекта потребуется самый простой Dockerfile:

FROM python:3.8
# set work directory
WORKDIR /usr/src/app/
# copy project
COPY . /usr/src/app/
# install dependencies
RUN pip install --user aiogram
# run app
CMD ["python", "bot.py"]

Каталог проекта должны при этом содержать следующие файлы:

  • bot.py;
  • Dockerfile.

Для локальных тестов достаточно установить Docker (linux, mac, windows), после чего в папке проекта собрать и запустить контейнер с помощью команд:

docker build -t my_app
docker run -d my_app

my_app — это просто название нашего контейнера, вместо которого можно использовать другое имя.

-d — специальный флаг, который запускает контейнер в фоне и позволяет дальше работать в терминале. Это называется detached mode.

Деплой на AWS

Прежде всего нам понадобится аккаунт на Docker Hub. Это аналог GitHub, только не с исходниками кода, а с уже созданными контейнерами. Работа с Docker Hub выглядит достаточно просто:

  1. Локально или с помощью пайплайнов собрали контейнер.
  2. Загрузили его на докер хаб.
  3. В любом удобном месте скачали его. Это может быть локальная машина, VPS сервер или облачный провайдер по типу AWS.
  4. Запустили.

Пройдёмся по этим шагам. Везде, где указано <docker_hub_username>, надо вставлять свой юзернейм, использованный при регистрации на докерхабе. Если это ваша первая публикация на докерхаб, для начала потребуется залогиниться с помощью docker login.

Билдим контейнер:

docker build -t <docker_hub_username>/my_app

Загружаем его на докерхаб:

docker push <docker_hub_username>/my_app

Для проверки успешности загрузки можете запустить контейнер из Docker Hub с помощью команды:

docker run -d <docker_hub_username>/my_app

Далее загрузим наш контейнер в AWS Elastic Beanstalk. Для этого потребуется аккаунт на AWS. Если его нет, необходимо зарегистрироваться. Вас попросят ввести данные карты для верификации, но переживать не стоит, ведь мы воспользуемся бесплатным годовым триалом. Чтобы поиграться, этого более чем достаточно, а вот если вы захотите вывести проект в продакшен, следует перейти на VPS — это даст больше контроля и гибкости.

  • Переходим в Elastic Beanstalk, на вкладку Applications, и создаём новое приложение:

Elastic Beanstalk вкладка Applications

  • Называем приложение, теги оставляем пустыми:

Называем приложение в Elastic Beanstalk

  • Создаём для приложения environment:

environment для будущего Telegram-бота

  • Выбираем Worker environment:

Worker environment для будущего Telegram-бота

  • В качестве платформы выбираем Docker:

Docker для Telegram-бота на Python

  • В пункте Application code нужно загрузить JSON-файл с конфигурацией Docker-образа. Сам файл:
Dockerrun.aws.json
{
 "AWSEBDockerrunVersion": "1",
 "Image": {
   "Name": "<docker_hub_username>/my_app",
   "Update": "true"
 },
"Ports": [
 {
   "ContainerPort": 5000,
   "HostPort": 8000
 }
]
}

Application code

  • Создаём окружение:

Создаём окружение

  • AWS начинает создавать окружение, просто ждём завершения процесса:

AWS начинает создавать окружение

  • Если всё прошло успешно, вы увидите индикатор успешного запуска приложения:

Docker для Телеграм бота

Проверяем работу нашего Telegram bot:

Проверка Телеграм бота

Успех!

Заключение

Поздравляем! Теперь вы знаете, как писать роботов для Telegram на Python.

Бота можно дополнять другими функциями, например, добавить отправку файлов, опрос или клавиатуру.

Кстати, в телеграмме есть аж целых два типа клавиатур:

  1. Классическая RelpyKeyboardMarkup, у которой кнопки располагаются под полем ввода сообщения:
    RelpyKeyboardMarkup
  2. Более современная InlineKeyboardMarkup, которая привязывается к конкретному сообщению:
    InlineKeyboardMarkup

Но и это полностью рабочий Телеграм-бот на Python: дополните словарём, и получите полноценную беседу. Также можете опробовать функциональность нашего Telegram-бота.

В «настоящих проектах» не обойтись без базы данных. Тут на помощь приходит docker-compose, который позволяет объединить несколько контейнеров в один сервис. Таким образом, например, можно создать приложение и положить его в контейнер, а базу данных, как отдельный сервис, поместить в другой контейнер, и с помощью docker-compose наладить между ними связь.

Также для более серьёзной разработки лучше использовать выделенный виртуальный сервер (VPS): он даёт гораздо больше гибкости и свободы, чем тот же AWS. А самое главное, он более приближён к «боевой» разработке. Схема работы тут будет даже проще, чем с AWS: вам просто нужно установить Docker, спуллить образ с Docker Hub и запустить его.

Telegram-боты от А до Я

Реализация телеграм-ботов различными методами, начиная от написания бота на чистом Python без внешних фреймворков и заканчивая реализацией бота внутри фреймворка Django

Проект находится в стадии разработки и будет регулярно дополняться

Оглавление

  1. Настройка рабочей среды
  2. Хардкор-бот без фреймворков
  3. Бот с webhook на Flask
    1. Запуск бота на сервере
      1. С SSL
      2. Без SSL
    2. Установка вебхука
  4. Бот на Django
    1. Настройка рабочей среды Django
    2. Запуск бота Django
  5. Полезные ресурсы

Настройка рабочей среды

Для начала необходимо установить и активировать виртуальную среду, обновить pip и установить все зависимости:

python3 -m venv venv
source ./venv/bin/activate
pip install pip --upgrade
pip install -r requirements.txt

Хардкор-бот без фреймворков

Простой эхо-бот. Умеет работать только с GET-запросами.
Для этого он использует библиотеку requests.
Для получения обновлений от Telegram используется метод getUpdates.
Исходники лежат здесь.

Предполагается, что токен лежит в файле config.py в папке bot-hardcore

Бот с webhook на Flask

Разница между предыдущим ботом и этим в методе получения обновлений от Telegram.
Здесь бот вместо того, чтобы периодически спамить сервера Telegram методом getUpdates для получения обновлений,
работает по принципу Webhook.
Исходники лежат здесь.

Предполагается, что токен лежит в файле config.py в папке bot-flask

  1. Запуск бота на сервере

    1. Запуск на сервере с установленным сертификатом SSL

    Для этого на сервере необходимо настроить связку Flask + UWSGI + Nginx
    В этом вам поможет статья на DigitalOcean

    1. Запуск на localhost или на сервере без SSL

    Telegram требует, чтобы url-адрес для вебхука начинался с https://.
    Поэтому для установки бота на локальный сервер или на сервер без SSL-сертификата
    вам понадобится установить «туннель» через сторонние сервисы типа localhost.run или ngrok.
    Рассмотрим пример установки с localhost.run.

    Например, если в ваш web-сервер на Flask с телеграм-ботом внутри запущен по адресу 127.0.0.1:5000 (по умолчанию),
    вам достаточно ввести в терминале эту команду:

    ssh -R 80:localhost:5000 localhost.run

    В ответ вы получите url-адреса вида https://f6773f9edca4d5.localhost.run,
    по которому извне можно будет получить доступ к локальным файлам вашего компьютера

  2. Установка вебхука

Для установки вебхука необходимо послать get-запрос такого формата:

https://api.telegram.org/{token}/setWebhook?url={url}

Где:

  • token — это токен, который вы получили от BotFather
  • url — это url-адрес, на который будут приходить обновления в виде POST-запроса

Например:

https://api.telegram.org/bot123445:FJFIOEJFIOER/setWebhook?url=https://bot.mysite.com

Чтобы послать get-запрос скопируйте url выше (изменив данные на свои) и:

  • либо вставьте url в поле ввода адреса вашего браузера и нажмите Enter
  • либо в терминале пошлите запрос через curl:
     curl -X GET https://api.telegram.org/bot123445:FJFIOEJFIOER/setWebhook?url=https://f6773f9edca4d5.localhost.run

В ответ вы должны получить:

{
  "ok":true,
  "result":true,
  "description":"Webhook was set"
}

Бот на Django

Бот, который реализован внутри приложения Django и запускаетя по команде python manage.py bot.
Используется фреймворк python-telegram-bot
Исходники лежат здесь.

Предполагается, что токен лежит в файле config.py в папке bot-django

  1. Настройка рабочей среды Django

Для того, чтобы бот работал, он должен находиться внутри зарегистрированного приложения Django. Если у вас уже есть готовый проект на Django, переходите сразу на шаг №2. В ином случае:

  1. Создайте проект Django в терминале:
django-admin startproject myproject
cd ./myproject
  1. Скопируйте bot-django в родительскую папку проекта Django (в моем случае это папка myproject) и зарегистрируйте приложение в настройках по пути `myproject/settings.py’:
...
INSTALLED_APPS = [
	...
	'bot-django',
	]
...
  1. Запуск бота Django

Если все прошло успешно, при наборе в терминале команды python manage.py --help вы должны увидеть что-то подобное:

Type 'manage.py help <subcommand>' for help on a specific subcommand.
Available subcommands:
...
[bot-django]
    bot

Как вы, наверное, уже догадались, запуск бота осуществляется командой python manage.py bot.
Если бот успешно запущен, вы должны увидеть в терминале такой ответ:

{'id': 1234567890, 'first_name': 'Крутой-бот', 'is_bot': True, 'username': 'very_cool_bot', 'can_join_groups': False, 'can_read_all_group_messages': False, 'supports_inline_queries': False}

Полезные ресурсы

  1. Официальная документация Telegram Bot API in English
  2. Документация Telegram Bot API на русском
  3. Уроки про Telegram-боты от Олега Молчанова на YouTube
  4. Уроки по фреймворку Aiogram от Physics is Simple на YouTube

В первой части мы сделали гороскоп на Python, который выдаёт нам прогноз на день по знаку зодиака. Сегодня пойдём дальше: теперь этот же генератор гороскопов будет встроен в Телеграм в виде бота.

Да. То, что обычно на курсах продают за 50 тысяч рублей, мы вам сейчас расскажем за 15 минут бесплатно.

Как всё будет работать

В этом проекте три звена: наш компьютер с Python, сервер Телеграма и Телеграм-клиент.

На компьютере работает интерпретатор Python, а внутри интерпретатора крутится наша программа на Python. Она отвечает за весь контент: в неё заложены все шаблоны текста, вся логика, всё поведение.

Внутри программы на Python работает библиотека, которая отвечает за общение с сервером Телеграма. В библиотеку мы вшили секретный ключ, чтобы сервер Телеграма понимал, что наша программа связана с определённым ботом.

Когда клиент с Телеграмом запрашивает у бота гороскоп, запрос приходит на сервер, а сервер отправляет его на наш компьютер. Запрос обрабатывается программой на Python, ответ идёт на сервер Телеграма, сервер отдаёт ответ клиенту. Изи:

Телеграм-бот на Python

Обратите внимание, что работать наш бот будет только тогда, когда включён компьютер и на нём запущена программа на Python. Если компьютер выключится, пропадёт интернет или вы отключите интерпретатор, то бот работать перестанет: запросы будут приходить, но никто на них не ответит. В одной из следующих частей мы сделаем так, чтобы это всё работало на удалённом сервере и было всегда доступно.

Что будем делать

Если записать пошагово наш план, то он будет выглядеть так:

  1. Регистрируем бота в Телеграме.
  2. Устанавливаем Python-библиотеку для работы с Телеграмом.
  3. Добавляем библиотеку в программу с гороскопом и учим программу реагировать на сообщения в чате.
  4. Пишем там же код, который покажет кнопки для выбора знаков зодиака.
  5. Сделаем так, чтобы по кнопкам появлялся гороскоп для этого знака.

Теперь по очереди разберём каждый пункт.

1. Регистрация нового бота

В Телеграме находим канал @BotFather — он отвечает за регистрацию новых ботов:

Первый в списке со специальным значком подтверждения — это он.

Нажимаем Start и пишем команду /newbot. Нас по очереди спросят про название бота и его никнейм (мы придумали только с третьей попытки, потому что остальные были заняты):

С третьей попытки нам дали нового бота и токен для управления. Токен нужен для управления ботом, поэтому на экране его нет.

2. Установка библиотеки

Есть два основных способа работать с телеграмом в Python: через библиотеку telebot и с помощью Webhook. Мы будем использовать библиотеку — так проще и быстрее.

Чтобы её установить, запускаем командную строку от имени администратора (если у вас Windows) и пишем команду pip install pytelegrambotapi

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

Подключаем библиотеку и получаем сообщения

Чтобы программа на Python умела управлять Телеграм-ботами, нужно в самое начало кода добавить строки:

bot = telebot.TeleBot('токен');

Единственное, о чём нужно не забыть — заменить слово «токен» на настоящий токен, который дал нам @BotFather. Открываем программу гороскопа и добавляем.

# Подключаем модуль случайных чисел 
import random
# Заготовка для первого предложения
first = ["Сегодня — идеальный день для новых начинаний.","Оптимальный день для того, чтобы решиться на смелый поступок!","Будьте осторожны, сегодня звёзды могут повлиять на ваше финансовое состояние.","Лучшее время для того, чтобы начать новые отношения или разобраться со старыми.","Плодотворный день для того, чтобы разобраться с накопившимися делами."]
second = ["Но помните, что даже в этом случае нужно не забывать про","Если поедете за город, заранее подумайте про","Те, кто сегодня нацелен выполнить множество дел, должны помнить про","Если у вас упадок сил, обратите внимание на","Помните, что мысли материальны, а значит вам в течение дня нужно постоянно думать про"]
second_add = ["отношения с друзьями и близкими.","работу и деловые вопросы, которые могут так некстати помешать планам.","себя и своё здоровье, иначе к вечеру возможен полный раздрай.","бытовые вопросы — особенно те, которые вы не доделали вчера.","отдых, чтобы не превратить себя в загнанную лошадь в конце месяца."]
third = ["Злые языки могут говорить вам обратное, но сегодня их слушать не нужно.","Знайте, что успех благоволит только настойчивым, поэтому посвятите этот день воспитанию духа.","Даже если вы не сможете уменьшить влияние ретроградного Меркурия, то хотя бы доведите дела до конца.","Не нужно бояться одиноких встреч — сегодня то самое время, когда они значат многое.","Если встретите незнакомца на пути — проявите участие, и тогда эта встреча посулит вам приятные хлопоты."]
# выводим знаки зодиака
print("1 — Овен")
print("2 — Телец")
print("3 — Близнецы")
print("4 — Рак")
print("5 — Лев")
print("6 — Дева")
print("7 — Весы")
print("8 — Скорпион")
print("9 — Стрелец")
print("10 — Козерог")
print("11 — Водолей")
print("12 — Рыбы")
# Спрашиваем у пользователя про его знак
zodiac = int(input("{blue}Введите число с номером знака зодиака: {endcolor}".format(blue="33[96m", endcolor="33[0m")))
# Если число введено верно — выдаём гороскоп
if 0 < zodiac < 13:
    print(random.choice(first), random.choice(second), random.choice(second_add), random.choice(third))
else:
    print("Вы ошиблись с числом, запустите программу ещё раз")
    

Теперь научим бота реагировать на слово «Привет». Для этого добавим после строчек с импортом новый метод и сразу пропишем в нём реакцию на нужное слово. Если не знаете, что такое метод и зачем он нужен, — читайте статью про ООП.

@bot.message_handler(content_types=['text'])
def get_text_messages(message):
  if message.text == "Привет":
      bot.send_message(message.from_user.id, "Привет, сейчас я расскажу тебе гороскоп на сегодня.")
  elif message.text == "/help":
      bot.send_message(message.from_user.id, "Напиши Привет")
  else:
      bot.send_message(message.from_user.id, "Я тебя не понимаю. Напиши /help.")
        

И последнее, что нам осталось сделать до запуска, — добавить после метода такую строчку:

bot.polling(none_stop=True, interval=0)

Она скажет программе, чтобы она непрерывно спрашивала у бота, не пришли ли ему какие-то новые сообщения. Запускаем программу и проверяем, как работает наш бот.

Бот отвечает именно так, как мы запрограммировали. Класс.
Такая ошибка во время запуска программы означает, что компьютер не может соединиться с сервером telegram.org, потому что его блокирует Роскомнадзор. Что делать? Сложно сказать. Если бы вы жили в другой стране, этой проблемы бы не было. Ещё можно использовать какие-то средства, которые направляют ваш трафик через другую страну, но рассказ об этих средствах является в России преступлением, поэтому тут мы вам ничего не можем подсказать.

Добавляем кнопки

Чтобы пользователям нашего бота было удобно, покажем им сразу все знаки зодиака в виде кнопок. А потом сделаем так, что когда на них нажимаешь — появляется гороскоп для этого знака на сегодня.

Добавляем код с кнопками в раздел, который реагирует на «Привет»:

# Готовим кнопки
keyboard = types.InlineKeyboardMarkup()
# По очереди готовим текст и обработчик для каждого знака зодиака
key_oven = types.InlineKeyboardButton(text='Овен', callback_data='zodiac')
# И добавляем кнопку на экран
keyboard.add(key_oven)
key_telec = types.InlineKeyboardButton(text='Телец', callback_data='zodiac')
keyboard.add(key_telec)
key_bliznecy = types.InlineKeyboardButton(text='Близнецы', callback_data='zodiac')
keyboard.add(key_bliznecy)
key_rak = types.InlineKeyboardButton(text='Рак', callback_data='zodiac')
keyboard.add(key_rak)
key_lev = types.InlineKeyboardButton(text='Лев', callback_data='zodiac')
keyboard.add(key_lev)
key_deva = types.InlineKeyboardButton(text='Дева', callback_data='zodiac')
keyboard.add(key_deva)
key_vesy = types.InlineKeyboardButton(text='Весы', callback_data='zodiac')
keyboard.add(key_vesy)
key_scorpion = types.InlineKeyboardButton(text='Скорпион', callback_data='zodiac')
keyboard.add(key_scorpion)
key_strelec = types.InlineKeyboardButton(text='Стрелец', callback_data='zodiac')
keyboard.add(key_strelec)
key_kozerog = types.InlineKeyboardButton(text='Козерог', callback_data='zodiac')
keyboard.add(key_kozerog)
key_vodoley = types.InlineKeyboardButton(text='Водолей', callback_data='zodiac')
keyboard.add(key_vodoley)
key_ryby = types.InlineKeyboardButton(text='Рыбы', callback_data='zodiac')
keyboard.add(key_ryby)
# Показываем все кнопки сразу и пишем сообщение о выборе
bot.send_message(message.from_user.id, text='Выбери свой знак зодиака', reply_markup=keyboard)

Кнопки есть, но пока не работают. Сейчас исправим.

Добавляем обработчик кнопок

Скорее всего, вы заметили, что в каждой кнопке у нас написано callback_data='zodiac'. Это значит, что при нажатии на любую кнопку у нас будет вызываться один и тот же метод, который отвечает за гороскоп. Если вы хотите сделать честный гороскоп, придётся в каждой кнопке прописать своё название обработчика, а потом задать его поведение, тоже для каждой кнопки.

Давайте сделаем обработчик кнопок, который будет реагировать на ‘zodiac’ и выдавать случайный текст, как в исходной программе. Для этого добавим новый метод в программу:

# Обработчик нажатий на кнопки
@bot.callback_query_handler(func=lambda call: True)
def callback_worker(call):
  # Если нажали на одну из 12 кнопок — выводим гороскоп
  if call.data == "zodiac": 
    # Формируем гороскоп
    msg = random.choice(first) + ' ' + random.choice(second) + ' ' + random.choice(second_add) + ' ' + random.choice(third)
    # Отправляем текст в Телеграм
    bot.send_message(call.message.chat.id, msg)

Нажимаем на кнопку — получаем текст гороскопа.

Убираем лишнее

Теперь у нас есть готовый бот, и нам осталось только убрать лишний код, который раньше отвечал за вывод знаков зодиака в консоли. После чистки получаем готовую программу:

# Подключаем модуль случайных чисел 
import random
# Подключаем модуль для Телеграма
import telebot
# Указываем токен
bot = telebot.TeleBot('токен')
# Импортируем типы из модуля, чтобы создавать кнопки
from telebot import types
# Заготовки для трёх предложений
first = ["Сегодня — идеальный день для новых начинаний.","Оптимальный день для того, чтобы решиться на смелый поступок!","Будьте осторожны, сегодня звёзды могут повлиять на ваше финансовое состояние.","Лучшее время для того, чтобы начать новые отношения или разобраться со старыми.","Плодотворный день для того, чтобы разобраться с накопившимися делами."]
second = ["Но помните, что даже в этом случае нужно не забывать про","Если поедете за город, заранее подумайте про","Те, кто сегодня нацелен выполнить множество дел, должны помнить про","Если у вас упадок сил, обратите внимание на","Помните, что мысли материальны, а значит вам в течение дня нужно постоянно думать про"]
second_add = ["отношения с друзьями и близкими.","работу и деловые вопросы, которые могут так некстати помешать планам.","себя и своё здоровье, иначе к вечеру возможен полный раздрай.","бытовые вопросы — особенно те, которые вы не доделали вчера.","отдых, чтобы не превратить себя в загнанную лошадь в конце месяца."]
third = ["Злые языки могут говорить вам обратное, но сегодня их слушать не нужно.","Знайте, что успех благоволит только настойчивым, поэтому посвятите этот день воспитанию духа.","Даже если вы не сможете уменьшить влияние ретроградного Меркурия, то хотя бы доведите дела до конца.","Не нужно бояться одиноких встреч — сегодня то самое время, когда они значат многое.","Если встретите незнакомца на пути — проявите участие, и тогда эта встреча посулит вам приятные хлопоты."]
# Метод, который получает сообщения и обрабатывает их
@bot.message_handler(content_types=['text'])
def get_text_messages(message):
    # Если написали «Привет»
    if message.text == "Привет":
        # Пишем приветствие
        bot.send_message(message.from_user.id, "Привет, сейчас я расскажу тебе гороскоп на сегодня.")
        # Готовим кнопки
        keyboard = types.InlineKeyboardMarkup()
        # По очереди готовим текст и обработчик для каждого знака зодиака
        key_oven = types.InlineKeyboardButton(text='Овен', callback_data='zodiac')
        # И добавляем кнопку на экран
        keyboard.add(key_oven)
        key_telec = types.InlineKeyboardButton(text='Телец', callback_data='zodiac')
        keyboard.add(key_telec)
        key_bliznecy = types.InlineKeyboardButton(text='Близнецы', callback_data='zodiac')
        keyboard.add(key_bliznecy)
        key_rak = types.InlineKeyboardButton(text='Рак', callback_data='zodiac')
        keyboard.add(key_rak)
        key_lev = types.InlineKeyboardButton(text='Лев', callback_data='zodiac')
        keyboard.add(key_lev)
        key_deva = types.InlineKeyboardButton(text='Дева', callback_data='zodiac')
        keyboard.add(key_deva)
        key_vesy = types.InlineKeyboardButton(text='Весы', callback_data='zodiac')
        keyboard.add(key_vesy)
        key_scorpion = types.InlineKeyboardButton(text='Скорпион', callback_data='zodiac')
        keyboard.add(key_scorpion)
        key_strelec = types.InlineKeyboardButton(text='Стрелец', callback_data='zodiac')
        keyboard.add(key_strelec)
        key_kozerog = types.InlineKeyboardButton(text='Козерог', callback_data='zodiac')
        keyboard.add(key_kozerog)
        key_vodoley = types.InlineKeyboardButton(text='Водолей', callback_data='zodiac')
        keyboard.add(key_vodoley)
        key_ryby = types.InlineKeyboardButton(text='Рыбы', callback_data='zodiac')
        keyboard.add(key_ryby)
        # Показываем все кнопки сразу и пишем сообщение о выборе
        bot.send_message(message.from_user.id, text='Выбери свой знак зодиака', reply_markup=keyboard)
    elif message.text == "/help":
        bot.send_message(message.from_user.id, "Напиши Привет")
    else:
        bot.send_message(message.from_user.id, "Я тебя не понимаю. Напиши /help.")
# Обработчик нажатий на кнопки
@bot.callback_query_handler(func=lambda call: True)
def callback_worker(call):
    # Если нажали на одну из 12 кнопок — выводим гороскоп
    if call.data == "zodiac": 
        # Формируем гороскоп
        msg = random.choice(first) + ' ' + random.choice(second) + ' ' + random.choice(second_add) + ' ' + random.choice(third)
        # Отправляем текст в Телеграм
        bot.send_message(call.message.chat.id, msg)
# Запускаем постоянный опрос бота в Телеграме
bot.polling(none_stop=True, interval=0)

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

Что дальше

Впереди — безграничные возможности:

  • можно сделать индивидуальный гороскоп для каждого знака;
  • научить бота новым командам;
  • присылать свежий гороскоп каждое утро;
  • наладить непрерывную работу на веб-сервере.

Напишите в комментариях, что бы вы хотели от такого бота? Что должен уметь идеальный бот с гороскопом?

С помощью языка Python и сервера Heroku мы напишем бот для мессенджера Telegram. Процесс создания простой, а помощник действительно полезный.

Вынуждены разочаровать тех, кто представляет ботов, как инструмент исключительно для автоответов и искусственной активности. Думайте о Telegram боте как об автоматизированной учетной записи, которая может выполнять для вас некоторые действия. Например, вы хотите поделиться ссылкой YouTube в групповом чате, но у вас пока нет ссылки.

Telegram

Без бота это выглядело бы так:

  1. Вы открываете в веб-браузере YouTube.
  2. Ищете видео, которым хотите поделиться.
  3. Выбираете общий доступ.
  4. Возвращаетесь в мессенджер и, наконец, делитесь ссылкой.

Конечно, большинство из нас привыкло к вышеуказанному алгоритму, и это неплохо работает. Однако…

С ботом:

  1. Вы находитесь в мессенджере.
  2. Вводите @vid, а затем видео, которым хотите поделиться.

И это всего лишь одна из возможностей ботов. Разработчики Telegram проделали отличную работу и позволили пользователям создавать своих собственных ботов. Отвечая на вопрос, почему это может быть интересно, я могу сказать, что это самый простой способ получить представление об API.

Прежде всего, зарегистрируйтесь. Рекомендую использовать веб-клиент. Откройте кроссплатформенный мессенджер, найдите @BotFather и запустите чат. Отправьте в сообщении /newbot и следуйте инструкциям. После завершения начальных шагов вы получите:

— токен;
— API URL;
— ссылку на документацию.

На момент создания бот 100% пассивен. Вам нужно инициализировать разговор. Для этого откройте поиск и введите имя своего бота, а после начните разговор, нажав /start. Введите что-то вроде «Hello». Это сообщение важно, поскольку это первое обновление, которое получит ваш бот.

Если это первый опыт, откройте новую вкладку в своем браузере и используйте URL-адрес: так вы отправите запрос на сервер Telegram. Пришедший ответ будет в формате JSON и чем-то напоминающим словарь Python. Вы должны увидеть что-то вроде этого:

{"ok":true,"result":[{"update_id":523349956,
"message":{"message_id":51,"from":{"id":303262877,"first_name":"YourName"},"chat":{"id":303262877,"first_name":"YourName","type":"private"},"date":1486829360,"text":"Hello"}}]}

Если вы откроете документацию и заглянете на раздел /sendMessage, то заметите, что требуется 2 дополнительных параметра: chat_id и text. В строке поиска браузера можно использовать ? для первого параметра и & для остальных. Отправка сообщения будет выглядеть следующим образом:

/sendMessage?chat_id=303262877&text=test

Для ответа от бота замените chat_id на значение, которое получите с вызовом /getUpdates.  У нас это 303262877. Текстовый параметр зависит от вас. Запрос должен выглядеть так:

https://api.telegram.org/bot<token>/sendMessage?chat_id=303262877&text=Hello

Подготовка к кодингу

Если ваша операционная система – Windows, но еще не установлен Python, скачайте его здесь. Без разницы, будет это версия 2.x или 3.x. Для примера мы будем использовать Python 3.x. На macOS и Linux обе версии уже установлены (либо минимум Python 2.x), поэтому нет необходимости дополнительно скачивать что-либо.

Следующий шаг – установка системы управления пакетами pip. Для Python 2.7.9 и выше, а также Python 3.4 и выше они уже предустановленны (равно как и для операционных систем macOS/Linux). Если нужно, вы всегда можете проверить это, используя в терминале команду pip –version. При отсутствии данной системы установите ее с помощью команды:

$ sudo apt-get install python-pip.

Интересная штука: разные версии Python работают с разными pip. Для обладателей macOS подойдет эта инструкция. Если же у вас ОС Windows, загрузите get-pip.py, откройте cmd, перейдите к скачанным файлам (директория) и выполните следующее:

$ python get-pip.py

Это было самое сложное. Осталось воспользоваться pip и установить пакет requests:

$ pip install requests

Дополнительно можно скачать PyCharm, хотя этот шаг и не относится к обязательным.

Начинаем кодить

Если принцип API понятен, и у вас есть все необходимые инструменты, давайте создадим скрипт Python, который будет проверять наличие обновлений и отвечать на них желаемым текстом.

Прежде всего, наш Telegram бот должен проверять наличие обновлений. Сообщение можно рассматривать как самое последнее из них. Так или иначе, getUpdates вернет все обновления за последние 24 часа. Давайте создадим небольшой скрипт, чтобы получить последнее обновление:

import requests

url = "https://api.telegram.org/bot<token>/"


def get_updates_json(request):  
    response = requests.get(request + 'getUpdates')
    return response.json()


def last_update(data):  
    results = data['result']
    total_updates = len(results) - 1
    return results[total_updates]

Словарь обновлений состоит из двух элементов — «ok» и «results». Нам нужен второй, который представляет собой список всех обновлений за последние 24 часа. Здесь вы можете посмотреть дополнительную информацию о библиотеке запросов. Основная идея заключается в том, что всякий раз, когда вам нужно получать, обновлять или удалять информацию на сервере, вы отправляете запрос и принимаете ответ.

Следующий шаг – добавление еще 2-х функций. Первая получит chat_id от обновления, а вторая отправит сообщение:

def get_chat_id(update):  
    chat_id = update['message']['chat']['id']
    return chat_id

def send_mess(chat, text):  
    params = {'chat_id': chat, 'text': text}
    response = requests.post(url + 'sendMessage', data=params)
    return response

chat_id = get_chat_id(last_update(get_updates_json(url)))

send_mess(chat_id, 'Your message goes here')

Помните, как мы привязывали параметры с помощью ? и &? Вы можете сделать то же самое, добавив dict в качестве второго необязательного параметра для запросов get/post.

Telegram скрипт готов

Однако он еще далек от идеала. Главный недостаток заключается в том, что вам нужно запускать скрипт каждый раз, когда вы хотите обменяться сообщениями с ботом. Давайте исправим это. Чтобы заставить нашего бота слушать сервер для получения обновлений, необходимо запустить главный цикл. Добавьте from time import sleep после import requests и замените 2 последние строки на:

def main():  
    update_id = last_update(get_updates_json(url))['update_id']
    while True:
        if update_id == last_update(get_updates_json(url))['update_id']:
           send_mess(get_chat_id(last_update(get_updates_json(url))), 'test')
           update_id += 1
    sleep(1)       

if __name__ == '__main__':  
    main()

Хотя мы добавили «тайм-аут» в 1 секунду, приведенный выше пример должен использоваться только в целях тестирования, поскольку он использует частые опросы. Это не очень хорошо для серверов Telegram. Есть еще два способа получить обновления через API – вебхуки и длинные опросы. Но так как мы проверяем обновления с использованием метода getUpdates, запросы будут частыми.

Поскольку мы использовали основной цикл, следует переключиться на длинные опросы. Изменим первую функцию, добавив параметр timeout. Тайм-аут сам по себе не сделает проверку скрипта для обновления реже. Кроме того, тайм-аут будет работать только в том случае, если последние обновления отсутствуют. Для отметки просмотренных обновлений нужно добавить параметр offset:

def get_updates_json(request):  
    params = {'timeout': 100, 'offset': None}
    response = requests.get(request + 'getUpdates', data=params)
    return response.json()

Теперь бот должен работать нормально, но немного изменим код

Неплохо было бы инкапсулировать использованные функции в класс. Модифицированная версия скрипта будет выглядеть таким образом:

import requests  
import datetime

class BotHandler:

    def __init__(self, token):
        self.token = token
        self.api_url = "https://api.telegram.org/bot{}/".format(token)

    def get_updates(self, timeout=30):
        method = 'getUpdates'
        params = {'timeout': timeout}
        resp = requests.get(self.api_url + method, params)
        result_json = resp.json()['result']
        return result_json

    def send_message(self, chat_id, text):
        params = {'chat_id': chat_id, 'text': text}
        method = 'sendMessage'
        resp = requests.post(self.api_url + method, params)
        return resp

    def get_last_update(self):
        get_result = self.get_updates()

        if len(get_result) > 0:
            last_update = get_result[-1]
        else:
            last_update = get_result[len(get_result)]

        return last_update

Ну и последний штрих – объявить переменные и научить нашего бота некоторым манерам. Идея состоит в том, чтобы сделать Telegram бота, который будет приветствовать вас раз в день. В зависимости от времени суток сообщение должно быть разным. Если вы хотите попробовать этот скрипт, добавьте строку import datetime после import requests , а также дополните скрипт данным кодом:

greet_bot = BotHandler(token)  
greetings = ('hello', 'hi', 'greetings', 'sup')  
now = datetime.datetime.now()


def main():  
    new_offset = None
    today = now.day
    hour = now.hour

    while True:
        greet_bot.get_updates(new_offset)

        last_update = greet_bot.get_last_update()

        last_update_id = last_update['update_id']
        last_chat_text = last_update['message']['text']
        last_chat_id = last_update['message']['chat']['id']
        last_chat_name = last_update['message']['chat']['first_name']

        if last_chat_text.lower() in greetings and today == now.day and 6 <= hour < 12:
            greet_bot.send_message(last_chat_id, 'Good Morning  {}'.format(last_chat_name))
            today += 1

        elif last_chat_text.lower() in greetings and today == now.day and 12 <= hour < 17:
            greet_bot.send_message(last_chat_id, 'Good Afternoon {}'.format(last_chat_name))
            today += 1

        elif last_chat_text.lower() in greetings and today == now.day and 17 <= hour < 23:
            greet_bot.send_message(last_chat_id, 'Good Evening  {}'.format(last_chat_name))
            today += 1

        new_offset = last_update_id + 1

if __name__ == '__main__':  
    try:
        main()
    except KeyboardInterrupt:
        exit()

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

Переходим к развертыванию

Последний шаг – это как вишенка на торте, которая позволит сделать из вашего Telegram бота настоящего помощника: его необходимо развернуть на сервере. Скорее всего, у вас нет собственного сервера, и уж вряд ли вы захотите покупать для этого дорогостоящую аппаратуру. К счастью, существует множество облачных сервисов, на которых можно бесплатно разместить приложение. Давайте развернем небольшой скрипт на Heroku.

Прежде всего, вам нужна учетная запись на GitHub. Переходите на главную страницу и регистрируйтесь: это обязательный шаг для любого, кто действительно заинтересован в программировании. Помимо учетной записи GitHub, вам также необходимо установить Git.

Если у вас Linux, выполните следующую команду:

$ sudo apt-get install git-all

Для macOS и Windows можно произвести ручную установку программы. И, конечно же, не забудьте завести аккаунт на Heroku.

Устанавливаем virtualenv, используя команду:

$ pip install virtualenv

Теперь вам нужно немного упорядочить свои файлы. Создайте новую папку, откройте терминал/cmd и перейдите в нее. Для инициализации в созданной папке virtualenv введите:

$ virtualenv my_env

Название не имеет особого значения, однако лучше делать его максимально понятным. Перейдите в папку my_env. Следующий шаг – клонировать ваш репозиторий Git. Введите следующую команду:

$ git clone https://github.com/yourprofilename/yourreponame

Поместите свой скрипт в папку и вернитесь в my_env, чтобы запустить virtualenv.

Windows:

$ scriptsactivate.bat

Linux/macOS:

$ source bin/activate

При успешном запуске virtualenv командная строка должна начинаться с (my_env). Установите модуль requests, перейдя в папку репозитория:

$ pip install requests

Для создания зависимостей Heroku введите:

$ pip freeze > requirements.txt

Создайте файл Procfile. В нем вы найдете инструкции для работы со своим скриптом. Имя должно быть Procfile или Procfile.windows, если это Windows. Не стоит включать в название .txt, .py или любые другие расширения. Содержимое файла должно быть следующим (измените my_bot на название вашего скрипта):

web: python my_bot.py

Добавьте файл __init__.py в свою папку. Файл может быть пустым, но он должен находиться там. Введите такую команду:

$ git init
$ git add .
$ git commit -m ‘short message that describe changes to commit’
$ git push -u https://github.com/yourusername/nameofrepo

А теперь развернем нашего Telegram бота на Heroku. Потренируемся делать это через консоль. При возникновении проблем, обратитесь к руководству. Для Windows и macOS нужно установить интерфейс командной строки, используя этот гайд. Для Ubuntu используем команды:

$ sudo add-apt-repository "deb https://cliassets.heroku.com/branches/stable/apt ./"
$ curl -L https://cli-assets.heroku.com/apt/release.key |
$ sudo apt-key add -
$ sudo apt-get update
$ sudo apt-get install heroku

Интересный факт: на моем домашнем компьютере все прошло без сучка и задоринки, а вот на ноутбуке последний шаг выполнить не удалось. Если вы столкнулись с такой же проблемой, проверьте терминал на наличие всех зависимостей. После выполните команды:

$ heroku login
$ heroku create
$ git push heroku master
$ heroku ps:scale web=1
$ heroku open

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

$ heroku logs --trail

Коды ошибок можно посмотреть здесь.

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

Понравилась статья? Поделить с друзьями:
  • Как написать свое ядро для сервера майнкрафт
  • Как написать свастику на клавиатуре
  • Как написать свадебную клятву невесте
  • Как написать свадебному фотографу
  • Как написать свадебное приглашение