В разделе рассмотрены примеры сниппетов, для работы с файлами, медиа и URL-адресами при создании Telegram бота с помощью пакета python-telegram-bot
.
Внимание! Пакеты
python-telegram-bot
версии 13.x будут придерживаться многопоточной парадигмы программирования (*на данный момент актуальна версия 13.15). Пакеты версий 20.x и новее предоставляют чистый асинхронный Python интерфейс для Telegram Bot API. Дополнительно смотрите основные изменения в пакетеpython-telegram-bot
версии 20.x.
Здесь рассматривается методы экземпляра bot = telegram.Bot()
. Если при создании бота используется пакет расширения telegram.ext
, то методы объекта bot
будут доступны через:
updater.bot
- это экземпляр telegram.Bot
, связанный с экземпляром Updater
, который присылает и отправляет все сообщения; context.bot
- это telegram.Bot
связанный с контекстом обработанного сообщения.Например:
from telegram.ext import Updater, CommandHandler TOKEN = 'Замените строку на Ваш token' updater = Updater(token=TOKEN) dispatcher = updater.dispatcher # экземпляр `telegram.Bot`, связанный с экземпляром `Updater` updater.bot.send_photo(...) # методы `telegram.Bot` доступны через `context` def call_back(update, context): ... # `telegram.Bot` связанный с контекстом # обработанного сообщения context.bot.send_photo(...) ... dispatcher.add_handler(CommandHandler("you_command", call_back))
Если нужно отправить файл, например, отправить фото, то для этого есть три метода:
file_id
уже отправленного файла.Обратите внимание, что не каждый метод поддерживается везде (например, для thumbnails
нельзя передать file_id
).
Загрузка файла в Telegram:
bot.send_document(chat_id=chat_id, document=open('tests/test.png', 'rb'))
Отправка HTTP-ссылки в Telegram:
bot.send_document(chat_id=chat_id, document='https://site.ru/static/test.gif'))
Отправка file_id
:
bot.send_document(chat_id=chat_id, document=file_id))
Два замечания по этому поводу:
Как получить fileid фотографии, которую вы отправили? Прочтите его из возвращаемого значения bot.senddocument (или любого другого объекта Message, который вы получите):
message = bot.send_document(...) file_id = message.document.file_id
Примечание. Метод
bot.send_document
используется для отправки файлов любого типа. В настоящее время боты могут отправлять файлы любого типа размером до 50 МБ, это ограничение может быть изменено в будущем. Аргументомdocument
может быть либоfile_id
, либо URL-адрес, либо файл с диска открытый какopen(file_name, 'rb')
. Отправка по URL в настоящее время работает только с файлами GIF, PDF и ZIP.
Это почти так же работает для всех других методов send_media_type
, таких как bot.send_photo()
, bot.send_video()
и т. д.
Далее рассматриваются другие распространенные примеры кода. Обратите внимание на то, что подход к публикации файлов почти одинаков, НО методы экземпляра bot
разные!
bot.send_photo(chat_id=chat_id, photo=open('tests/test.png', 'rb'))
bot.send_photo(chat_id=chat_id, photo='https://telegram.org/img/t_logo.png')
bot.send_voice(chat_id=chat_id, voice=open('tests/telegram.ogg', 'rb'))
bot.send_audio(chat_id=chat_id, audio=open('tests/test.mp3', 'rb'))
bot.send_document(chat_id=chat_id, document=open('tests/test.zip', 'rb'))
Используйте этот метод для отправки файлов анимации (видео в формате GIF или H.264/MPEG-4 AVC без звука). В настоящее время боты могут отправлять файлы анимации размером до 50 МБ, это ограничение может быть изменено в будущем.
bot.send_animation(chat_id=chat_id, document=open('tests/animation.gif', 'rb'))
Используйте этот метод для отправки группы фотографий или видео в виде альбома.
from telegram import InputMediaPhoto list_of_urls = [ 'https://example.org/commons/foto1.jpg', 'https://example.org/commons/foto2.jpg', 'https://example.org/commons/foto3.jpg' ] # список мультимедиа media_group = [] for number, url in enumerate(list_of_urls): media_group.append(InputMediaPhoto(media=url, caption="Фотография №" + number)) bot.send_media_group(chat_id=chat_id, media=media_group)
Примечание Элементы в списке мультимедиа
media_group
обязательно должны быть экземплярамиInputMediaAudio
,InputMediaDocument
,InputMediaPhoto
илиInputMediaVideo
.
Если файл отправлен, то можно его отредактировать. Это работает аналогично send_media_group
, т. е. медиаданные должны быть заключены в объект InputMedia<media_type>
. Опять же, с документом в качестве примера:
bot.edit_message_media(chat_id=chat_id, message_id=message_id, media=InputMediaDocument(media=open('tests/test.png'), ...))
Ознакомьтесь с ограничениями на редактирование мультимедиа в документах send_media_group
.
В этом примере изображение является объектом изображения модуля Pillow
, но оно работает одинаково со всеми типами мультимедиа.
from io import BytesIO bio = BytesIO() bio.name = 'image.jpeg' image.save(bio, 'JPEG') bio.seek(0) bot.send_photo(chat_id, photo=bio)
Где photos - это список объектов PhotoSize
, а desired_size
- кортеж, содержащий нужный размер.
def get_closest(photos, desired_size): def diff(p): return p.width - desired_size[0], p.height - desired_size[1] def norm(t): return abs(t[0] + t[1] * 1j) return min(photos, key=lambda p: norm(diff(p)))
Примечание. При загрузке фотографий имейте в виду, что
update.message.photo
- это массив фотографий разных размеров (упорядоченный от самого малого к большому).
Используйте update.message.photo[-1]
, чтобы получить самый большой размер.
file_id = message.voice.file_id newFile = bot.get_file(file_id) newFile.download('voice.ogg')
Для полученного video, voice и т.д нужно изменить message.document
на message.video
, message.voice и т.д. Однако есть одно исключение: message.photo
- это список объектов PhotoSize
, которые представляют разные размеры одной и той же фотографии. Чтобы получить наибольший размер, нужно используйте message.photo[-1].file_id
.
Кроме того, приведенный выше фрагмент можно сократить, используя встроенные ссылки:
newFile = message.effective_attachment.get_file() newFile.download('file_name')
message.efficient_attachment
автоматически содержит любое мультимедийное вложение, которое есть в сообщении - в случае фотографии снова придется использовать, например: message.efficient_attachment[-1].get_file()
.