Питоном по телеграму! Пишем пять простых Telegram-ботов на Python
matrixВ этой статье мы реализуем простой, но крайне полезный проект на Python — бота для Telegram. Боты — это небольшие скрипты, которые могут взаимодействовать с API, чтобы получать сообщения от пользователя и отправлять информацию в разные чаты и каналы.
Python для новичков
Если ты совсем не ориентируешься в Python, то отличным началом будет прочтение трех вводных статей, которые я публиковал в «Хакере» этим летом, либо посещение курса «Python для новичков», который я начну вести для читателей «Хакера» уже совсем скоро — 30 ноября.
- Python с абсолютного нуля. Учимся кодить без скучных книжек
- Python с абсолютного нуля. Учимся работать со строками, файлами и интернетом
- Python с абсолютного нуля. Работаем с ОС, изучаем регулярные выражения и функции
Чтобы создать бота, нам нужно дать ему название, адрес и получить токен — строку, которая будет однозначно идентифицировать нашего бота для серверов Telegram. Зайдем в Telegram под своим аккаунтом и откроем «отца всех ботов», BotFather.
Жмем кнопку «Запустить» (или отправим /start), в ответ BotFather пришлет нам список доступных команд:
/newbot— создать нового бота;/mybots— редактировать ваших ботов;/setname— сменить имя бота;/setdescription— изменить описание бота;/setabouttext— изменить информацию о боте;/setuserpic— изменить фото аватарки бота;/setcommands— изменить список команд бота;/deletebot— удалить бота.
Отправим бате‑боту команду /newbot, чтобы создать нового бота. В ответ он попросит ввести имя будущего бота, его можно писать на русском. После ввода имени нужно будет отправить адрес бота, причем он должен заканчиваться на слово bot. Например, xakepbotили xakep_bot. Если адрес будет уже кем‑то занят, BotFather начнет извиняться и просить придумать что‑нибудь другое.
Когда мы наконец найдем свободный и красивый адрес для нашего бота, в ответ получим сообщение, в котором после фразы Use this token to access the HTTP API будет написана строка из букв и цифр — это и есть необходимый нам токен. Сохраним ее где‑нибудь на своем компьютере, чтобы потом использовать в скрипте бота.
Для взаимодействия с Telegram API есть несколько готовых модулей. Самый простой из них — Telebot. Чтобы установить его, набери
pip install pytelegrambotapi
В Linux, возможно, понадобится написать pip3вместо pip, чтобы указать, что мы хотим работать с третьей версией Python.
ЭХО-БОТ
Для начала реализуем так называемого эхо‑бота. Он будет получать от пользователя текстовое сообщение и возвращать его.
import telebot
# Создаем экземпляр бота
bot = telebot.TeleBot('Здесь впиши токен, полученный от @botfather')
# Функция, обрабатывающая команду /start
@bot.message_handler(commands=["start"])
def start(m, res=False):
bot.send_message(m.chat.id, 'Я на связи. Напиши мне что-нибудь )')
# Получение сообщений от юзера
@bot.message_handler(content_types=["text"])
def handle_text(message):
bot.send_message(message.chat.id, 'Вы написали: ' + message.text)
# Запускаем бота
bot.polling(none_stop=True, interval=0)
Запускай скрипт и ищи в поиске Telegram своего бота по адресу, который ты придумал ранее. Запускаем бота кнопкой «Запустить» (Start) или командой /start и можем убедиться в том, что он работает и возвращает сообщения.

