В своей работе над ботом, который проводит розыгрыши, мне потребовалось сохранять у себя на сервере файлы, присылаемые пользователями. Очень интересный и простой процесс получился.
У Telegram Bot Api для этого есть специальный метод getFile. На входе он получает
, на выходе объект File.file_id
Параметров
у картинки может быть больше одного, потому как телеграм присылает несколько вариантов размеров картинки, последний всегда оригинал. При загрузке картинки в бот приходит информация в виде объекта Photo, в котором лежит массив объектов PhotoSize. file_id
Наш бот будет принимать только команду /start
и картинку, на остальные запросы он будет "ругаться". Чтобы определить, что нам пришло в нашем уже знакомом по предыдущим статьям методе
будем проверять ключи массива пришедших данных. Для реализации задуманного нам нужен только объект Message. init()
<?php
// проверяем если пришло сообщение
if (array_key_exists('message', $data)) {
//если пришла команда /start
if ($data['message']['text'] == "/start") {
$this->sendMessage($chat_id, "Приветствую! Загрузите картинку.");
} elseif (array_key_exists('photo', $data['message'])) {
// если пришла картинка то сохраняем ее у себя
$text = $this->getPhoto($data['message']['photo'])
? "Спасибо! Можете еще загрузить мне понравилось их сохранять."
: "Что-то пошло не так, попробуйте еще раз";
// отправляем сообщение о результате
$this->sendMessage($chat_id, $text);
} else {
// если пришло что-то другое
$this->sendMessage($chat_id, "Не понимаю команду! Просто загрузите картинку.");
}
}
?>
Картинки мы будем сохранять в директории
, располагается она рядом с файлом img
в котором наш код.index.php
.
..
[ img ]
index.php
В случае если прислали картинку, то мы передаем массив объектов
в метод PhotoSize
, он вернет результат в boolean. Внутри метода происходит 2 действия:getPhoto()
- через метод
получаем расположение файла на сервере TelegramgetPhotoPath()
- через метод
копируем картинку к себе на серверcopyPhoto()
Картинка располагается на сервере Telegram по стандартному пути:
https://api.telegram.org/file/bot<token>/<file_path>
Выводит картинку по этому пути где-либо в сети не рекомендую, так как будет доступен ваш токен от бота.
Сохранять себе на сервер мы будем оригинал, поэтому нам надо узнать количество элементов в массиве, использовать будем функцию count().
Чтобы получить расширение файла, будем разбивать
в массив по знаку file_path
функцией explode() и брать последний элемент используя функцию end(). Для копирования файлов пользуемся функцией copy()..
<?php
// общая функция загрузки картинки
private function getPhoto($data)
{
// берем последнюю картинку в массиве
$file_id = $data[count($data) - 1]['file_id'];
// получаем file_path
$file_path = $this->getPhotoPath($file_id);
// возвращаем результат загрузки фото
return $this->copyPhoto($file_path);
}
// функция получения метонахождения файла
private function getPhotoPath($file_id) {
// получаем объект File
$array = json_decode($this->requestToTelegram(['file_id' => $file_id], "getFile"), TRUE);
// возвращаем file_path
return $array['result']['file_path'];
}
// копируем фото к себе
private function copyPhoto($file_path) {
// ссылка на файл в телеграме
$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);
}
?>
* * *
Подводим итог
Сохранить картинку через Телеграм бот очень просто. Методы Bot API позволяют это сделать быстро. Для сохранения других типов файлов с Телеграм алгоритм аналогичный. Скачать исходный код можно по этой ссылке.
Откройте по ссылке или QR бот @iMakeBot, нажмите кнопку Старт/Start.
Следуйте инструкциям бота.
А можете подсказать чтобы бот вместе с успешной загрузкой выводил ещё и линк на загруженный файл?
Скинул решение в бот обратной связи
Привет. Я писал код с нуля, не используя ничего. У вас тут есть функция requestToTelegram, не могу понять где ее можно взять, немного не понятно(
В архиве приложенном к статье есть файл index.php - в нем есть класс Bot в этом классе последний метод
можно готовый билд ?
В статье файл, это уже готовый билд
Здравствуйте, а на ftp сервер загрузить можно и какой командой, чтоб успел загрузиться файл. Спасибо.
А как переслать сразу файл в группу , не сохраняя на сервере, подскажите пожалуйста?
и как отправить видеофайл/GIF? подстановка video вместо photo не решает задачу
Попробуйте применить нужный метод отправки файла. Для video использовать sendVideo ... тд
GIF - может быть также type = animation
При получении файла у вас будет в массиве данных его file_id, используя методы отправки файлов Телеграм, направьте этот файл в нужный вам чат - бот при этом должен быть участником группы с необходимым набором прав.
Эххх... Этот код бы перевести в Python... Кому под силу это сделать?
С чем может быть связано, что
стал отдавать код ошибки 404 спустя неделю работы?
Новые файлы телеграм отправляет, выдает id файлов, но их по ссылкам на api.telegram нет
Привет, Хороший Человек!
Отличный сайт...
А как можно сохранять себе не оригинал, а сжатую телеграмом картинку, или задать размеры сохраняемой картинки?
А еще как сделать так, чтобы имя картинки было равно ID пользователя, который ее грузит...Большой Спасиб!
Телеграм отправляет массив file_id картинок, каждый из которой имеет разные размеры, в первом элементе массива лежит файл с самым маленьким по сторонам размерам, в последнем элементе массива лежит оригинальный размер загруженной картинки.
При сохранении картинки на сервере - вы можете указать любое название, в том числе и id пользователя.
Здравствуйте!
Я запустил этот код, изменил только токен бота, ид-р админа, внес брекпоинты для отладки.
Почему в данном коде есть ошибка при отправке боту простого изображения с форматом png?
А именно ошибка при получении пути файла по его ид-ру файла.
может быть из-за того, что файл на латинском языке имеет название?хотя я загружал и с именем на кириллице и на латинице.