Как получить file id telegram

от admin

Получение ботом медиа-файлов и сохранение их на своем сервере

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

У Telegram Bot Api для этого есть специальный метод getFile. На входе он получает file_id , на выходе объект File.

Параметров file_id у картинки может быть больше одного, потому как телеграм присылает несколько вариантов размеров картинки, последний всегда оригинал. При загрузке картинки в бот приходит информация в виде объекта Photo, в котором лежит массив объектов PhotoSize.

Наш бот будет принимать только команду /start и картинку, на остальные запросы он будет "ругаться". Чтобы определить, что нам пришло в нашем уже знакомом по предыдущим статьям методе init() будем проверять ключи массива пришедших данных. Для реализации задуманного нам нужен только объект Message.

Картинки мы будем сохранять в директории img , располагается она рядом с файлом index.php в котором наш код.

В случае если прислали картинку, то мы передаем массив объектов PhotoSize в метод getPhoto() , он вернет результат в boolean. Внутри метода происходит 2 действия:

  1. через метод getPhotoPath() получаем расположение файла на сервере Telegram
  2. через метод copyPhoto() копируем картинку к себе на сервер

Картинка располагается на сервере Telegram по стандартному пути:

Выводит картинку по этому пути где-либо в сети не рекомендую, так как будет доступен ваш токен от бота.

Сохранять себе на сервер мы будем оригинал, поэтому нам надо узнать количество элементов в массиве, использовать будем функцию count().

Чтобы получить расширение файла, будем разбивать file_path в массив по знаку . функцией explode() и брать последний элемент используя функцию end(). Для копирования файлов пользуемся функцией copy().

Подводим итог

Сохранить картинку через Телеграм бот очень просто. Методы Bot API позволяют это сделать быстро. Для сохранения других типов файлов с Телеграм алгоритм аналогичный. Скачать исходный код можно по этой ссылке.

Комментарии

Авторизуйтесь через Telegram, чтобы оставить комментарий.
Откройте бот @SiteAuthBot, нажмите кнопку Старт/Start. Следуйте инструкциям бота.

Внимание!
Убедитесь, что эта страница открыта в браузере, а не в приложении Telegram. В противном случае авторизация пройдет только в приложении Telegram.

Привет, Хороший Человек!
Отличный сайт.

А как можно сохранять себе не оригинал, а сжатую телеграмом картинку, или задать размеры сохраняемой картинки?
А еще как сделать так, чтобы имя картинки было равно ID пользователя, который ее грузит.
Большой Спасиб!

Здравствуйте!
Я запустил этот код, изменил только токен бота, ид-р админа, внес брекпоинты для отладки.
Почему в данном коде есть ошибка при отправке боту простого изображения с форматом png?
А именно ошибка при получении пути файла по его ид-ру файла.

Вот код метода инит.

/** Обрабатываем сообщение
* @param $data
*/
public function init($data)
<

// создаем массив из пришедших данных от API Telegram
$arrData = $this->getData($data);

// Определяем id пользователя
$chat_id = $arrData[‘message’][‘chat’][‘id’];

// проверяем кто написал: пользователь или админ
$is_admin = $this->isAdmin($chat_id);

$this->requestToTelegram(array("text" => "Hello, people!"), $chat_id, "sendMessage");
$this->requestToTelegram(array("text" => json_encode($arrData)), $chat_id, "sendMessage");

$help_text = "Это текст справки";
// Отправляем сообщение
$this->requestToTelegram(array("text" => $help_text), $chat_id, "sendMessage");
>

// если это Старт
if($this->isStartBot($arrData)) <

$this->requestToTelegram(array("text" => "Старт бота!"), $chat_id, "sendMessage");

// Определяем кто написал
$chat_id = $is_admin ? $this->adminId : $chat_id;

// Выводим приветственное слово
$hello = $is_admin ? $this->helloAdmin : $this->setTextHello($this->helloUser, $arrData);

// Отправляем сообщение
$this->requestToTelegram(array("text" => $hello), $chat_id, "sendMessage");

