Forked from peterthehan/discord-batch-emoji-downloader.js
Last active
July 19, 2026 11:08
-
-
Save antonlabz/157efd566667aa926a2bf0b4fbfe5327 to your computer and use it in GitHub Desktop.
Batch download emojis from any Discord server.
This file contains hidden or 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
| // based on peterthehan's gist - with updated scraping logic and per-emote logging | |
| // ------------------------------------------------------------------------------- | |
| // 0. Open Discord's web client | |
| // 1. Visit the server whose emojis you want | |
| // 2. Open the emoji picker UI and keep it open | |
| // 3. Minimize the page's zoom so that as many emojis load into the picker as possible | |
| // 4. Open the browser's DevTools (press F12) > Elements tab | |
| // 5. Use the element picker tool to select the server's emoji list header | |
| // 6. Find the section that highlights the emojis you want when hovering over the element "<div class="categorySection_.." | |
| // 7. Right click the element and Copy > Copy Element | |
| // 8. Paste the element into "file.txt" | |
| // 9. Run this script at the same location as "file.txt" to download all the emojis. | |
| // Use a sensible sleep value so as not to rate-limit yourself | |
| // The script relies on scraping so the regexp/logic may become outdated | |
| const https = require("https"); | |
| const fs = require("fs"); | |
| const sleepDuration = 1000; | |
| const emojiRegExp = /<li.*?<img.*?><\/li>/g; | |
| const emojiNameRegExp = /data-name="(.*?)"/; | |
| const emojiIdRegExp = /data-id="(\d+?)"/; | |
| const isAnimatedRegExp = /data-animated="true"/; | |
| const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms)); | |
| const main = async () => { | |
| const input = fs.readFileSync("./file.txt").toString(); | |
| const parsed = [...input.matchAll(emojiRegExp)] | |
| .map((match) => match[0]) | |
| .map((fragment) => { | |
| const nameMatch = fragment.match(emojiNameRegExp); | |
| if (!nameMatch) { | |
| console.log("NO NAME MATCH:\n", fragment.slice(0, 300)); | |
| return null; | |
| } | |
| const emojiName = nameMatch[1].replace(/~\d+$/, ""); // strip ~1 disambiguator | |
| const idMatch = fragment.match(emojiIdRegExp); | |
| if (!idMatch) return null; // unicode sprite emoji, nothing to download | |
| const emojiId = idMatch[1]; | |
| const isAnimated = isAnimatedRegExp.test(fragment); | |
| const extension = isAnimated ? "gif" : "png"; | |
| const emojiUrl = `https://cdn.discordapp.com/emojis/${emojiId}.${extension}`; | |
| return { emojiName, extension, emojiUrl }; | |
| }); | |
| for (const { emojiName, extension, emojiUrl } of parsed.filter(Boolean)) { | |
| console.log(`Downloading ${emojiName}.${extension}`); // progress | |
| const file = fs.createWriteStream(`./${emojiName}.${extension}`); | |
| https.get(emojiUrl, function (response) { | |
| response.pipe(file); | |
| }); | |
| await sleep(sleepDuration); | |
| } | |
| }; | |
| main(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment