Greasy Fork is available in English.
提取blob URL 中的 UUID 作为文件名批量下载头像,默认保存格式为jpg
// ==UserScript==
// @name 批量保存Telegram用户头像
// @namespace http://tampermonkey.net/
// @version 1.1
// @description 提取blob URL 中的 UUID 作为文件名批量下载头像,默认保存格式为jpg
// @author GR:PM
// @license MIT
// @match https://web.telegram.org/k/*
// @grant none
// ==/UserScript==
(function () {
"use strict";
// 创建控制按钮
function createUI() {
const container = document.createElement("div");
container.style.cssText =
"position:fixed; bottom:20px; right:20px; z-index:9999; display:flex; flex-direction:column; gap:10px;";
const autoBtn = document.createElement("button");
autoBtn.innerText = "⚡ 自动加载并下载全部头像";
styleButton(autoBtn, "#ff8c00");
autoBtn.onclick = startAutoProcess;
container.appendChild(autoBtn);
document.body.appendChild(container);
}
function styleButton(btn, color) {
btn.style.cssText = `
padding: 12px 20px;
background-color: ${color};
color: white;
border: none;
border-radius: 8px;
cursor: pointer;
box-shadow: 0 4px 12px rgba(0,0,0,0.2);
font-weight: bold;
transition: transform 0.2s;
`;
btn.onmouseover = () => (btn.style.transform = "scale(1.05)");
btn.onmouseout = () => (btn.style.transform = "scale(1)");
}
// 等待函数
const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
// 核心流程:自动翻页 -> 等待加载 -> 下载
async function startAutoProcess() {
console.log("开始自动执行...");
let nextButton = document.querySelector(".profile-avatars-arrow-next");
// 1. 循环点击“下一步”直到按钮消失或不可点击
while (
nextButton &&
getComputedStyle(nextButton).display !== "none" &&
getComputedStyle(nextButton).visibility !== "hidden"
) {
nextButton.click();
// 稍微等待动画和加载,300ms 是一个比较稳妥的值
await sleep(300);
// 重新获取按钮状态
nextButton = document.querySelector(".profile-avatars-arrow-next");
// 检查是否还有未加载的 hide 元素
const hiddenAvatars = document.querySelectorAll(
".profile-avatars-avatar.hide",
);
if (hiddenAvatars.length === 0) break;
}
console.log("翻页完成,等待最终资源同步...");
await sleep(1000); // 给 Blob 生成留一点最后的时间
// 2. 执行下载
downloadAll();
}
function downloadAll() {
const avatarImages = document.querySelectorAll(
".profile-avatars-avatars .avatar-photo",
);
if (avatarImages.length === 0) {
alert("未找到可下载的头像图片。");
return;
}
console.log(`准备下载 ${avatarImages.length} 张头像...`);
avatarImages.forEach((img, index) => {
const src = img.src;
if (!src || !src.startsWith("blob:")) return;
const uuid = src.split("/").pop();
const fileName = `${uuid}.jpg`;
const link = document.createElement("a");
link.href = src;
link.download = fileName;
// 批量下载间隔,防止浏览器崩溃
setTimeout(() => {
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
console.log(
`[${index + 1}/${avatarImages.length}] 已保存: ${fileName}`,
);
}, index * 200);
});
console.log(`完成。`)
}
createUI();
})();