$this->requestToTelegram(array("text" => "Пришло сообщение"), $chat_id, "sendMessage");

// отвечаем что пришло фото
$this->requestToTelegram(array("text" => $typeMsg), $chat_id, "sendMessage");

$this->requestToTelegram(array("text" => "Запуск загрузки фото"), $chat_id, "sendMessage");

$text = $this->getPhoto($data[‘message’][‘photo’], $chat_id)
? "Спасибо! Можете еще загрузить мне понравилось их сохранять."
: "Что-то пошло не так, попробуйте еще раз";

// отправляем сообщение о результате
// $this->sendMessage($chat_id, $text);
$this->requestToTelegram(array("text" => $text), $chat_id, "sendMessage");
>

// Если это не старт
if($is_admin) <
if($this->isReply($arrData)) <

// если ответ самому себе
if($this->isAdmin($arrData[‘message’][‘reply_to_message’][‘from’][‘id’])) <
$this->requestToTelegram(array("text" => "Вы ответили сами себе."), $this->adminId, "sendMessage");
> elseif($this->isBot($arrData)) <

// если ответ боту
$this->requestToTelegram(array("text" => "Вы ответили Боту."), $this->adminId, "sendMessage");
> else <

// все нормально отправляем на обработку
$this->getTypeCommand($arrData);
>
> else <

// нажать кнопку ответить
$this->requestToTelegram(array("text" => $this->answerAdmin), $this->adminId, "sendMessage");
>
> else <

// Если это написал пользователь то перенаправляем админу
$dataSend = array(
‘from_chat_id’ => $chat_id,
‘message_id’ => $arrData[‘message’][‘message_id’],
);
$this->requestToTelegram($dataSend, $this->adminId, "forwardMessage");
>
>
>

// общая функция загрузки картинки
private function getPhoto($data, $chat_id)
<
$this->requestToTelegram(array("text" => "function getPhoto старт"), $chat_id, "sendMessage");
// берем последнюю картинку в массиве
$file_id = $data[count($data) — 1][‘file_id’];

Читать:
Где архив в телеграмме

// получаем file_path
$file_path = $this->getPhotoPath($file_id, $chat_id);
$this->requestToTelegram(array("text" => "получили file_path"), $chat_id, "sendMessage");

// возвращаем результат загрузки фото
return $this->copyPhoto($file_path);
>

// функция получения метонахождения файла
private function getPhotoPath($file_id, $chat_id)
<

// получаем объект File
$array = json_decode($this->requestToTelegram2([‘file_id’ => $file_id], "getFile"), TRUE);

$this->requestToTelegram(array("text" => "function getPhotoPath старт"), $chat_id, "sendMessage");

$this->requestToTelegram(array("text" => json_encode($array)), $chat_id, "sendMessage");

// возвращаем file_path
return $array[‘result’][‘file_path’];
>

// копируем фото к себе
private function copyPhoto($file_path, $chat_id)
<

$this->requestToTelegram(array("text" => "function copyPhoto старт"), $chat_id, "sendMessage");

// ссылка на файл в телеграме
$file_from_tgrm = "https://api.telegram.org/file/bot".$this->botToken."/".$file_path;
// достаем расширение файла
$ext = end(explode(".", $file_path));
// назначаем свое имя здесь время_в_секундах.расширение_файла
$name_our_new_file = time().".".$ext;
return copy($file_from_tgrm, "img/".$name_our_new_file);
>

/** Определяем тип сообщения и передаем для отправки
* @param $data
*/
private function getTypeMsg($data)
<
// определяем id пользователя для уведомления
$chat_id = $data[‘message’][‘reply_to_message’][‘forward_from’][‘id’];
// если текст
if (array_key_exists(‘text’, $data[‘message’])) <

// готовим данные
$dataSend = array(
‘text’ => $data[‘message’][‘text’],
);

// отправляем — передаем нужный метод
$this->requestToTelegram($dataSend, $chat_id, "sendMessage");

> elseif (array_key_exists(‘sticker’, $data[‘message’])) <

