Как создать простого командного бота в python

Часть 2 Написание кода

sudo apt-get install python python-pip

Далее воспользуемся системой управления пакетами PIP, которая используется для установки и управления программными пакетами, и установим библиотеку PyTelegramBotAPI (Telebot):

Создадим логику работы нашего бота. Используя полноценный IDE или простой текстовый редактор создадим файл ourbot.py и заполним его необходимой логикой.

import telebot 

bot = telebot.TeleBot(‘851216368:AAG6_JHHsIqAK-lX2CxOWQHTAM109zdrcZM’)

Теперь создадим метод, для получения сообщений.

Возможности PyTelegramBotAPI позволяют отправлять боту аудио (content_types=[‘audio’), видео (content_types=[‘video’), документы (content_types=[‘document’), текст (content_types=[‘text’), географический адрес (content_types=[‘location’), данные контакта (content_types=[‘contact’) и стикеры (content_types=[‘sticker’).  Мы, для простоты опыта, будем общаться с ботом только текстом:

@bot.message_handler(content_types=)
def handle_text_messages(message):

Теперь рассмотрим логику обработки наших текстовых сообщений. Мы хотим захардкодить простое общение бота с пользователем: бот должен уметь здороваться, когда с ним здороваются, уметь отвечать на вопросы «Кто ты?», «Как тебя зовут?» и «Что ты умеешь?».

Видео курсы по схожей тематике:

UX/UI Design Стартовый

Артур Рыгус

UX/UI Design мобильных приложений

Владислав Шевченко

Создаем игру типа “Pokémon Go“

Роман Самчук

    if message.text == «Привет»:
        bot.send_message(message.from_user.id, «Привет»)
    elif message.text == «Кто ты?»:
        bot.send_message(message.from_user.id, «Я тестовый чатбот для учебного примера.»)
    elif message.text == «Как тебя зовут?»:
        bot.send_message(message.from_user.id, «Меня зовут MyFirstTestBot.»)
    elif message.text == «Что ты умеешь?»:
        bot.send_message(message.from_user.id, «Я умею отвечать на несколько простых вопросов — кто я, как меня зовут и что я умею делать.»)
    else:
        bot.send_message(message.from_user.id, «Я тебя не понимаю. Напиши что-то другое.»)

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

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

Задачей этого метода является создание потока, в котором бот отправляет запросы на сервер, уточняя таким способом, не писал ли ему кто-то сообщение. Параметр none_stop: False означает, что наша программа будет продолжать отправлять запросы на сервер после получения сообщения об ошибке от сервера Telegram.

Сохраним наш код:

Мы можем протестировать работу нашего бота, запустив его код в той IDE, в которой мы писали. И написав нашему боту в мессенджере.

Все работает.

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

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

pyTelegramBotApi

Ссылки на документации всех библиотек будут в конце.

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

pyTelegramBotApi является просто обёрткой для всего Telegram Bot API, но здесь разберутся только основные составляющие.Взаимодействие с ботом происходит через переменную bot (токен надо вставить свой). Декоратор @message_handler реагирует на входящие сообщение.Message – это объект из Bot API, содержащий в себе информацию о сообщении. Полезные поля: message.chat.id – идентификатор чатаmessage.from.id – идентификатор пользователяmessage.text – текст сообщенияФункция send_message принимает идентификатор чата (берем его из сообщения) и текст для отправки.

Замена клавиатуры

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

ReplyKeyboardMarkup – и есть та самая клавиатура. Метод row() создает ряд (максимум 12) из кнопок, передаваемых в качестве аргумента.Также есть особенная клавиатура types.ReplyMarkupRemove(), которая меняет клавиатуру на стандартную.

Клавиатура для сообщений

Можно создавать клавиатуру для отдельного сообщения. Передавать его нужно так же в аргумент reply_markup:

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

Для обработки обязательно указать аргумент func для «отсеивания» Callback запросов.После обработки каждого запроса нужно выполнить команду answer_callback_query, чтобы Telegram понял, что запрос обработан. В поле callback.data хранится информация из callback_data нажатой кнопки.

Изменение сообщений

У ботов есть функция изменения своих сообщений (можно использовать, чтобы сделать перелистывание страниц, например). Для этого нужно воспользоваться методом edit_message_text (edit_message_caption для картинок):

Смысл аргументов понятен из их названия.

Бот лайкающий посты на сайте.

Последовательность действий у нас следующая.

  1. Зайти на сайт under-prog.ru (открыть браузер)
  2. Пройтись по каждому из постов.
  3. Нажать кнопку лайк, если она не нажата.
  4. Закрыть браузер.

Первый пункт мы уже сделали, перейдем ко второму.

Пройтись по каждому из постов.

Зайдите на сайт, и нажмите кнопку F12.

У вас откроются инструменты разработчика. Изучив разметку, мы понимаем, что все посты находятся в теге article.

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

Данный селектор указывает:

  • На элемент с тегом a
  • который находится находится внутри тега h2 с классом entry-title
  • тот, в свою очередь, находится внутри тега header с классом entry-header
  • тег header находится внутри тега div с классом blog-entry-content
  • тот, находится в теге div
  • тег div находится внутри тега article

Теперь, дополним бота.

Разберем новую функцию.

Данная функция ищет элементы по css селектору. В результате своей работы, она возвращает массив элементов.

В-общем, мы из этого массива, достали первый элемент, и при помощи функции get_attribute(), получили значение атрибута href (ссылка на пост).

И вывели его на экран.

Запустите скрипт, в консоли должна появится ссылка на первый пост.

Если закинуть массив элементов в цикл, то получится извлечь ссылки на все посты.

Отлично, ссылки на все посты получены, осталось всем этим постам, поставить лайк.

Нажать кнопку лайк, если она не нажата

Сначала перекопируем наши ссылки в отдельный массив. Замените это:

На это:

Далее напишем код, отвечающий за нажатие кнопки лайк.

Разберем данные строки.

Данная строка ищет кнопку с помощью css_селектора, и получает строку с названиями классов нашей кнопки.

Далее, при помощи функции find (стандартная функция python), мы получаем индекс подстроки ‘wp_ulike_btn_is_active‘, если не удалось найти подстроку, функция find возвращает -1, этим мы и воспользовались в нашем условии. Т.е. если атрибут ‘class‘ не содержит подстроку ‘wp_ulike_btn_is_active‘, то.

Кликаем по кнопке лайк.

Осталось закрыть браузер, делается это с помощью функции quit().

Бот завершен, запустите скрипт, и наслаждайтесь автоматизацией.

Признавая сообщения, которые мы уже видели

Вместо того, чтобы просить телеграммы для всех наших недавних сообщений с каждым вызовом, а затем пытаться понять, какие из них нас интересуют, мы можем сказать телеграмме, что мы уже обработали определенные сообщения, и что мы хотим прекратить получать их как часть звонки. Каждое обновление имеет поле, и это инкрементные (более поздние сообщения имеют более высокие числа). Когда мы делаем API Call, мы можем необязательно пройти аргумент и дать как значение. Это говорит о телеграмме, которую мы уже видели и обработали это сообщение и что мы не хотим этого снова. Это также означает, что телеграмма никогда не отправит нам никаких предыдущих сообщений (сообщения с более низким ), поэтому мы должны убедиться, что мы действительно закончили всеми сообщениями, прежде чем делать это.

Измените наш бот следующим образом:

Добавьте дополнительное Смещение Параметр на нашу функцию getupdate. Если это указано, мы передадим его на API Telegram, чтобы указать, что мы не хотим получать сообщения с меньшими идентификаторами, чем это. Модифицированная функция должна выглядеть так:

def get_updates(offset=None):
    url = URL + "getUpdates"
    if offset:
        url += "?offset={}".format(offset)
    js = get_json_from_url(url)
    return js

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

def get_last_update_id(updates):
    update_ids = []
    for update in updates:
        update_ids.append(int(update))
    return max(update_ids)

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

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

def echo_all(updates):
    for update in updates:
        try:
            text = update
            chat = update
            send_message(text, chat)
        except Exception as e:
            print(e)

Обновите код в Главная () Так что это выглядит так:

def main():
    last_update_id = None
    while True:
        updates = get_updates(last_update_id)
        if len(updates) > 0:
            last_update_id = get_last_update_id(updates) + 1
            echo_all(updates)
        time.sleep(0.5)

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

Обратите внимание, что мы должны проверить, есть ли новые обновления (которые мы делаем на третьей строке ), и что мы должны всегда отправлять идентификатор обновления, который является одним из них, как предыдущий, который мы видел (т.е. мы на самом деле говорим телеграмму, которую ID мы ожидаем, а не какой мы видели)

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

Создание интерфейса бота

Теперь мы можем приступить к написанию той части программы, которая обрабатывает запросы из Telegram. Создадим новую repl-среду, а в качестве языка программирования выберем Python.

Наш бот должен взаимодействовать с Telegram. Для этого нам понадобится доступ к Telegram REST API. Есть много способов сделать это, но в рамках данной статьи мы будем использовать удобную библиотеку, обернутую обернута вокруг API.

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


Создание переменной среды

Это гарантирует, что наш токен доступен как переменная среды и что к нему не смогут получить доступ люди, имеющие доступ к нашей среде repl (в бесплатной версии она открыта для всех, — прим. переводчика).

Собираем все воедино

Если мы запустим нашу программу сейчас, веб-приложение еще не будет работать. Flask должен прослушивать запросы аналогично библиотеке Telegram. Чтобы запустить сервер Flask, мы вполне можем в конце нашей программы использовать  .

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

#updater.idle()
app.run(host='0.0.0.0', port=8080)

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

Polling vs Webhook

Если бы не противостояние polling vs webhook и некоторые сложности (отчасти надуманные) с webhook’ом, в этой статье не было бы необходимости. Раз это имеет принципиальное значение, давайте разберемся подробнее.

Что такое бот и как он общается с Телеграмом? Очевидно, бот это программа, которая работает на вашем компьютере или сервере. А общение с Телеграмом происходит методами отправки и получения сообщений. И если с отправкой сообщений примерно все ясно, вариант один — послать (адрес “куда” мы знаем). То вариантов получения ботом сообщений от Телеграма два.

Первый — это опрос (буквальный перевод слова polling) сервера Телеграма на наличие сообщений для бота. Второй — это “почтовый ящик” с ip-адресом (webhook — можно перевести как веб-ловушка), на который приходят сообщения от сервера Телеграма.

Самая простая аналогия с реальной почтой. Пусть почта (почтовое отделение) — это сервер Телеграма, а вы — это ваш бот. Тогда, в первом случае (polling) вам приходится ходить на почту за корреспонденцией. И если хотите получать сообщения без задержек, то придется не ходить, а буквально бегать без передышек взад и вперед. Как понимаем, жить на почте в ожидании сообщений запрещено! Во втором случае вы сообщаете почтовому отделению свой домашний адрес и ждете корреспонденцию спокойно дома, попивая чай или покуривая бамбук.

Конечно, для человека первый вариант кажется самым суровым. Но, говоря между нами, если бегать за сообщениями мы посылаем железку с кодом, то нам должно быть все равно. И так бы и было, если бы не одна проблема. Время от времени, почта (сервер Телеграма) то закрывается на обед, то переезжает. И у вас в первом варианте (polling) происходит трагедия, которая в реальном мире ботов заканчивается их зависанием и сбоем.

Во втором же случае “почтового ящика” с адресом (webhook’ом) такого не происходит. Потому что ни вы, ни ваш бот, никуда не ходите, а просто ждете. И вам все равно, куда переехало почтовое отделение, потому что почту вам приносит почтальон.

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

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

Я сначала не поверил, что проблема настолько серьезна. И сделал вариант с polling’ом, предполагая, что как-нибудь позже перепишу на webhook’и. Но это не сработало. На моем домашнем компе с macOS бот работал без проблем и час и два (конечно, с VPN) и не падал. Но стоило мне перенести его на облачный сервер на Linux’е он не мог проработать и 20 минут. Я пытался решить эту проблему разными путями и настройками, но получал лишь разный код ошибок. Селяви, это Телеграм. Потеряв день, пришлось взяться за webhook’и, не откладывая на потом. В конце концов, я же хотел запустить бот на сервере сейчас, а не через год.

Подготовка — Создаём config.py и используем Proxy.

Файл config.py понадобится нам для хранения Токена бота и proxy (Если используете). Сложного тут нет ничего, обычный файл с двумя переменными, которые мы будет использовать в основном файле проекта.

token = ‘Token’
proxy = ‘socks5://Proxy_User:Proxy_Password@Proxy_IP:Proxy_Port’

1
2

token=’Token’

proxy=’socks5://Proxy_User:Proxy_Password@Proxy_IP:Proxy_Port’

Так просто выглядит файл config.py который нужно импортировать в основном файле проекта, созданием которого мы сейчас займемся. Я его так и назову «telegram_bot.py»

import telebot
from telebot import apihelper # Нужно для работы Proxy
import config # Импорт config.py
import urllib.request # request нужен для загрузки файлов от пользователя

bot = telebot.TeleBot(config.token) # Передаём токен из файла config.py
apihelper.proxy = {‘http’:config.proxy} # Передаём Proxy из файла config.py

bot.polling() # запускаем бота

1
2
3
4
5
6
7
8
9
10

importtelebot

fromtelebot importapihelper# Нужно для работы Proxy

importconfig# Импорт config.py

importurllib.request# request нужен для загрузки файлов от пользователя

bot=telebot.TeleBot(config.token)# Передаём токен из файла config.py

apihelper.proxy={‘http’config.proxy}# Передаём Proxy из файла config.py

bot.polling()# запускаем бота

Практически Telegram бот на Python уже готов к работе и его можно запустить, если нет ошибок то бот работает. Но есть одна проблема. Бот работает через прокси, а библиотека request, которая нам нужна для загрузки файлов от пользователя, в данном случаи не использует прокси, по этому скачивать файлы не получиться… Это дело можно исправить, но лучше использовать VPN а от proxy отказаться.

В дальнейшем будем считать, что у нас настроен VPN ну или бот пишется непосредственно на сервере))) Теперь когда с подключением разобрались, пришло время научить бота совершать какие либо действия.

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

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

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

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

Помимо определения викторины, нам нужно хранить некоторую дополнительную информацию

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

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

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

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

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

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

Но ничего не происходит! Сейчас разберёмся.

Установка Python и Pip

Для того, чтобы создать чат-бот на Rasa, очевидно, понадобится очень важный инструмент — python, а ещё установить зависимости (сторонние библиотеки), для чего обычно используется встроенный в python инструмент — pip.

На самом деле вовсе не обязательно заниматься установкой Python. Для того, чтобы установить необходимые зависимости можно воспользоваться open-source библиотекой miniconda. Это более легковесная версия Anaconda, которая содержит conda, python, а также несколько дополнительных полезных пакетов, таких как pip, zlib и другие.

После установки проверить версию conda можно следующим образом:

Для того, чтобы обновить conda, выполните следующую команду:

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

Как работает чат-бот?

Существует два типа ботов: работающие по правилам и самообучающиеся.

  • Бот первого типа отвечает на вопросы, основываясь на некоторых правилах, которым он обучен. Правила могут быть как простыми, так и очень сложными. Боты могут обрабатывать простые запросы, но не справлятся со сложными.
  • Самообучающиеся боты создаются с использованием основанных на машинном обучении методов и определенно более эффективны, чем боты первого типа. Самообучающиеся боты бывают двух типов: поисковые и генеративные.

В поисковых ботах используются эвристические методы для выбора ответа из библиотеки предопределенных реплик. Такие чат-боты используют текст сообщения и контекст диалога для выбора ответа из предопределенного списка. Контекст включает в себя текущее положение в древе диалога, все предыдущие сообщения и сохраненные ранее переменные (например, имя пользователя). Эвристика для выбора ответа может быть спроектирована по-разному: от условной логики «или-или» до машинных классификаторов.

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

В этой статье мы научимся писать код простых поисковых чат-ботов на основе библиотеки NLTK.

Установка библиотеки “rasa”

Установить библиотеку можно воспользовавшись pip:

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

Чтобы проверить доступные аргументы rasa можно ввести команду:

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

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

а также предоставлен выбор обучать бота или нет:

Если согласитесь, вы сможете поговорить с ботом 😉

Команда rasa shell позволяет сделать это прямо в терминале.

Первый бот¶

Давайте создадим файл с базовым шаблоном бота на aiogram:

Первое, на что нужно обратить внимание: aiogram — асинхронная библиотека, поэтому ваши функции тоже должны быть асинхронными,
а перед вызовами методов API нужно ставить ключевое слово await, т.к. эти вызовы возвращают

Асинхронное программирование в Python

Не стоит пренебрегать официальной документацией!
Прекрасный туториал по asyncio доступен на сайте Python.

Если вы в прошлом работали с какой-то другой библиотекой для Telegram, например, pyTelegramBotAPI, то концепция
хэндлеров (обработчиков событий) вам сразу станет понятна, разница лишь в том, что в aiogram хэндлерами управляет диспетчер.
Диспетчер регистрирует функции-обработчики, дополнительно ограничивая перечень вызывающих их событий через фильтры.
После получения очередного апдейта (события от Telegram), диспетчер выберет нужную функцию обработки, подходящую по всем
фильтрам, например, «обработка сообщений, являющихся изображениями, в чате с ID икс и с длиной подписи игрек». Если две
функции имеют одинаковые по логике фильтры, то будет вызвана та, что зарегистрирована раньше.

Чтобы зарегистрировать функцию как обработчик сообщений, нужно сделать одно из двух действий:
1. Навесить на неё декоратор, как в примере выше.
С различными типами декораторов мы познакомимся позднее.
2. Напрямую вызвать метод регистрации у диспетчера.

Рассмотрим следующий код:

Давайте запустим с ним бота:

Функция не работает, т.к. диспетчер о ней не знает. Исправим эту ошибку
и отдельно зарегистрируем функцию:

Снова запустим бота:

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

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

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

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

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

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

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

Выбор бокса и системы

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

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

Операционная система подойдет любая, но если это ваш первый проект, то лучше выбрать Ubuntu: она проще в администрировании, чем CentOS.

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

Для Ubuntu обновление проводится в 2 команды:

root@box-10000:~# apt-get update
root@box-10000:~# apt-get upgrade

Их можно совместить в одну:

root@box-10000:~# apt-get update && apt-get upgrade

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

Создание плагинов

В папке plugins есть пример плагина в файле example.py, отвечающий на команду .
В нём подробно расписана структура плагина. Для примера работы plugin.data или plugin.temp_data
вы можете посмотреть memo.py, weather.py. Для примера цикличных задач friends.py.
Там есть и другие плагины, код которых можно просмотреть для понимания того, что можно сделать с помощью бота.

Каждый плагин должен иметь экземпляр класса Plugin (из plugin_system) под именем (обязательно) plugin.
Все команды, на которые подписывается плагин, должны быть в нижнем регистре.

Вот пример простого плагина:

# Импортируем класс Plugin
from plugin_system import Plugin
# Создаём объект класса, через него мы будем "подписываться" на команды
plugin = Plugin('Плагин для еды')

# Использование async и await обязательно, т.к. бот асинхронный
@plugin.on_command('еда')
async def test(msg, args):
    # Отвечаем пользователю
    await msg.answer('Где еда?!')

Вы можете использовать db, который является экземпляром peewee_async.Manager.
В database.py хранятся основные модели бд.
Каждый плагин может создавать свои модели после импорта database с помощью, например, такого объявления:

Помле этого можно рассматривать как обычную модель.

Плагины размещаются в папке . Если два плагина имеют одинаковые команды — они обрабатываются в обоих плагинах.
Плагины могут работать со всеми методами API ВКонтакте.

Telebot и сила python

Мне всегда казалось, что создавать бота — это не так просто. Честно говоря, давно хотел попробовать, но то ли не хватало времени (думал, что это займет не один вечер), то ли не мог выбрать технологию (как-то смотрел туториал для c#), ну а скорее всего было просто лень. Но тут мне понадобилось это для работы, так что я больше не смел откладывать.

Сила python заключается в его популярности. А, как следствие, в появлении огромного количества сторонних библиотек практически под все нужды. Именно это сделало возможным написание примитивного бота (который просто отвечает однотипно на сообщения) в 6 (ШЕСТЬ!) строчек кода. А именно:

Первое сообщение

На самом деле бот будет отвечать только на команду /start, но для начала неплохо. Здесь все довольно просто: в первой строчке импортируется библиотека telebot (для ее работы необходимо установить пакет pyTelegramBotAPI командой (НЕ !), далее создаем объекта бот, используя токен, который нам прислал BotFather. Третья строчка проверяет, что присылают пользователи (в данном случае это только команда “/start”), и, если проверка пройдена, то бот отправляет ответ с текстом “Hello!”. Последняя строчка, наверное, самая сложная для понимания, и в следующих разделах я ее подробно разберу. Сейчас же я только скажу о ее предназначении — она заставляет бота работать, то есть «реагировать» на полученные сообщения.

Подробнее о хендлерах

Давайте немножко упростим нашу функцию с приветствием:

Теперь мы передаём в конструктор ChatAction аргумент — это функция для фильтрации событий. Сюда мы перенесли условие. Теперь хендлер будет срабатывать только для нужных событий.

Также обратите внимание на функцию. Она отправляет сообщение в чат, из которого пришёл event

На самом деле это просто сокращение для функции , которую мы использовали выше.

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

Но мы пришли сюда не за этим. Мы хотим сделать команды и другие фичи для администраторов группы! Для этого нам нужно уметь отличать админов от простых участников группы. Этим мы займёмся в следующей части туториала. Мы подключим базу данных и научимся хитрым способом получать админов.

Продолжение следует.

Обучение и запуск бота

После того, как заполнены и валидированы тренировочные данные, настроена конфигурация (https://rasa.com/docs/rasa/model-configuration) можно приступать непосредственно к обучению чат-бота. Это делается с помощью простой команды:

После успешного обучения модель, как правило, сохраняется в папку “models”.

Шпаргалка с полным списком команд rasa:

Команда

Что делает

rasa init

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

rasa train

Обучает модель, используя nlu-файл и истории диалогов, сохраняет обученную модель в ./models.

rasa interactive

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

rasa shell

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

rasa run

Запускает сервер с обученной моделью.

rasa run actions

Запускает action сервер, используя Rasa SDK.

rasa visualize

Визуализирует истории диалогов.

rasa test

Тестирует обученную модель на тестовых данных, хранящихся в файлах, название которых начинается с “test_”.

rasa data split nlu

Делит NLU-данные на трейн и тест в отношении 80/20.

rasa data convert

Конвертирует обучающие данные.

rasa data validate

Проверяет domain, NLU и истории диалогов на несоответствия.

rasa export

Экспортирует диалоги из tracker store в event broker.

rasa x

Локально запускает Rasa X.

rasa -h

Показывает все возможные команды.

Поговорить с обученным ассистентом в командной строке можно запустив команду:

Команда rasa shell —debug позволит запустить чат-бот в режиме debug и посмотреть логи ошибок. Аргумент -m MODEL (путь до модели) или —model MODEL позволяет явно указать модель. По умолчанию rasa shell запускается, используя последнюю модель из папки “models”. Подробнее с аргументами и командами можно ознакомиться здесь.

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

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

Adblock
detector