This is a repository with everything you need to know about abusing the Discord API and how it works!
If you have any suggestions or find any problems with these docs, feel free to open a GitHub issue!
Note that nearly every topic covered in this document is against Discord's Terms of Service.
- All Contributors
- Dolfies
- MeguminSama
- ImLorio
- Monst3red
- LewisTehMinerz
- Discord-Datamining
- PythonMCPI
- ReallyAmused
- Help! I Can't Open The "Inspect Element" Console!
- Other Docs
- Tools
- Self-Bots
- Client Modding
- Tokens
- UserIDs
- Log-Ins
- The API
- Markdown
- Discord's Webpack Implementation
- JavaScript Snippets
Alright, so, Discord recently started automatically disabling inspect element for the Discord desktop app. If you'd like to re-enable it, do the following:
- [Windows] Go to
%APPDATA%\discord\settings.json
- [The Linux Kernel] Go to
~/.config/discord/settings.json
, or if it's not there, go to~/.var/app/com.discordapp.Discord/config/discord/settings.json
- [MacOS] Go to
~/Library/Application Support/discord/settings.json
- Delete the current data, and paste the following:
{
"BACKGROUND_COLOR": "#202225",
"DANGEROUS_ENABLE_DEVTOOLS_ONLY_ENABLE_IF_YOU_KNOW_WHAT_YOURE_DOING": true
}
- Reload/restart Discord, and you should be good! Try
CTRL
+SHIFT
+I
, and it'll launch.
Credit to this Reddit comment, and also remember that each Discord app update will override the config file.
Some more documentation about the Discord API can be found below (ranked by usefulness):
Exploits and glitches can be found very simply. Some tools I use for this are Burp Suite, FireFox's Dev Tools, and the Python Requests Library. Also, pay special attention to any Discord API documentation; they'll be a great tool on your journey.
The below snippet will show every object, function, and variable a certain website added, and log them.
getAddedWindowValues = () => {
const defaultWindowKeys = window.navigator.userAgent.toLowerCase().includes("chrome") ? ["window", "self", "document", "name", "location", "customElements", "history", "locationbar", "menubar", "personalbar", "scrollbars", "statusbar", "toolbar", "status", "closed", "frames", "length", "top", "opener", "parent", "frameElement", "navigator", "origin", "external", "screen", "innerWidth", "innerHeight", "scrollX", "pageXOffset", "scrollY", "pageYOffset", "visualViewport", "screenX", "screenY", "outerWidth", "outerHeight", "devicePixelRatio", "clientInformation", "screenLeft", "screenTop", "defaultStatus", "defaultstatus", "styleMedia", "onsearch", "isSecureContext", "performance", "onappinstalled", "onbeforeinstallprompt", "crypto", "indexedDB", "webkitStorageInfo", "sessionStorage", "localStorage", "onbeforexrselect", "onabort", "onblur", "oncancel", "oncanplay", "oncanplaythrough", "onchange", "onclick", "onclose", "oncontextmenu", "oncuechange", "ondblclick", "ondrag", "ondragend", "ondragenter", "ondragleave", "ondragover", "ondragstart", "ondrop", "ondurationchange", "onemptied", "onended", "onerror", "onfocus", "onformdata", "oninput", "oninvalid", "onkeydown", "onkeypress", "onkeyup", "onload", "onloadeddata", "onloadedmetadata", "onloadstart", "onmousedown", "onmouseenter", "onmouseleave", "onmousemove", "onmouseout", "onmouseover", "onmouseup", "onmousewheel", "onpause", "onplay", "onplaying", "onprogress", "onratechange", "onreset", "onresize", "onscroll", "onsecuritypolicyviolation", "onseeked", "onseeking", "onselect", "onslotchange", "onstalled", "onsubmit", "onsuspend", "ontimeupdate", "ontoggle", "onvolumechange", "onwaiting", "onwebkitanimationend", "onwebkitanimationiteration", "onwebkitanimationstart", "onwebkittransitionend", "onwheel", "onauxclick", "ongotpointercapture", "onlostpointercapture", "onpointerdown", "onpointermove", "onpointerup", "onpointercancel", "onpointerover", "onpointerout", "onpointerenter", "onpointerleave", "onselectstart", "onselectionchange", "onanimationend", "onanimationiteration", "onanimationstart", "ontransitionrun", "ontransitionstart", "ontransitionend", "ontransitioncancel", "onafterprint", "onbeforeprint", "onbeforeunload", "onhashchange", "onlanguagechange", "onmessage", "onmessageerror", "onoffline", "ononline", "onpagehide", "onpageshow", "onpopstate", "onrejectionhandled", "onstorage", "onunhandledrejection", "onunload", "alert", "atob", "blur", "btoa", "cancelAnimationFrame", "cancelIdleCallback", "captureEvents", "clearInterval", "clearTimeout", "close", "confirm", "createImageBitmap", "fetch", "find", "focus", "getComputedStyle", "getSelection", "matchMedia", "moveBy", "moveTo", "open", "postMessage", "print", "prompt", "queueMicrotask", "releaseEvents", "reportError", "requestAnimationFrame", "requestIdleCallback", "resizeBy", "resizeTo", "scroll", "scrollBy", "scrollTo", "setInterval", "setTimeout", "stop", "structuredClone", "webkitCancelAnimationFrame", "webkitRequestAnimationFrame", "chrome", "caches", "cookieStore", "ondevicemotion", "ondeviceorientation", "ondeviceorientationabsolute", "oncontextlost", "oncontextrestored", "getScreenDetails", "showDirectoryPicker", "showOpenFilePicker", "showSaveFilePicker", "originAgentCluster", "trustedTypes", "speechSynthesis", "onpointerrawupdate", "crossOriginIsolated", "scheduler", "openDatabase", "webkitRequestFileSystem", "webkitResolveLocalFileSystemURL", "getAddedWindowValues"] : ["close", "stop", "focus", "blur", "open", "alert", "confirm", "prompt", "print", "postMessage", "captureEvents", "releaseEvents", "getSelection", "getComputedStyle", "matchMedia", "moveTo", "moveBy", "resizeTo", "resizeBy", "scroll", "scrollTo", "scrollBy", "getDefaultComputedStyle", "scrollByLines", "scrollByPages", "sizeToContent", "updateCommands", "find", "dump", "setResizable", "requestIdleCallback", "cancelIdleCallback", "requestAnimationFrame", "cancelAnimationFrame", "reportError", "btoa", "atob", "setTimeout", "clearTimeout", "setInterval", "clearInterval", "queueMicrotask", "createImageBitmap", "structuredClone", "fetch", "self", "name", "history", "customElements", "locationbar", "menubar", "personalbar", "scrollbars", "statusbar", "toolbar", "status", "closed", "event", "frames", "length", "opener", "parent", "frameElement", "navigator", "clientInformation", "external", "applicationCache", "screen", "innerWidth", "innerHeight", "scrollX", "pageXOffset", "scrollY", "pageYOffset", "screenLeft", "screenTop", "screenX", "screenY", "outerWidth", "outerHeight", "performance", "mozInnerScreenX", "mozInnerScreenY", "devicePixelRatio", "scrollMaxX", "scrollMaxY", "fullScreen", "ondevicemotion", "ondeviceorientation", "onabsolutedeviceorientation", "InstallTrigger", "sidebar", "visualViewport", "crypto", "onabort", "onblur", "onfocus", "onauxclick", "onbeforeinput", "oncanplay", "oncanplaythrough", "onchange", "onclick", "onclose", "oncontextmenu", "oncuechange", "ondblclick", "ondrag", "ondragend", "ondragenter", "ondragexit", "ondragleave", "ondragover", "ondragstart", "ondrop", "ondurationchange", "onemptied", "onended", "onformdata", "oninput", "oninvalid", "onkeydown", "onkeypress", "onkeyup", "onload", "onloadeddata", "onloadedmetadata", "onloadend", "onloadstart", "onmousedown", "onmouseenter", "onmouseleave", "onmousemove", "onmouseout", "onmouseover", "onmouseup", "onwheel", "onpause", "onplay", "onplaying", "onprogress", "onratechange", "onreset", "onresize", "onscroll", "onsecuritypolicyviolation", "onseeked", "onseeking", "onselect", "onslotchange", "onstalled", "onsubmit", "onsuspend", "ontimeupdate", "onvolumechange", "onwaiting", "onselectstart", "onselectionchange", "ontoggle", "onpointercancel", "onpointerdown", "onpointerup", "onpointermove", "onpointerout", "onpointerover", "onpointerenter", "onpointerleave", "ongotpointercapture", "onlostpointercapture", "onmozfullscreenchange", "onmozfullscreenerror", "onanimationcancel", "onanimationend", "onanimationiteration", "onanimationstart", "ontransitioncancel", "ontransitionend", "ontransitionrun", "ontransitionstart", "onwebkitanimationend", "onwebkitanimationiteration", "onwebkitanimationstart", "onwebkittransitionend", "u2f", "onerror", "speechSynthesis", "onafterprint", "onbeforeprint", "onbeforeunload", "onhashchange", "onlanguagechange", "onmessage", "onmessageerror", "onoffline", "ononline", "onpagehide", "onpageshow", "onpopstate", "onrejectionhandled", "onstorage", "onunhandledrejection", "onunload", "ongamepadconnected", "ongamepaddisconnected", "localStorage", "origin", "crossOriginIsolated", "isSecureContext", "indexedDB", "caches", "sessionStorage", "window", "document", "location", "top", "ASRouterMessage", "ASRouterAddParentListener", "ASRouterRemoveParentListener", "RPMSendAsyncMessage", "RPMAddMessageListener", "RPMRemoveMessageListener", "ContentSearchUIController", "ContentSearchHandoffUIController", "React", "ReactDOM", "PropTypes", "ReactTransitionGroup", "Redux", "ReactRedux", "NewtabRenderUtils", "getAddedWindowValues"];
return Object.fromEntries(Object.keys(window)
.filter(key => !defaultWindowKeys.includes(key))
.map(key => [key, window[key]]));
};
console.log(getAddedWindowValues());
On running the above in Discord's website or client, you should get something similar to the below logged to your console:
This snippet works for every website. For example, this is what YouTube shows:
A selfbot can be useful for quick Discord utilities; it's a bot running on a user account.
A selfbot is always risky due to its being against Discord's terms, although Discord won't notice unless you use it to carry out certain risky actions.
Discum.py (powerful wrapper with lowest chance of getting caught, though hard to master) (example here)developer has had less and less time to maintain this, so use with caution- Discord.py-Self (same syntax as discord.py, adapted for support with user accounts, one of the most secure) (example here)
Anarchy.NET (powerful wrapper w/super low chance of getting caught, weird syntax though) (example here)project is being less and less maintained, i tried it earlier today and it was not functional. not-ilinked is probably merge pull requests from people adding to the repo that'll fix some issues, but won't be doing active development. use this with caution.- Discord.JS-Selfbot-V13 (seems to be one of the best discord.js forks for selfbot development) (example here)
- Discord.JS-Pure (discord selfbot wrapper written in plain browser javascript; it runs in the inspect element console and has the same level of interactivity with the client as a client mod, such as betterdiscord or powercord.) (example here)
- Discord.py-Self Telegram
- r/Discord_Selfbots Subreddit
- Discord Previews (not really selfbot specific, mainly API stuff)
I'm a bit too lazy and inexperienced with client mods to write an entire section about them. Luckily, someone already made a repo with a list of all the big client mods! Check that out here.
Also, if you're trying to make your own, check here.
A Discord token is the authorization for your account; a userid is your account's unique identifier (userids follow a modified snowflake format).
Example token: ODU4OTMyMDU4NjAwMjQzMjMw.YY4OOw.1hs4tL-J0dBMS_yKSTN6iuhqcPo
*NOTE: don't even try this token. I changed the password + enabled 2fa after writing these docs.
- The first section (before the first period) is the account's userid, encoded in base64.
In the example token, It'sODU4OTMyMDU4NjAwMjQzMjMw
, which decodes to858932058600243230
. Running a lookup on discord.id will show that this is, indeed, the token's owner. - The second section (after the first period, before the second period) is the token's mint (creation) date, in unix time. The unix is first converted to hex, and then base64. So, to decode it, you can convert this part of the token from base64 to hex. Next, you can take the hex number and convert it to the decimal format (you'll end up with
1636699707
if you do this with the example token). If you run this through a unix to date converter, you'll get the token's mint date. - The third (and final) section is a cryptographic verification system (HMAC/Hash based Message Authentication Code) that occurs on Discord's end. Not much can be done with this alone.
Some believe that knowing this token format would allow you to bruteforce someone's token, though it'd take more than thirty years. Anything claiming to do this is probably lying or runs off 69,000,000 supercomputers. Apologies for earlier misinformation.
Here's a chart (CREDIT: ImLorio):
- First, you convert the userid to binary.
- First 42 bits of the binary can be converted to the decimal format, and the remaining integer is the amount of time since the Discord Epoch,
1420070400000
. - The next 5 bits are an internal worker id
- The next 5 bits are an internal process id
- The last 12 bits are a count of every discord id, ever.
Here's a chart (CREDIT: ImLorio)
Discord and Log-ins: What to Know & How to Abuse It (CREDIT: Monst3red)
The Discord login (in the browser's context, frontend) works as an iframe with the token inside, and it reloads to log you in. This can be abused (and it was, by m-Phoenix852) for a token login script. Because of this, you can log into the Discord webapp with a user token using selenium's webdrivers.
# SCRIPT TAKEN FROM "https://github.com/Monst3red/Discord-Token-Login-Tool"
import selenium
from selenium import webdriver
token = input("Token here: ")
script = '''
const login = (token) => {
setInterval(() => document.body.appendChild(document.createElement `iframe`).contentWindow.localStorage.token = `"${token}"`, 50);
setTimeout(() => location.reload(), 2500);
};''' + f'login("{token}")' # adapted from "https://gist.github.com/m-Phoenix852/b47fffb0fd579bc210420cedbda30b61"
driver = webdriver.Chrome("chromedriver.exe")
driver.get("https://discord.com/login")
driver.execute_script(script)
The Discord login (in the API's context, backend) works as a WebSocket connection to the url wss://gateway.discord.gg/?encoding=json&v=9&compress=zlib-stream
. I don't know much about this part, however, Hornwitser has a good documentation of Discord's WebSockets on his site.
Currently, we're on API v10 (though the client still communicates on v9).
One of the most notable URLs (in my opinion) is https://discord.com/api/v10/science; it's Discord's data collection URL. More info about it here.
I'm not gonna include all the other ones in this document, but if all you need is a list of the endpoints, they can be found here.
Hidden channels
Hidden channels are hidden on the frontend, yes, but there's nothing in the API blocking you from accessing these channels; they simply don't display. This was discovered long ago, and led to the development of this BD (BetterDiscord) extension's creation. This can be abused with, say, a selfbot or a UserScript to display all channels as if you have Owner
level permissions on that server. NOTE: you can see the channel's name and topic, though no messages sent in there are able to be seen.
JS Snippet For Getting All Hidden Channels
getHiddenChannels = (guildID) => {
const webpackCache = webpackChunkdiscord_app.push([
[Symbol()], {}, (req) => Object.values(req.c)
]);
// Prevent memory leak
webpackChunkdiscord_app.pop();
const { getMutableGuildChannelsForGuild } = webpackCache.find(m => m?.exports?.default?.getMutableGuildChannelsForGuild).exports.default;
const allChannels = Object.keys(getMutableGuildChannelsForGuild(guildID));
const { getChannels } = webpackCache.find(m => m?.exports?.default?.getChannels).exports.default;
const visibleChannels = getChannels(guildID).SELECTABLE.map(c => c.channel.id);
const { getChannel } = webpackCache.find(m => m?.exports?.default?.hasChannel).exports.default;
return allChannels
.filter(id => !visibleChannels.includes(id))
.map(id => getChannel(id))
.filter(c => !c.isCategory());
};
This function finds all channelIds for a certain guild, then finds the visible ones. It then takes the visible ones away from the total list, and we're left with the hidden channels. Finally, it makes a request for all the Channel
objects, and puts them inside an array, which is what's returned! Usage:
getHiddenChannels("guildid12419012490owo");
Webhooks are an excellent way to send data to and from discord without creating a bot, and they also work well to route selfbot responses. (dsc.RED, one of my old selfbot projects, responds through webhooks).
A webhook url accepts a few different HTTP request types:
POST
: to send a messageGET
to get data about the webhookDELETE
to delete the webhook remotely
NOTE: no external authorization is required to perform any of these actions (currently). If you have the webhook URL, you can do all of this.
- They don't seem to be very highly rate-limited; if at all.
- They're one of the most easily abused pieces of Discord's API.
- They're channel-specific.
- They can't receive messages (as far as I know).
- Their tokens are a completely different format than User/Bot auth tokens.
As everyone should know, you can easily make invites to servers. What you might not know, though, is that you can actually make friend links; AKA links that, when someone clicks on them, it makes them add you!
void async function () {
const { createFriendInvite } = webpackChunkdiscord_app.push([[Symbol()], {}, req => (
Object.values(req.c).find(m => m?.exports?.default?.createFriendInvite)
)]).exports.default;
// Prevent memory leak
webpackChunkdiscord_app.pop();
console.log(`Friend invite: https://discord.gg/${(await createFriendInvite()).code}`);
}();
This snippet is self-working, unlike the getHiddenChannels
one. Just paste it in your console, and bam: you have a friend link!
Self explanatory, the below snippet will make your client think you're a Discord developer.
Object.defineProperty(
(window.webpackChunkdiscord_app.push([
[""],
{},
(e) => {
m = [];
for (let c in e.c) {
m.push(e.c[c]);
}
},
]),
m).find((m) => m?.exports?.default?.isDeveloper !== void 0)
.exports.default,
"isDeveloper", {
get: () => true,
configurable: true,
},
window.webpackChunkdiscord_app.pop();
);
Object.defineProperty(
(window.webpackChunkdiscord_app.push([
[""],
{},
(e) => {
m = [];
for (let c in e.c) {
m.push(e.c[c]);
}
},
]),
m).find((m) => m?.exports?.default?.isDeveloper !== void 0)
.exports.default,
"isDeveloper", {
get: () => false,
configurable: true,
},
window.webpackChunkdiscord_app.pop();
);
You can earn one of three HypeSquad badges by taking the test (located below the Change Log in Discord's settings).
Each HypeSquad badge has an ID.
Bravery
: 1Brilliance
: 2Balance
: 3
You can abuse this fact to get any HypeSquad Badge you want.
Here's some code to do that, using Python's requests
lib.
# ADAPTED FROM "https://github.com/TT-Tutorials/Rage-Multi-Tool/blob/main/rage.py#L2804"
import requests
token = input('What\'s your token?: ')
house = input('Which HypeSquad Badge do you want?\n[1]: Bravery\n[2]: Brilliance\n[3]: Balance\n\n> ')
try:
house_id = int(house)
except:
print("You must input 1, 2, or 3!")
JSON_PAYLOAD = {'house_id': house_id}
JSON_HEADERS = {'Authorization': f'{token}'}
r = requests.post('https://discordapp.com/api/v9/hypesquad/online', headers=JSON_HEADERS, json=JSON_PAYLOAD, timeout=10)
if r.status_code == 204:
print(f"Badge successfully changed!")
else:
print("There was an error changing your badge.")
Currently, the Discord API isn't very secure. To get access to nearly every endpoint, you only need to set the Authorization
header of your request to a User/Bot token. Do note, though, that User tokens and Bot tokens grant different access to different endpoints; you have to experiment to find what token has more access. But, I'd assume User tokens have the least limitations (with the highest chance of getting in trouble). Also note that Discord user tokens are practically immune to ratelimiting aside from spam; bot-tokens aren't that powerful.
The Discord Client Application uses etf rather than json to connect to the gateway, where as the website uses json, they both send slightly different Identify payloads to the gateway meaning Discord should be able to notice when you're connecting as a "Browser" and when you're connecting as a "Discord Client". You should keep this in mind when picking the encoding for your connection.
Bot accounts and User accounts both have their advantages and disadvantages, however, Bot accounts get rate-limited more frequently than User accounts. This fact can be useful when it comes to selfbotting and API exploitation.
Flags are a deciding factor in your account's preferences, as well as what badges you have. Similar to genetics with alleles controlling traits, your number of flags codes for badges, as well as other user-data.
See the untold Flag Documentation (Credit LewisTehMiners)
Your token will almost never stay the same forever. Regardless of if you have 2fa or not, changing your password will always change your token.
Users with any form of 2fa (like Google Authenticator) have "MFA Accounts." These accounts have a different token each time you log in.
Users without 2fa in any form can change their password to change their token.
Alright, so this also deserves a section on its own, but not much is here.
- ~~strikethrough text~~
- **bolded text**
- *italicized text (1)*
- _italicized text (2)_
- __underlined text__
- `single-lined codeblock`
- ```multi-lined codeblock``` *see below
- > single-lined quote
- >>> multi-lined quote
Discord added a new feature recently; ANSI colors in multi-lined codeblocks! To do them manually, check here!
Discord, like many platforms, has their own, pre-written API wrap. It's only accessable through the application itself, sorry Python devs.
If this section has peaked your interest, you're in luck! I have a "library" (used in loose terms; it's just something you paste in the inspect element console, but still) that automates a lot of this stuff, and has support for its own special stuff. Check that out here!
See the window.webpackChunkdiscord_app
object here. (CREDIT to the Discord Datamining team!)
To fetch webpack modules in the easiest way possible, load up Discord, open the inspect element console (can't? see here), and paste the following functions:
let getModule = (n, f = true) => { // 'f' is whether to return the first module found if it goes by display name
const cache = () => {
let webp = window.webpackChunkdiscord_app.push([
[Symbol()], {},
_ => _.c
]);
window.webpackChunkdiscord_app.pop();
return webp;
};
let findAllModules = (filter = (m) => m) => {
let modules = [];
for (let item in cache()) {
if (Object.hasOwnProperty.call(cache(), item)) {
let element = cache()[item].exports;
if (!element) {
continue
}
if (filter(element)) {
modules.push(element)
}
}
}
return modules
};
let x = false;
let mod;
window.webpackChunkdiscord_app.push([
[Math.random()], {}, (e) => {
mod = mod || Object.values(e.c).find(m => m?.exports?.default?.[n]);
}
]);
window.webpackChunkdiscord_app.pop();
if (typeof mod === "undefined") {
window.webpackChunkdiscord_app.push([
[Math.random()], {}, (e) => {
mod = mod || Object.values(e.c).find(m => m?.exports?.[n]);
}
]);
window.webpackChunkdiscord_app.pop();
}
if (typeof mod === "undefined") {
x = true;
if (f == true) {
mod = mod || (typeof findAllModules(m => m?.default?.displayName === n) !== "undefined") ? findAllModules(m => m?.default?.displayName === n)?.[0] : findAllModules(m => m?.displayName === n)?.[0];
} else {
mod = mod || (typeof findAllModules(m => m?.default?.displayName === n) !== "undefined") ? findAllModules(m => m?.default?.displayName === n) : findAllModules(m => m?.displayName === n);
}
}
if (x) {
return (typeof mod?.default !== "undefined") ? mod?.default : mod;
}
else if (x == false) {
return (typeof mod?.exports?.default !== "undefined") ? mod?.exports?.default : mod?.exports;
}
return undefined;
}
Example usage:
getModule("getToken").getToken();
getModule("getChannelId").getChannelId();
getModule("Markdown");
Credit to DoggyBootsy, as he originally made this function, I just altered it a bit.
// function to find all of Discord's webpack modules, based on a filter if applicable
let findAllModules = (filter = () => true) => {
(e = webpackChunkdiscord_app.push([
[Math.random()], {}, (e) => {
webpackChunkdiscord_app.pop();
return e;
}
]),
m = []);
for (let i in e.c) {
if (Object.hasOwnProperty.call(e.c, i)) {
let o = e.c[i].exports;
if (!o) {
continue;
};
if (filter(o)) {
m.push(o);
};
}
}
return m;
}
This function locates all of Discord's webpack modules (if a filter isn't supplied), and returns them. Example filters:
findAllModules(m => m?.default?.displayName=="MiniPopover");
The question marks are required as a sort of error checking; if there's no default
child of m
, your code won't die because you had the question marks.
This snippet will find all of discord's modules, and then return the one(s) with a display name of "MiniPopover"
. By the way, the "MiniPopover"
is the three dots menu on every message.
findAllModules(() => true);
This snippet finds every module (no filter).
let findModules = (n, b) => {
(d = typeof b === "undefined" ? true : b,
n = n.toLowerCase(),
m = new Array());
webpackChunkdiscord_app.push([
[Math.random()], {},
(e) => {
m.push(...Object.values(e.c).filter(m => m?.exports && ((m?.exports?.default && Object.keys(m.exports.default).some(key => key.toLowerCase().includes(n))) || (m.exports?.default?.prototype && Object.keys(m.exports.default.prototype).some(key => key.toLowerCase().includes(n))) || Object.keys(m.exports).some(key => key.toLowerCase().includes(n)))))
}
]);
if (d) {
m.forEach(f => m.push(typeof f?.exports?.default === "undefined" ? f?.exports : f?.exports?.default));
for (var i = 0; i < m.length; i++) {
m.forEach((f, i) => typeof f?.id === "undefined" ? m = m : m.splice(i, 1));
}
return [...m];
} else {
return [...m];
}
}
This function (CREDIT pythonmcpi for the general function, I modded it slightly to filter in a little bit more of a fine way) does a general function search and returns the encasing modules.
For example, findModules("gettoken")
will return two modules including that function, and since they're modules, other functions involving the token will show up as well.
This function has two "modes", and defaults to the first if no mode (boolean) is specified.
findModules("TERM_HERE", true)
: finds the direct "module export" and grabs only the functions in that module, not information like module-IDs. This is the most "straight-shot" way a fuzzy module search should go imo.findModules("TERM_HERE", false)
: returns the raw module, including module-IDs and other info that may be useful, but not generally.
For more JS snippets, check here!