return("sticker");
$dataSend = array(
‘sticker’ => $data[‘message’][‘sticker’][‘file_id’],
);
$this->requestToTelegram($dataSend, $chat_id, "sendSticker");

> elseif (array_key_exists(‘document’, $data[‘message’])) <

return("document");
$dataSend = array(
‘document’ => $data[‘message’][‘document’][‘file_id’],
‘caption’ => $data[‘message’][‘caption’],
);
$this->requestToTelegram($dataSend, $chat_id, "sendDocument");

> elseif (array_key_exists(‘photo’, $data[‘message’])) <

return("photo");
// картинки Телеграм ресайзит и предлагает разные размеры, мы берем самый последний вариант
// так как он самый большой — то есть оригинал
$img_num = count($data[‘message’][‘photo’]) — 1;
$dataSend = array(
‘photo’ => $data[‘message’][‘photo’][$img_num][‘file_id’],
‘caption’ => $data[‘message’][‘caption’],
);
$this->requestToTelegram($dataSend, $chat_id, "sendPhoto");

> elseif (array_key_exists(‘video’, $data[‘message’])) <

return("video");
$dataSend = array(
‘video’ => $data[‘message’][‘video’][‘file_id’],
‘caption’ => $data[‘message’][‘caption’],
);
$this->requestToTelegram($dataSend, $chat_id, "sendVideo");

> else <
return("Тип передаваемого сообщения не поддерживается");
$this->requestToTelegram(array("text" => "Тип передаваемого сообщения не поддерживается"), $chat_id, "sendMessage");
>
>

/** Проверяем не отвечаем ли мы боту
* @param $data
* @return bool
*/
private function isBot($data) <
return ($data[‘message’][‘reply_to_message’][‘from’][‘is_bot’] == 1

getFile

Use this method to get basic info about a file and prepare it for downloading.

Use this method to get basic info about a file and prepare it for downloading. For the moment, bots can download files of up to 20MB in size. On success, a File object is returned.

The file can then be downloaded via the link https://api.telegram.org/file/bot<token>/<file_path> , where <file_path> is taken from the response. It is guaranteed that the link will be valid for at least 1 hour. When the link expires, a new one can be requested by calling getFile again.

See getFile official docs for a list of supported parameters and other info.

Как телеграмм-бот может получить file_id загруженного файла?

В документации API Telegram я вижу: «Вы можете передать file_id как String, чтобы повторно отправить фотографию, которая уже находится на серверах Telegram», но я не могу найти способы получить file_id загруженного файла. Как я могу это получить?

Это зависит от ваших content_types, например:

Подробнее см. По этой ссылке.

В зависимости от метода (типа файла), который вы выбрали для отправки файла, после отправки файла в Telegram возвращается ответ. Например, если вы отправляете файл MP3 в Telegram с помощью sendAudio метода, Telegram возвращает Audio объект, содержащий идентификатор файла. Источник: https://core.telegram.org/bots/api#audio

В дополнение к приведенным выше ответам вы можете регистрировать обновления, поступающие к вашему боту, либо от них, https://api.telegram.org/bot’.BOT_TOKEN.’/getUpdates либо отправлять обновления, которые поступают в ваше приложение. там вы найдете Json недвижимость, как показано ниже:

Скажем, вы получили Message с массивом PhotoSize

Как видите, есть кнопка file_id , которую можно использовать для отправки фотографии sendPhoto .

Если мы предполагаем, Update что это объект, в нем есть Message объект, который, в свою очередь, предоставляет Chat объекту в нем id : чат, из которого пришло исходное сообщение, и массив PhotoSize (извините за использование PHP здесь, но это мой основной язык. ..)

$update->message->photo как вы можете получить доступ к массиву. Используйте какой-то цикл For для перебора элементов или просто обращайтесь к первому, если массив не больше 1.

После этого, вы можете использовать результат (ов) , чтобы извлечь file_id и отправить его в качестве string через sendPhoto «s photo параметра и чат ID через chat_id параметр.

Надеюсь, это помогло!

PS Вот схема моей текущей реализации API, надеюсь, она внесет в вас некоторую ясность!

Похожие статьи