WIKIPEDIA-БОТ
Давай научим нашего бота не просто отсылать сообщения обратно, а чему‑нибудь поинтереснее. Например, по введенному слову давать статью на Википедии. Здесь нам поможет модуль Wikipedia:
pip install wikipedia
Готовим код.
import telebot, wikipedia, re
# Создаем экземпляр бота
bot = telebot.TeleBot('Здесь впиши токен, полученный от @botfather')
# Устанавливаем русский язык в Wikipedia
wikipedia.set_lang("ru")
# Чистим текст статьи в Wikipedia и ограничиваем его тысячей символов
def getwiki(s):
try:
ny = wikipedia.page(s)
# Получаем первую тысячу символов
wikitext=ny.content[:1000]
# Разделяем по точкам
wikimas=wikitext.split('.')
# Отбрасываем всЕ после последней точки
wikimas = wikimas[:-1]
# Создаем пустую переменную для текста
wikitext2 = ''
# Проходимся по строкам, где нет знаков «равно» (то есть все, кроме заголовков)
for x in wikimas:
if not('==' in x):
# Если в строке осталось больше трех символов, добавляем ее к нашей переменной и возвращаем утерянные при разделении строк точки на место
if(len((x.strip()))>3):
wikitext2=wikitext2+x+'.'
else:
break
# Теперь при помощи регулярных выражений убираем разметку
wikitext2=re.sub('\([^()]*\)', '', wikitext2)
wikitext2=re.sub('\([^()]*\)', '', wikitext2)
wikitext2=re.sub('\{[^\{\}]*\}', '', wikitext2)
# Возвращаем текстовую строку
return wikitext2
# Обрабатываем исключение, которое мог вернуть модуль wikipedia при запросе
except Exception as e:
return 'В энциклопедии нет информации об этом'
# Функция, обрабатывающая команду /start
@bot.message_handler(commands=["start"])
def start(m, res=False):
bot.send_message(m.chat.id, 'Отправьте мне любое слово, и я найду его значение на Wikipedia')
# Получение сообщений от юзера
@bot.message_handler(content_types=["text"])
def handle_text(message):
bot.send_message(message.chat.id, getwiki(message.text))
# Запускаем бота
bot.polling(none_stop=True, interval=0)

WWW
При создании следующих ботов мы будем использовать несколько текстовых файлов с контентом. Скачать их можно с моего сайта.
БОТ С ДВУМЯ ВИРТУАЛЬНЫМИ КНОПКАМИ
Во многих Telegram-ботах для выбора каких‑то действий используются так называемые виртуальные кнопки. Давай попробуем сделать себе такие же!
Предположим, что у нас есть два файла facts.txt и thinks.txt, которые содержат список интересных фактов и поговорки. На каждой строке файлов находится по одному факту или поговорке.
Сделаем бота, в котором будут две кнопки: «Факты» и «Поговорки». Если нажать любую, бот отправит пользователю соответствующее сообщение.
INFO
Если ты будешь использовать для этого бота тот же токен, что и для предыдущего, то, чтобы увидеть кнопки, перезапусти бота командой /start.
import telebot
import random
from telebot import types
# Загружаем список интересных фактов
f = open('data/facts.txt', 'r', encoding='UTF-8')
facts = f.read().split('\n')
f.close()
# Загружаем список поговорок
f = open('data/thinks.txt', 'r', encoding='UTF-8')
thinks = f.read().split('\n')
f.close()
# Создаем бота
bot = telebot.TeleBot('Здесь твой токен, полученный от @botfather')
# Команда start
@bot.message_handler(commands=["start"])
def start(m, res=False):
# Добавляем две кнопки
markup=types.ReplyKeyboardMarkup(resize_keyboard=True)
item1=types.KeyboardButton("Факт")
item2=types.KeyboardButton("Поговорка")
markup.add(item1)
markup.add(item2)
bot.send_message(m.chat.id, 'Нажми: \nФакт для получения интересного факта\nПоговорка — для получения мудрой цитаты ', reply_markup=markup)
# Получение сообщений от юзера
@bot.message_handler(content_types=["text"])
def handle_text(message):
# Если юзер прислал 1, выдаем ему случайный факт
if message.text.strip() == 'Факт' :
answer = random.choice(facts)
# Если юзер прислал 2, выдаем умную мысль
elif message.text.strip() == 'Поговорка':
answer = random.choice(thinks)
# Отсылаем юзеру сообщение в его чат
bot.send_message(message.chat.id, answer)
# Запускаем бота
bot.polling(none_stop=True, interval=0)

