Решил немного погрузиться в изучение Python, в процессе поставил задачу отойти от стандартного Hello World и попытаться написать сразу простого бота для Telegram. В итоге, бот может отвечать на заданные фразы, присылать внешний ip адрес и делать снимок с камеры. Скажу сразу, код не идеальный, но в процессе отладки ни один котик не пострадал.
Для начала сразу оговорюсь писать будем на Python версии 3 и будем использовать модули для облегчения жизни нашего проекта.
python3 — V
Python 3.7.5
Пишем мы на Ubunru 19.10, поэтому надо учитывать, что есть две версии установленного Python.
Установим PIP и необходимые пакеты:
apt install python3 — pip
pip3 install pytelegrambotapi
pip3 install PySocks
PIP – система управления пакетами, которая используется для установки и управления программными пакетами.
pytelegrambotapi – нужен для работы с API Telegram
PySocks – прокси сервер, иначе бот не будет работать.
Как было указано выше, пишем мы на Ubuntu, поэтому в директории пользователя /home/users-name/ создаем файлы bot-file.py и config.py
Телеграм бот для твоей шараги. Часть 1 (Фундамент проекта)
touch bot — file . py
touch config . py
Файл bot-file содержит код бота, а файл config необходим для конфигурации бота. В конфигурации необходимо будет указать список пользователей, которым разрешено взаимодействие с ботом.
Начнем с файла конфигурации, там все просто, необходимо просто указать id пользователя Telegram.
users = [ ‘id-user1’ , ‘id-user2’ ]
Переходим к файлу бота.
import config
import telebot
from telebot import apihelper
from telebot import types
import datetime
import logging
logger = logging . getLogger ( ‘log’ )
logger . setLevel ( logging . INFO )
fh = logging . FileHandler ( ‘someTestBot.log’ )
fh . setLevel ( logging . DEBUG )
formatter = logging . Formatter ( «%(asctime)s | %(levelname)-7s | %(message)s» )
fh . setFormatter ( formatter )
logger . addHandler ( fh )
### Прокси сервер
### Token telegram bot
bot = telebot . TeleBot ( ‘Token-bot’ , threaded = True )
### Функция проверки авторизации
def autor ( chatid ) :
strid = str ( chatid )
for item in config . users :
if item == strid :
return True
return False
### Клавиатура
keyboard1 = telebot . types . ReplyKeyboardMarkup ( )
keyboard1 . row ( ‘Привет’ , ‘Пока’ , ‘/ip’ , ‘/camera’ )
### Прием документов
def handle_docs_photo ( message ) :
chat_id = message . chat . id
downloaded_file = bot . download_file ( file_info . file_path )
with open ( src , ‘wb’ ) as new_file :
new_file . write ( downloaded_file )
bot . reply_to ( message , «Пожалуй, я сохраню это» )
except Exception as e :
bot . reply_to ( message , e )
### Прием фото
def handle_docs_photo ( message ) :
chat_id = message . chat . id
file_info = bot . get_file ( message . photo [ len ( message . photo ) — 1 ] . file_id )
downloaded_file = bot . download_file ( file_info . file_path )
src = ‘/home/users-name/received/’ + file_info . file_path ;
with open ( src , ‘wb’ ) as new_file :
new_file . write ( downloaded_file )
bot . reply_to ( message , «Фото добавлено» )
except Exception as e :
bot . reply_to ( message , e )
def start_message ( message ) :
if autor ( message . chat . id ) :
cid = message . chat . id
message_text = message . text
user_id = message . from_user . id
user_name = message . from_user . first_name
bot . send_message ( message . chat . id , ‘Привет, ‘ + user_name + ‘ Что ты хочешь от меня, собака сутулая!’ , reply_markup = keyboard1 )
bot . send_sticker ( message . chat . id , ‘CAADAgAD6CQAAp7OCwABx40TskPHi3MWBA’ )
bot . send_message ( message . chat . id , ‘Тебе сюда нельзя. Твой ID: ‘ + str ( message . chat . id ) )
bot . send_sticker ( message . chat . id , ‘CAADAgADcQMAAkmH9Av0tmQ7QhjxLRYE’ )
def camera_message ( message ) :
if autor ( message . chat . id ) :
bot . send_message ( message . chat . id , ‘Фото с камеры’ )
os . system ( ‘wget %s -O /tmp/photo.jpg’ % link )
imageFile = ‘/tmp/photo.jpg’
img = open ( imageFile , ‘rb’ )
bot . send_photo ( message . chat . id , img , caption = ‘Фото с камеры’ , reply_markup = keyboard1 )
bot . send_message ( message . chat . id , ‘Тебе сюда нельзя. Твой ID: ‘ + str ( message . chat . id ) )
bot . send_sticker ( message . chat . id , ‘CAADAgADcQMAAkmH9Av0tmQ7QhjxLRYE’ )
def prim_message ( message ) :
if autor ( message . chat . id ) :
link = ‘https://flammlin.com/pi’
os . system ( ‘wget %s -O /tmp/ip.txt’ % link )
docum = open ( ‘/tmp/ip.txt’ , ‘rb’ )
bot . send_message ( message . chat . id , docum , reply_markup = keyboard1 )
bot . send_sticker ( message . chat . id , ‘CAADAgADcQMAAkmH9Av0tmQ7QhjxLRYE’ )
bot . send_message ( message . chat . id , ‘Тебе сюда нельзя. Твой ID: ‘ + str ( message . chat . id ) )
bot . send_sticker ( message . chat . id , ‘CAADAgADcQMAAkmH9Av0tmQ7QhjxLRYE’ )
bot . polling ( )
Разберем некоторые интересные моменты, на которые следует обратить внимание.
Прокси
В данном примере используется Socks 5 прокси:
### Прокси сервер
Достаточно указать свои данные и запустить бот.
Token ID
В начале пытался брать Token из файла конфигурации, но бот так и не запустился. Пришлось оставить в коде, поэтому Token бота вписывать придется в сам код.
### Token telegram bot
bot = telebot . TeleBot ( ‘Token-bot’ , threaded = True )
Авторизация
### Функция проверки авторизации
def autor ( chatid ) :
strid = str ( chatid )
for item in config . users :
if item == strid :
return True
return False
Для проверки пользователя используется функция проверки id пользователя из файла конфигурации. В случае успеха бот присылает сообщение и стикер, тоже самое в случае отказа.
Клавиатура
Красивые кнопочки любят все.
### Клавиатура
keyboard1 = telebot . types . ReplyKeyboardMarkup ( )
keyboard1 . row ( ‘Привет’ , ‘Пока’ , ‘/ip’ , ‘/camera’ )
Второй горизонтальный ряд добавляется легко, просто пишем снова – keyboard1.row.
Прием документов и фотографий
Бот умеет сохранять документы и фотографии, которые скачиваются в папку received. Папку предварительно необходимо будет создать в профиле пользователя, где создавали файлы бота и файла конфигурации.
Wget
С вопросом получения картинки с камеры и внешнего ip адреса пришлось повозить подольше. Но в итоге через папку temp и вызов через bash wget все получилось.
Планировщик crontab
Бот запускается через планировщик задач, каждые пять минут происходит проверка запущенного процесса. Так как бот использует прокси и может произойти обрыв канала интернет, то повторный запуск бота не сможет произойти.
Для начала необходимо точно определить где и какая версия Python установлена.
Источник: flammlin.com
На чём писать чатботов?
Фрймворков для написания чатботов очень много. Из популярных – есть aiogram , telethon , python-telegram-bot . Есть и no code решения по созданию чатботов.
Здесь мы разберём какие библиотеки/решения существуют, их плюсы и минусы и границы применимости.
aiogram
Самый популярный вариант, который фигурирует в каждом первом видео на ютубе. Самое распространённое заблуждение насчёт него – что “асинхронность ускорит вашего чатбота”.
На самом деле не совсем. Она сделает это, но для этого недостаточно просто писать async и await в начале объявления/вызова функций. Для асинхронной работы бота все операции внутри него не должны быть блокирующими (или хотя бы какая-то ощутимая их часть). Это значит, что больше нельзя пользоваться бибилотекой requests , ведь она синхронная, а вам нужен её асинхронный аналог, например, httpx или asks . Нельзя пользоватья redis , нужен aioredis . И так далее.
Библиотека хороша для написания асинхронного кода, но если вы не умеете его писать, то трогать не стоит, получите кучу проблем асинхронного кода, не получив его преимуществ.
python-telegram-bot
Библиотека поддерживает сразу 2 версии: синхронную и асинхронную. Синхронная – это версии 13.X, вот их документация. Асинхронная – в том же репозитории, просто для неё нужно установить версию библиотеки 20.X и старше, документация.
За счёт этого библиотека дружелюбнее для начинающих, пусть это и создаёт некоторую путаницу для новичков, но если вы разобрались один раз “где синхронная, а где нет” – дальше в целом всё понятно. Зато асинхронщину можно совсем не трогать, пока вы к ней не готовы.
Библиотека обладает куда более подробной документацей в сравнении с aiogram, есть статьи о архитектуре, персистентности или обходе спам-лимита Telegram. Функционал, кажется, тоже богаче.
Из минусов – библиотека не обладает таким же активным коммьюнити, как aiogram , в репозитории которого есть ссылки на сообщества по странам.
Python — самообучающийся чат-бот для Телеграмм
На досуге было нечего делать, решил посмотреть на Python, раньше никогда на нем не программировал и его синтаксис кардинально отличается от моего родного языка PHP, но за вечер мне удалось состряпать не сложного чат-бота. Да, не обошлось без глюков и ошибок. Пришлось гуглить как подружить Python с MySQL. Но я справился, на второй день — я научил чат бота учиться и поселил в Телеграме под ником yurecnt_bot