如何通过MadelineProto无file_id下载Telegram频道全部照片
使用MadelineProto下载Telegram频道全部照片(无需file_id)
我来帮你搞定这个需求!不用file_id也能轻松把频道历史里的所有照片下载下来,咱们结合你已经写的代码,一步步完善实现:
1. 循环分页获取全部消息历史
你当前的getHistory调用只获取25条消息,要拿到频道所有历史,得通过分页循环来实现。核心是每次请求后,用最后一条消息的id作为下一次请求的offset_id,直到返回的消息数组为空,说明已经获取完所有历史。
示例代码片段:
$channelPeer = "-100xxxxxx"; // 你的目标频道ID $offsetId = 0; $allMessages = []; do { $messages = $MadelineProto->messages->getHistory([ 'peer' => $channelPeer, 'offset_id' => $offsetId, 'offset_date' => 0, 'add_offset' => 0, 'limit' => 100, // 可以适当调大,减少请求次数,建议不超过100 'max_id' => 0, 'min_id' => 0, 'hash' => 0, ]); if (empty($messages['messages'])) { break; } $allMessages = array_merge($allMessages, $messages['messages']); // 更新offset_id为最后一条消息的id,下一次从这条之后开始获取 $offsetId = end($messages['messages'])['id']; } while (true);
2. 筛选出包含照片的消息
遍历所有消息,筛选出带有有效照片媒体的消息。判断标准很明确:
- 消息存在
media字段 media['_']等于"messageMediaPhoto"media['photo']['_']等于"photo"
筛选代码:
$photoMessages = []; foreach ($allMessages as $msg) { // 检查是否为有效照片消息 if (isset($msg['media']) && $msg['media']['_'] === 'messageMediaPhoto' && isset($msg['media']['photo']) && $msg['media']['photo']['_'] === 'photo') { $photoMessages[] = $msg; } }
3. 下载照片到本地
用MadelineProto的downloadToFile方法直接下载照片,不需要file_id,直接传入photo对象即可。为了避免文件名重复,建议用消息ID或者照片的唯一ID作为文件名。
下载代码:
$saveDir = './telegram_channel_photos/'; // 确保保存目录存在,不存在则创建 if (!is_dir($saveDir)) { mkdir($saveDir, 0755, true); } foreach ($photoMessages as $msg) { $photo = $msg['media']['photo']; // 生成唯一文件名,比如用消息ID+照片ID组合 $fileName = $saveDir . "photo_msg_{$msg['id']}_{$photo['id']}.jpg"; try { // 下载照片到指定路径 $MadelineProto->downloadToFile($photo, $fileName); echo "成功下载:{$fileName}\n"; } catch (\Exception $e) { echo "下载失败(消息ID: {$msg['id']}):" . $e->getMessage() . "\n"; } }
一些实用注意事项
- 权限检查:确保你的MadelineProto账号有权限访问目标频道(公开频道可直接访问,私有频道需要先加入)
- 速率限制:Telegram API有请求速率限制,不要把
limit设得过大或者循环速度太快,避免被临时限流 - 分辨率选择:如果需要指定下载的照片分辨率,可以从
photo['sizes']里挑选合适的尺寸(比如最大的那个),传入对应的size对象给downloadToFile
内容的提问来源于stack exchange,提问作者vxopdx
相关产品推荐
相关产品推荐

