Last active
January 4, 2025 16:52
-
-
Save wibus-wee/b7f7710546f8f98fbacf034687e90967 to your computer and use it in GitHub Desktop.
Download WeChat Stickers in macOS
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// How to use: node DownloadWeChatStickers_macOS.js | |
// Requirements: curl, node | |
// Reference: https://blog.jogle.top/2022/08/14/macos-wechat-sticker-dump/ | |
const { execSync } = require('child_process'); | |
const { randomUUID } = require('crypto'); | |
const fs = require('fs'); | |
const exec = require('child_process').exec; | |
const os = require('os'); | |
const argv = process.argv.slice(2); | |
const path = require('path'); | |
let userDir; | |
const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms)); | |
function copyFavArchive() { | |
const weChatDataPath = `${os.homedir()}/Library/Containers/com.tencent.xinWeChat/Data/Library/Application Support/com.tencent.xinWeChat/2.0b4.0.9`; | |
// 获取当前目录下有多少个文件夹名字符串长的文件夹 | |
let dirs = fs.readdirSync(weChatDataPath).filter((dir) => dir.length > 30); | |
if (dirs.length === 0) { | |
console.error('找不到用户文件夹'); | |
return; | |
} | |
// 检查文件夹里面有没有 Stickets/fav.archive 文件 | |
dirs = dirs.filter((dir) => fs.existsSync(`${weChatDataPath}/${dir}/Stickers/fav.archive`)); | |
if (dirs.length > 1 && argv.length === 0) { | |
console.info('疑似找到多个用户文件夹,重新运行时请指定序号'); | |
dirs.forEach((dir, index) => { | |
console.info(`${index + 1}. ${path.resolve(weChatDataPath, dir)}`); | |
}); | |
return; | |
} | |
if (dirs.length > 1 && argv.length > 0) { | |
userDir = dirs[argv[0] - 1]; | |
} | |
if (dirs.length === 1) { | |
userDir = dirs[0]; | |
} | |
const favArchivePath = `${weChatDataPath}/${userDir}/Stickers/fav.archive`; | |
const destPath = `${os.homedir}/Desktop/fav.archive.plist` | |
fs.copyFileSync(favArchivePath, destPath); | |
console.info(`已复制 fav.archive 文件到桌面`); | |
console.info(`[*] UserDir: ${userDir}`); | |
console.info(`[*] fav.archive 路径: ${favArchivePath}`); | |
return destPath; | |
} | |
if (fs.existsSync('fav.archive')) { | |
fs.unlinkSync('fav.archive'); | |
} | |
if (fs.existsSync('fav.archive.plist')) { | |
fs.unlinkSync('fav.archive.plist'); | |
} | |
copyFavArchive(); | |
const cmd = 'plutil -convert xml1 fav.archive.plist'; | |
execSync(cmd); // 转换为 plist 格式 | |
const input = fs.readFileSync('fav.archive.plist', 'utf8'); | |
const linkRegex = /<string>(https?:\/\/.*?)<\/string>/g; | |
let match; | |
const links = []; | |
while ((match = linkRegex.exec(input)) !== null) { | |
links.push(match[1]); | |
} | |
console.log('匹配到' + links.length + '个表情包'); | |
links.forEach((url, index) => { | |
links[index] = url.replace(/&/g, '&'); | |
}); | |
function download(url, filename) { | |
console.log('开始下载' + filename); | |
const userAgent = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.71 Safari/537.36'; | |
const cmd = `curl -A "${userAgent}" -o 'download/${filename}' '${url}'`; | |
exec(cmd, (error, stdout, stderr) => { | |
if (error) { | |
console.error(`执行出错: ${error}`); | |
return; | |
} | |
console.log('下载完成' + filename); | |
}); | |
} | |
async function main() { | |
const downloadDir = `${userDir}_Stickers`; | |
if (!fs.existsSync(downloadDir)) { | |
console.log('创建文件夹' + downloadDir); | |
fs.mkdirSync(downloadDir); | |
} | |
console.log('5秒后开始下载表情包...'); | |
await sleep(3000); | |
links.forEach((url, index) => { | |
const name = randomUUID(); | |
const filename = `${name}.gif`; | |
console.log('开始下载第' + (index + 1) + '个表情包'); | |
download(url, filename); | |
}); | |
} | |
main(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment