Plugin

emojiDumper

Context menu to dump and download a server's emojis.

index.tsx
Download

Source

src/plugins/emojiDumper/index.tsx
1/*
2 * FiveCord — a Discord client mod
3 * Copyright (c) 2025 FiveCord
4 * SPDX-License-Identifier: GPL-3.0-or-later
5 */
6
7import { addContextMenuPatch, findGroupChildrenByChildId, NavContextMenuPatchCallback, removeContextMenuPatch } from "@api/ContextMenu";
8import { Devs } from "@utils/constants";
9import definePlugin from "@utils/types";
10import { Menu } from "@webpack/common";
11import type { Guild } from "discord-types/general";
12import { zipSync } from "fflate";
13
14const Patch: NavContextMenuPatchCallback = (children, { guild }: { guild: Guild; }) => {
15 // Assuming "privacy" is the correct ID for the group you want to modify.
16 const group = findGroupChildrenByChildId("privacy", children);
17
18 if (group) {
19 group.push(
20 <Menu.MenuItem id="emoji.download" label="Download Emojis" action={() => zipServerEmojis(guild)}></Menu.MenuItem>
21 );
22 }
23};
24
25export default definePlugin({
26 name: "emojiDumper",
27 description: "Context menu to dump and download a server&#039;s emojis.",
28 authors: [Devs.FiveCord],
29 start() {
30 addContextMenuPatch(["guild-context", "guild-header-popout"], Patch);
31 },
32 stop() {
33 removeContextMenuPatch(["guild-context", "guild-header-popout"], Patch);
34 }
35});
36
37async function zipServerEmojis(guild: Guild) {
38
39 const emojis = FiveCord.Webpack.Common.EmojiStore.getGuilds()[guild.id]?.emojis;
40 if (!emojis) {
41 return console.log("Server not found!");
42 }
43
44 const fetchEmojis = async e => {
45 const filename = e.id + (e.animated ? ".gif" : ".png");
46 const emoji = await fetch("https:class="ts-cmt">//cdn.discordapp.com/emojis/" + filename + "?size=512&quality=lossless").then(res => res.blob());
47 return { file: new Uint8Array(await emoji.arrayBuffer()), filename };
48 };
49 const emojiPromises = emojis.map(e => fetchEmojis(e));
50
51 Promise.all(emojiPromises)
52 .then(results => {
53 const emojis = zipSync(Object.fromEntries(results.map(({ file, filename }) => [filename, file])));
54 const blob = new Blob([emojis], { type: "application/zip" });
55 const link = document.createElement("a");
56 link.href = URL.createObjectURL(blob);
57 link.download = `${guild.name}-emojis.zip`;
58 link.click();
59 link.remove();
60 })
61 .catch(error => {
62 console.error(error);
63 });
64}
65