БОТ, ВЕДУЩИЙ TELEGRAM-КАНАЛ С АНЕКДОТАМИ
Предыдущие боты посылали юзеру сообщения тогда, когда получали от него команды или фразы. Но что, если нам нужен бот, который будет периодически и в автоматическом режиме постить что‑то в наш канал?
Давай сделаем бота, который получает список анекдотов из файла и каждый час постит в канал один из этих анекдотов. Для этого нам нужно создать свой канал в Telegram, добавить в подписчики канала нашего бота и назначить его администратором канала с правом публиковать сообщения.
Файл с анекдотами должен лежать в папке dataрядом со скриптом бота.
import telebot
import time
# Токен, который выдает @botfather
bot = telebot.TeleBot('Здесь твой токен, полученный от @botfather')
# Адрес телеграм-канала, начинается с @
CHANNEL_NAME = '@адрес_твоего_канала'
# Загружаем список шуток
f = open('data/fun.txt', 'r', encoding='UTF-8')
jokes = f.read().split('\n')
f.close()
# Пока не закончатся шутки, посылаем их в канал
for joke in jokes:
bot.send_message(CHANNEL_NAME, joke)
# Делаем паузу в один час
time.sleep(3600)
bot.send_message(CHANNEL_NAME, "Анекдоты закончились :-(")

ЧАТ-БОТ «МАША»
Теперь давай сделаем простейшего чат‑бота, который будет болтать с пользователем. Для этого мы подготовим файл boltun.txt, содержащий строки с вопросами (в начале таких строк поставим метку u:) и ответами на них в следующей строке.
u: как зовут
Маша меня зовут!
u: сколько тебе лет
Мне уже 18, честно-честно!
Файл boltun.txt поместим в папку data рядом со скриптом бота. Для поиска похожих вопросов используем модуль fuzzywuzzy, который позволяет сравнивать, насколько похожи между собой две строки. Естественно, сперва этот модуль нужно установить:
pip install fuzzywuzzy
pip install python-Levenshtein
Ниже приведен исходный код бота. После его запуска напиши боту «Привет» и попробуй с ним пообщаться. Естественно, это не искусственный интеллект и набор его ответов ограничен фразами из файла boltun.txt.
import telebot
import os
from fuzzywuzzy import fuzz
# Создаем бота, пишем свой токен
bot = telebot.TeleBot('Здесь твой токен, полученный от @botfather')
# Загружаем список фраз и ответов в массив
mas=[]
if os.path.exists('data/boltun.txt'):
f=open('data/boltun.txt', 'r', encoding='UTF-8')
for x in f:
if(len(x.strip()) > 2):
mas.append(x.strip().lower())
f.close()
# С помощью fuzzywuzzy вычисляем наиболее похожую фразу и выдаем в качестве ответа следующий элемент списка
def answer(text):
try:
text=text.lower().strip()
if os.path.exists('data/boltun.txt'):
a = 0
n = 0
nn = 0
for q in mas:
if('u: ' in q):
# С помощью fuzzywuzzy получаем, насколько похожи две строки
aa=(fuzz.token_sort_ratio(q.replace('u: ',''), text))
if(aa > a and aa!= a):
a = aa
nn = n
n = n + 1
s = mas[nn + 1]
return s
else:
return 'Ошибка'
except:
return 'Ошибка'
# Команда «Старт»
@bot.message_handler(commands=["start"])
def start(m, res=False):
bot.send_message(m.chat.id, 'Я на связи. Напиши мне Привет )')
# Получение сообщений от юзера
@bot.message_handler(content_types=["text"])
def handle_text(message):
# Запись логов
f=open('data/' + str(message.chat.id) + '_log.txt', 'a', encoding='UTF-8')
s=answer(message.text)
f.write('u: ' + message.text + '\n' + s +'\n')
f.close()
# Отправка ответа
bot.send_message(message.chat.id, s)
# Запускаем бота
bot.polling(none_stop=True, interval=0)

ВЫВОДЫ
Мы написали пять простых ботов, на примере которых научились принимать и отправлять сообщения, делать кнопки и понимать неточные запросы.
В следующей статье мы рассмотрим работу с Telegram-ботами более подробно: научимся делать ботов, работающих через веб‑хуки, принимать оплату от пользователей и взаимодействовать с базой данных SQLite.