Перейти к содержимому

Как отправить фото aiogram

  • автор:

Как отправить фотографию в бота телеграмм aiogram

Создайте объект InputFile , в котором хранится путь к файлу и воспользуйтесь методом send_photo() :

photo = InputFile("files/test.png") await bot.send_photo(chat_id=message.chat.id, photo=photo) 

Отслеживать
ответ дан 4 июл 2021 в 14:43
2,836 1 1 золотой знак 11 11 серебряных знаков 19 19 бронзовых знаков
а чем ваш ответ принципиально отличается от предыдущего ответа?
4 июл 2021 в 17:28
Мой ответ более соответствует фреймворку aiogram. Аргумент photo должен принимать объект InputFile.
4 июл 2021 в 17:53

Там происходит то что человек водит код который генерируется ,как сделать чтобы открывалось именно то фото которое до этого сгенерировалось с этим кодом

4 июл 2021 в 19:49

photo = InputFile(f’./data/tmp/emulator_.png') await bot.send_photo(chat_id=message.chat.id, photo=photo) Таким способом можно будет вывести

4 июл 2021 в 19:49
InputFile(f’data/tmp/emulator_.png')
4 июл 2021 в 19:59

photo = open('Путь к фото', 'rb') await bot.send_photo(chat_id, photo) 

Отслеживать
ответ дан 4 июл 2021 в 14:01
665 1 1 золотой знак 3 3 серебряных знака 18 18 бронзовых знаков
Не понял, работает же
4 июл 2021 в 14:40
Про with open . главное не забывать
10 июн 2022 в 21:02

with open('Путь к фото', 'rb') as photo: await bot.send_photo(chat_id=message.chat.id, photo) 

Отслеживать
68k 218 218 золотых знаков 79 79 серебряных знаков 221 221 бронзовый знак
ответ дан 30 янв 2023 в 12:04
Длиато Райкаут Длиато Райкаут

Нужно импортировать InputFile

from aiogram.types import InputFile 

Затем создать переменную, через которую указываем путь к фото и указываем нашу переменную photo при отправке через bot.send_photo()

photo = InputFile("files/any_picture.png") await bot.send_photo(chat_id=message.chat.id, photo) 

Урок 2. Медиа, разметка, эмоджи и щепотка логирования

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

Если вы собираетесь работать с отправкой эмоджи, и делать это не по их коду, например ‘\U0001F31A’ , а пользоваться наглядными названиями как :new_moon_with_face: , то необходимо установить библиотеку emoji , для этого воспользуемся командой pip install emoji (или командой python3.6 -m pip install emoji , если у вас установлено несколько интерпретаторов питона).

Зачем хранить айди файлов, которые мы отправляем?

Например, мы хотим добавить в нашего бота возможность отправлять картинки. Скорее всего, эти картинки будут отправлены неоднократно. Поэтому Телеграм даёт нам возможность отправлять файлы по айди. Вероятно, вы уже замечали, как это работает. Например, вы отправляете фото другу, оно отправляется пару секунд, а потом решаете отправить это же фото подруге, выбираете, жмете отправить, а оно тут же отправляется — это происходит потому, что ваш телеграм клиент запомнил, что вы уже отправляли это фото, поэтому в следующий раз шлёт его по айди. Боты могут то же самое (и даже лучше). Отправляя файл по айди мы в первую очередь ускоряем отправку сообщения пользователю, так как медиа уже загружено на сервер телеграм.

Итак, допустим, наш бот будет отправлять различные типы медиа. В этом уроке мы рассмотрим отправку изображений по одному, медиагруппами, отправку аудиосообщений, файлов, видео и видео в кружочке. Предполагая, что все файлы, отсылаемые нашим ботом, будут когда-либо отправлены пользователю, сделаем выгрузку данных заранее. Для того, чтобы не вносить данные в базу данных вручную, автоматизируем этот процесс. В данном случае нам подойдет база данных на движке SQLite. Для новичков скажу, что этот тип баз данных по умолчанию поддерживается языком Python (проверить это можно сделав в интерпретаторе import sqlite3 ). В своих проектах вы можете пользоваться любимыми ORM или писать чистые SQL запросы (вам всего доброго, хорошего настроения и здоровья). Мой выбор пал на SQLAlchemy. Так как работа с данной библиотекой — не тема наших уроков, я не буду углубляться в подробности и поверхностно расскажу, что происходит коде, относящемся к работе с базой данных (далее — БД). Напоминаю, что весь исходный код, продемонстрированный в уроке, доступен по ссылке. Отмечу, что база данных намерено представлена в максимально простом виде — в целях наглядности.

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

Наконец-то код!

Для начала создаем модель таблицы для нашей базы данных. Файл db_map.py:

from sqlalchemy import Column, Integer, String from sqlalchemy.ext.declarative import declarative_base Base = declarative_base() class MediaIds(Base): __tablename__ = 'Media ids' primary_key=True) file_id = Column(String(255)) filename = Column(String(255)) 

Теперь загружаем в Телеграм файлы и сохраняем возвращаемые айди в базу данных. Для этого я написал небольшой скрипт, который доступен по ссылке. Если будете исполнять его на своём компьютере, можете обратить внимание на то самое логирование библиотеки aiogram.

Вот результат выполнения скрипта:

Представим, что в базе данных было ещё несколько полей, по которым вы в коде будете получать необходимые данные. Теперь переходим к основному коду бота. Так как создание логики запросов к БД — не тема этих уроков, допустим, что вы получили данные при старте программы и записали их в переменные (строки кода 17 — 26).

Создаем хэндлер команд /start и /help :

@dp.message_handler(commands=['start']) async def process_start_command(message: types.Message): await message.reply('Привет!\nИспользуй /help, ' 'чтобы узнать список доступных команд!') @dp.message_handler(commands=['help']) async def process_help_command(message: types.Message): msg = text(bold('Я могу ответить на следующие команды:'), '/voice', '/photo', '/group', '/note', '/file, /testpre', sep='\n') await message.reply(msg, parse_mode=ParseMode.MARKDOWN) 

Обращу внимание читателя на то, что в ответе на команду /help мы воспользовались новыми методами: text и bold . Эти на первый взгляд простые функции сильно упрощают работу с генерацией текста. Первая склеивает в одно целое все передаваемые ей строчки, перемежая сепаратором (по умолчанию пробел, в таких случаях переменную sep вообще не нужно указывать), а вторая обрамляет входящую строчку метками для жирного текста (в данном примере используется разметка Markdown, поэтому это символы * . Для HTML теги будут другие). По аналогии работают методы italic , code и pre для Markdown и аналогичные для HTML. А чтобы Телеграм понял, что эти символы здесь не просто так, но обозначают разметку, мы явно указываем тип этой самой разметки: parse_mode=ParseMode.MARKDOWN . Напомню, что все необходимые импорты можно посмотреть по ссылке.

Затем добавляем обработчики всех остальных команд
О каждой по отдельности (за одно разберем эмоджи):

Отправка аудио + ответ на определенное сообщение:

@dp.message_handler(commands=['voice']) async def process_voice_command(message: types.Message): await bot.send_voice(message.from_user.id, VOICE, reply_to_message_id=message.message_id) 

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

Отправка фото с комментарием + эмоджи:

@dp.message_handler(commands=['photo']) async def process_photo_command(message: types.Message): caption = 'Какие глазки! :eyes:' await bot.send_photo(message.from_user.id, CAT_BIG_EYES, caption=emojize(caption), reply_to_message_id=message.message_id) 

Тут мы дополнительно передаем данные в параметр caption , предварительно преобразовав текст, чтобы получить эмоджи из его кода. Теперь от простого переходим к более сложному.

Отправка медиагруппы (где смешались кони, люди фото и видео):

@dp.message_handler(commands=['group']) async def process_group_command(message: types.Message): media = [InputMediaVideo(VIDEO, 'ёжик и котятки')] for photo_id in KITTENS: media.append(InputMediaPhoto(photo_id)) await bot.send_media_group(message.from_user.id, media) 

Внимание! На момент публикации заметки при использовании релизной версии библиотеки невозможно отправить медиагруппу представленным выше способом из-за ошибки в коде. Недочёт исправлен в этом коммите. Версия 1.1, которая устанавливается через pip, уже несет в себе это исправление.

Итак, что же произошло в коде? Для начала создаем массив и кладем в него один элемент типа InputMediaVideo . Первый входной параметр — само видео (в данном случае айди), а второй элемент — caption (его передавать не обязательно). Дальше в цикле заполняем массив элементами типа InputMediaPhoto . Их создаем без подписи, тем самым делаем так, что всей медиагруппе принадлежит комментарий, оставленный к первому медиа. Затем просто в нужный метод передаем массив элементов. Можно, конечно, ещё было передать сразу медиагруппу, сделав MediaGroup(media) , но так как библиотека делает это сама, то какой смысл писать лишний код и делать лишний импорт?

Отправка видеозаметки (видео в кружочке):

@dp.message_handler(commands=['note']) async def process_note_command(message: types.Message): user_id = message.from_user.id await bot.send_chat_action(user_id, ChatActions.RECORD_VIDEO_NOTE) await asyncio.sleep(1) # конвертируем видео и отправляем его пользователю await bot.send_video_note(message.from_user.id, VIDEO_NOTE) 

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

Отправка файла:

@dp.message_handler(commands=['file']) async def process_file_command(message: types.Message): user_id = message.from_user.id await bot.send_chat_action(user_id, ChatActions.UPLOAD_DOCUMENT) await asyncio.sleep(1) # скачиваем файл и отправляем его пользователю await bot.send_document(user_id, TEXT_FILE, caption='Этот файл специально для тебя!') 

Тут как и в предыдущем примере предполагаем, что файл нужно ещё откуда-то достать или, может, сгенерировать, поэтому снова отправляем chatAction , выжидаем драматичную паузу и отправляем сам файл.

Преформатированный текст:

@dp.message_handler(commands=['testpre']) async def process_testpre_command(message: types.Message): message_text = pre(emojize('''@dp.message_handler(commands=['testpre']) async def process_testpre_command(message: types.Message): message_text = pre(emojize('Ха! Не в этот раз :smirk:')) await bot.send_message(message.from_user.id, message_text)''')) await bot.send_message(message.from_user.id, message_text, parse_mode=ParseMode.MARKDOWN) 

Так как разметка тут немного шалит, приложу ещё и скриншот кода с более понятной подсветкой синтаксиса: Тут мы отправляем преформатированный текст. Обычно такая разметка необходима при отправке блоков кода. По сути, это тот же моноширинный шрифт как и при использовании code (рассмотрим его ниже), однако pre работает для многострочных вставок и автоматически отделяется переносом строки до и после. В качестве примера отправим данную же функцию с её хэндлером. Получаем такой результат:

Ну и напоследок немного улучшим знания, полученные в предыдущем уроке и закрепим их на деле:

Оставим для нерадивого пользователя пару хэндлеров для нежданных сообщений:

@dp.message_handler() async def echo_message(msg: types.Message): await bot.send_message(msg.from_user.id, msg.text) @dp.message_handler(content_types=ContentType.ANY) async def unknown_message(msg: types.Message): message_text = text(emojize('Я не знаю, что с этим делать :astonished:'), italic('\nЯ просто напомню,'), 'что есть', code('команда'), '/help') await msg.reply(message_text, parse_mode=ParseMode.MARKDOWN) 

И если первый должен быть понятен ещё с первого урока, то о втором расскажу поподробнее:
Так как по умолчанию в пустой хэндлер прилетают только текстовые сообщения, то наш бот будет игнорировать все остальные типы сообщений. Специально для этого мы создаем «уловитель» этих самых «всех остальных типов» сообщений, передавая content_types=ContentType.ANY . Обращу внимание читателя на то, что данная библиотека работает так, что сообщение передается в первый подходящий по условиям message_handler , поэтому необходимо соблюдать логический порядок. И именно по этой причине нельзя ставить хэндлер команд выше хэндлера текстовых сообщений — из-за того, что команды — это тоже текстовые сообщения, в вашей программе будет нарушена логика.

Домашнее задание

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

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

sendPhoto#

Returns: Message class aiogram.methods.send_photo. SendPhoto ( * , chat_id : int | str , photo : InputFile | str , message_thread_id : int | None = None , caption : str | None = None , parse_mode : str | None = sentinel.UNSET_PARSE_MODE , caption_entities : List [ MessageEntity ] | None = None , has_spoiler : bool | None = None , disable_notification : bool | None = None , protect_content : bool | None = sentinel.UNSET_PROTECT_CONTENT , reply_parameters : ReplyParameters | None = None , reply_markup : InlineKeyboardMarkup | ReplyKeyboardMarkup | ReplyKeyboardRemove | ForceReply | None = None , allow_sending_without_reply : bool | None = None , reply_to_message_id : int | None = None , ** extra_data : Any ) [source] # Use this method to send photos. On success, the sent aiogram.types.message.Message is returned. Source: https://core.telegram.org/bots/api#sendphoto chat_id : int | str # Unique identifier for the target chat or username of the target channel (in the format @channelusername ) photo : InputFile | str # Photo to send. Pass a file_id as String to send a photo that exists on the Telegram servers (recommended), pass an HTTP URL as a String for Telegram to get a photo from the Internet, or upload a new photo using multipart/form-data. The photo must be at most 10 MB in size. The photo’s width and height must not exceed 10000 in total. Width and height ratio must be at most 20. More information on Sending Files » message_thread_id : int | None # Unique identifier for the target message thread (topic) of the forum; for forum supergroups only caption : str | None # Photo caption (may also be used when resending photos by file_id), 0-1024 characters after entities parsing parse_mode : str | None # Mode for parsing entities in the photo caption. See formatting options for more details. caption_entities : List [ MessageEntity ] | None # A JSON-serialized list of special entities that appear in the caption, which can be specified instead of parse_mode has_spoiler : bool | None # Pass True if the photo needs to be covered with a spoiler animation disable_notification : bool | None # Sends the message silently. Users will receive a notification with no sound. protect_content : bool | None # Protects the contents of the sent message from forwarding and saving reply_parameters : ReplyParameters | None # Description of the message to reply to reply_markup : InlineKeyboardMarkup | ReplyKeyboardMarkup | ReplyKeyboardRemove | ForceReply | None # Additional interface options. A JSON-serialized object for an inline keyboard, custom reply keyboard, instructions to remove reply keyboard or to force a reply from the user. allow_sending_without_reply : bool | None # Pass True if the message should be sent even if the specified replied-to message is not found

Deprecated since version API:7.0: https://core.telegram.org/bots/api-changelog#december-29-2023

reply_to_message_id : int | None # If the message is a reply, ID of the original message

Deprecated since version API:7.0: https://core.telegram.org/bots/api-changelog#december-29-2023

Usage#

As bot method#

result: Message = await bot.send_photo(. ) 

Method as object#

  • from aiogram.methods.send_photo import SendPhoto
  • alias: from aiogram.methods import SendPhoto
With specific bot#
result: Message = await bot(SendPhoto(. )) 
As reply into Webhook in handler#
return SendPhoto(. ) 

As shortcut from received object#

  • aiogram.types.message.Message.answer_photo()
  • aiogram.types.message.Message.reply_photo()
  • aiogram.types.chat_join_request.ChatJoinRequest.answer_photo()
  • aiogram.types.chat_join_request.ChatJoinRequest.answer_photo_pm()
  • aiogram.types.chat_member_updated.ChatMemberUpdated.answer_photo()

Как отправить фото aiogram

Скачай курс
в приложении

Перейти в приложение
Открыть мобильную версию сайта

© 2013 — 2023. Stepik

Наши условия использования и конфиденциальности

Get it on Google Play

Public user contributions licensed under cc-wiki license with attribution required

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

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