#🧩-plugin-development
1 messages · Page 88 of 1
it immediately updates the message component if it's currently rendered on screen
if that wasn't a forced behavior, you would have to click away or interact with the message to trigger a rerender
Hey! I'm currently working on an EditUsers plugin for Vencord (ported from BetterDiscord) and I'm looking for testers.
send your github repository here if you want any help
you don’t need to go to DMs or anything
Ohh awesome thank you
Is there any way to edit the content of messages on screen?
For example by taking the actual text of the message and scrambling with words or something
The actual operation on the words don't matter just the ability to read them and change the text shown
not to be pushy but i would like if someone available could answer :)
yeah pretty possible
find: "!1,hideSimpleEmbedContent",
you want to patch c
c is the message content
not sure i understand lol
where is this in the api?
you have some reading to do if you dont understand
it's the find for a patch
search up patches
the reading is pins btw
The top pin has a guide that's kinda outdated in terms of its specific example but the concept is still valid
to be fair i did start yesterday
you can look through all the current plugins to see how patches work
Since discord is minified, to what extend is writing patches just reverse engineering what does what?
you're writing regex to match the minified code and replace it
ofcofc, but how do you find the minified code in the first place, cus ive been having a tough time with that ;-;
wait theres a video omagah
? where?
danke
Bitteschöönn :3
- Go to settings
- Enable react inspector
- Full restart Discord. Tray > Quit
- Launch Discord
- Reload Discord (ctrl + r)
- Now that it is installed, every time you full restart Discord, you will need to reload after. It only attaches after a reload.
- ctrl + shift + i -> component inspector
im fairly certain we won't have to do too much/any patches for the plugin we wanna do
break points, inspecting multiple layers in the hierarchy, and using Sadan's dev companion in vscode which actually lets you go through the call chain for patches and finds
You also just get more familiar with it over time and it becomes less of a maze
Sometimes it's still a maze though
weird
Searching for the css classes on the component you want to patch can be a good way of finding things too
i followed all the steps but all i got was this
For react dev tools?
You'll need to full restart discord and then also ctrl+r reload for it to show up
i did that
you probably didnt actually fully close discord
you probably just clicked X and it minimized to tray
nope i fully closed it
regex 
Doesn't matter but watch already includes --dev so you don't need to add it on
ah I dont ever use watch lol
up arrow + enter + ctrl-r my beloved
do you guys not actually use watch 😭
watch is insane behavior
I don't want the mf tweaking at every character I mistype
like let me do my thing and reload on my own terms
thank you very much
watch is so goated cuz I just hit ctrl S and reload discord
also using jetbrains for vencord is something I had not ever even considered
Does vscode save whenever you click off the file?
IDEA does and I don't want it reloading every time I do that lol
But I do like the autosave
nah at least not with the default config
i feel like i'm missing something really obvious lol
same goes for my custom plugin, putting it in a folder and renaming the file index.tsx doesn't make it show up
this is a really elementary question i know but i'm following the instructions exactly
are you using vesktop or vencord
vencord
how is your folder named userDevTools
if you cloned off the repo I sent it should be named vc-userDevTools
i renamed it from vc-userDevTools
idk what the instructions are but try running pnpm run inject ig
i did that lol but i'll try again
changed it back lmao
same issue
am following this https://docs.vencord.dev/installing/custom-plugins/
did you actually git clone vencord or are you just trying to do this in the vencord folder created by a normal install
i did git clone vencord
it works fine when it's not in a folder
wtf
Yeah probably lol
you rebuild in dev and reload?
Yep
You're not using any relative paths for imports or anything that are broken by introducing a folder?
I feel like that'd still appear but error anyway but I dunno what else to think
Nope
And no errors are thrown in console from what I can see
why would devcompanion not be showing up tho
Surely the only other thing could be the build script not checking subfolders in userplugins
if you didnt name it userplugins but some weird unicode abomination
zws hiddin within
But surely then it wouldn't compile my plugin outside of the folder?
are those the only 5 things in the folder
no theres the types folder with stuff in it too
guess it wasnt made to be
im on cachy
no errors in console?
make sure it isnt filtering or searching anything
Nothing out of the ordinary
hang on i think this second one is new
i don't think thats it tho
no vencord errors
If you launch discord from command line does anything stand out in there? There's logs from the native process in that one too
It's harder to read though, kinda spammy
not sure how to do that lul lemme figure it out
nope nothing in particular
wait does this mean anything?
I don't get that line on windows but I also don't think it's from vencord so 
I think you're just not allowed to make plugins
Why would that be lol
show ur index.tsx
cause it's not working
I'm just joking
u probably messed up define
oma
you need to backread before talking
it's not even working for a git clone of sadan's dev companion
ah
😭 he's probably building it to the wrong dir i bet
She
And I haven't done anything but run pnpm build --dev and pnpm install
And as I say
My custom plugin works fine when it's not in a folder
whats the name of ur custom plugin when its contained within the folder
Index.tsx
and no build errors interesting and murphy mentioned how even sadan's dev companion is not working
Yes.
what about the actual folder where u have that all placed
is it named "userplugins" within the src?
Do you have any empty folders in your userplugins folder?
I remember that caused an issue in the past
Or maybe it was an empty index.ts in there, something like that
My desktop
Nope and nope
I'll try putting it inside plugins instead of userplugins
That dev companion is the regular one that appears when you build with --dev unless you renamed it
userdevcompanion is also enabled
Sick
but seriously
what the fuck
i moved it back into userplugins and it now magically works
i'm struggling to understand what /i does in the regex?
or actually this entire chunk of the regex in the example
I forget exactly what \i gets replaced with, but it's any valid character in a variable
and the rest is normal regex
use https://regex101.com to explain regex (and also test it and see all the tokens)
oh wow they changed the look
and backend apparently
Yeah \i just matches variable names, so by doing something like src:\i.url to match src:xj.url, you avoid the match breaking if Discord's minifier decides to change it to src:ey.url
ah got it
why does it need the greedy expression?
wdym?
the {0,400}
wheres that
ah here
can I see full line?
context matters
so after src:<variable> there's 400 characters or less of stuff we don't care about and that manually matching would be a nightmare for long term maintainability. but we need stuff on both sides of the 400 characters but dont care whats in the middle so we just say "anything up to 400" and we cap it at some number close to the actual number of characters so it doesnt accidentally match something too far
here is the referenced code block. why does it match for primaryEmoji, src:\i when the code they want to patch is fourish lines below?
cause they are capturing the variable src:(<variable>) now <variable> is usable in the replacement as $1
the .primaryEmoji, is to anchor it to that instance of src: because src: is a very common occurrence in code
ohh that' so interesting
did you truncate the code there or is that how it looks
cause if thats how it looks the 400 is way too much imo lol
so the idea is to bring the src variable down to that code section
am reading this
ok they probably truncated it for the example yeah
but they're adding a thing instead of replacing it
yes in this case
what if i want to make $1 be something that isn't in the code block?
the $& means "everything the match matches regardless of capture groups"
then you either change the match to capture it or if you meant something stable you come up with you just write the text
capture it how?
exploring existing plugin patches with dev companion would be helpful
(capture and overwrite)
(?:dont capture but group this in the regex and overwrite it)
(?<=dont capture and put the replacement after this group, not overwriting it)
(?=dont capture and put the replacement before this group, not overwriting it)
thanks for the help!
can't for the life of me figure out where you found this
ohh
i can't find the whole code snippet and there's nothing distinctive in the screenshot to match
o wow
top/bottom dont count, 2nd is the modified version of the 3rd
thank you so much
embeds will still render so you'd need to handle that differently if that matters
not for now thanks
the function i call in my patch needs to be async because it calls a function that returns a promise, but when i make it async discord shoots itself in the head, what am i supposed to do?
can i make an async patch??
Not without also patching everything that calls it, and everything that calls that
So practically, no
waiting on a promise to be fulfilled
That tells absolutely nothing y'know
good point lol
You want to use async to do async, oh my
i'm waiting on the decrypt function from subtle crypto
which returns an arraybuffer promise as previously stated
prolly just cuz it takes time to decrypt stuff
i don't know how it works under the hood lol
you tryna encrypt messages? lol
nope SubtleCrypto is async
Yep lol
but yea it really depends on what you're trying to do
Encryption is all done
why
Why not?
is it for actual protection or protection against normies. cause anyone with half a brain and access to your pc could just type ctrl+shift+i and type the code to fetch the message you're visually hiding in the chat
what?
no the message is encrypted before it's sent
ah
so you just dont want discord to see it
sus
or anyone else I guess
other than receiver
it's the same way whatsapp group chats work lmao
how is that sus
it just seemed like a fun project and i'm not sure i like what you're insinuating
that is how encryption works yes
Just use a platform with builtin encryption tbh, rather than shoehorning it into one that doesn't
i'm not expecting to get genuine security out of this
We used .then()and edited the message using the updateMessage api function
well there's plenty of existing plugins that use advanced algorithms to generate encrypted messages and decrypt it when received
both users have to have the plugin
Doesn't hurt to make it yourself as a learning excercise
well honestly it's really not that difficult at all
intercepting received, and sent encryption / decryption depending on author and having a context menu patch on user to enable that
i just don't see the use case in this mainly because the other author you're sending / receiving from has to have the plugin enabled also
Why does everything have to have a point?
Can I not just do a thing for the sake of doing it?
It is my first project
Why would I do something harder
This is plenty difficult for me
i'm not challenging you to do something more difficult i'm just saying it's an easy task
yes of course i'm just saying between users you'd have to have them install the same user plugin as you
I know that
Bro you aint gotta try to aura farm like that 🥶
what is classname needed for?
so devs can specify custom classnames
what does that mean?
custom css classes
ahh
react uses className because class is a reserved js keyword
got it working!
where on earth is this variable defined???
i can't find it anywhere
Isnt that not just some styling property? I looked it up, stack overflow says this
HTML uses color whereas SVG uses fill and stroke. You can get fill or stroke to use the value of the color CSS property by using the value currentColor e.g. fill="currentColor"
that would make sense but the translate icon turns green once enabled
so something must be changing it
I think the currentColor value sets the color of the path to the color css attribute. So maybe check there?

if anyone could send this in console and lmk what it says for you that'd be great.
more people the merrier.
await Vencord.Webpack.Common.RestAPI.get({
url: "/quests/@me"
}).then(r => r.body.quests[0].traffic_metadata_raw)
EAE=
bro is E 💔
what does it mean
trying to figure that out. running theory is rollout order for new quests. idk though
EAI=
why do you have E as 4
Shouldn't it be this?
what is the proper way to see if a plugin idea would be likely to be accepted? CONTRIBUTING.md says to open a request and say you want to work on it but requests are closed now
no EAE= is 10 01
idk how it got E to 4
insane
this was 3 pro model too
none of my alts are EAE smh
testing if it's rollout order is gonna be annoying
what isn't it 16 01
take it up with whatever cryptii.com is
ah
whatever i'll just make it and if it's rejected so be it
i'd use it anyway
you could say what it is here
would add giphy alongside tenor for gifs
that way if it already exists or something, someone can say
there's an experiment for that
really
dev://experiment/2025-10-gif-providers-multi-treatment
they're right
Hello, is anyone familiar with the process of patching the router component(s) and/or rendering a component on a 'custom' route?
I have reviewed many brief discussions on the topic in this server, including dated examples and resources.
If anyone has a current working example or preferably resources for learning how to investigate discord's code to find what I am looking for and patch it, that would be appreciated.
does this only show up in vencord
Would vencord accept a plugin that rewrites the entirety of the discord audio stack to increase quality?
I've written up one that uses ffmpeg for encoding/decoding and it matches the original audio much closer
before
after
white line = original audio
red line = recieved audio
(tested through a loopback on two clients, one unmodified, one with the custom voice stack)
audio is sent through the custom stack and recieved through the default client
also, i discovered that audio loudness is decreased by exactly 6db at discords end
boosting it by 6db before sending cancels the offset
I'm aware there used to be issues with some plugins that enable stereo and such which never got accepted into vencord
actually, this is a more accurate representation of the default audio
this is with the default audio artificially boosted by 6db
How does the PR process work? I've had https://github.com/Vendicated/Vencord/pull/4014 up for a week now and I don't think a single person has actually taken a look at it yet lol
the embed only does, yes
What pr review process 
that's what it feels like lmao
Right so, I think I've taken things too far.
no
running doom on something is never too far
u right
This should be merged, I’d use it
is this jsdos
Yes
there’s no delay for prs you just wait
uhhh have you ever wanted to render graphs and make complex algebraic equations in a discord command palette?
no? well now you can
why are we making DiscordOS
yes
yes
I actually dont know why he thinks im gonna approve this
oh ur gonna
you will
Equicord has ten times more useless plugins
who is gonna use doom in discord 😭
just add geforce now atp

add it as hidden true so you can say equicord runs doom
lmfao
discord running doom before gta 6
Coming back to working on a new plugin after a few months.. when I have the plugin included in the build and inject, every patch errors on start with the same error and Vencord fails to initialize - any ideas what it could be that's causing it?
update ur vencord
I'm pretty sure my branch is up to date
is 12da7a08fbbfe118ffdb293488745cc991c1c8a6 the latest commit? bump to 1.14.3?
for clarity, if I remove my two plugin files and build and inject, it works, adding the two plugin files back in and I get all those errors and Vencord doesn't initialize
ah that did end up being it, weird I swear I didn't see any new commits
vscode being buggy as usual 😔
Vencord: v1.14.1 • af708b4 (Dev) - 4 Mar 2026
Client: stable ~ Vesktop v1.6.5
Platform: MacIntel
⚠️ Vencord DevBuild
Oh yeah then 1.14.3 should be decently up to date, mine's a couple months old
Hi, could anyone review https://github.com/Vendicated/Vencord/pull/3885 ?
hi, what is the canonical way to get into a bundle? I want to see what the datastructre is for dave voice packets is as they get parsed
dumb question, how would I know what fields are valid for embeds? I tried setting author.url, but apparently that's not valid. I'm just going off of what messageLinkEmbeds uses, const Embed = findComponentLazy(m => m.prototype?.renderSuppressButton);
I'd just use ViewRaw on a message with an embed in it
Oh the component
Then I guess react dev tools on an embed or use that find and see what the component it finds uses in its code
Places like this where it destructures props are your best bet
This is probably still valid though because I assume that embed object is one of the props
I could never figure out how to get React DevTools to show up for me lol - I see it in %appdata%\Vencord\ExtensionCache, do I still need to create an extensions folder and put it in there like for BetterDiscord?
(obviously I have it enabled in the Vencord settings)
You also have to ctrl+r discord after fully restarting for it to appear, if you've done that I guess delete the folder in extensioncache and let it try again?
I'll try the latter
nop
skill issue ig ¯_(ツ)_/¯
let me try on vanilla vencord
still no lol wtf
I don't need to be in dev mode or whatever, do I?
yes
I get no errors, devcompanion starts up correctly... surely I'm just doing something wrong here? would it not work on canary for some reason?
nothing on stable 
pnpm build --dev- Tray > Right Click Discord > Quit
- Launch Discord
- ctrl + r in Discord once launched
uhhh
To use it you also need to compile Vencord with DEV (aka pnpm build --watch or pnpm buildWeb --watch) and enable the "DevCompanion" plugin. Then just start Discord
hi, i want to analyze how the discord client responds to a given RPC command; is there a way to dig into the webpacks of the native side like you can on the browser side
im familiar with electron's structure but not how to debug the other runtime
alright i got it (thanks to @modern cave), does anybody know of a module that I can use to get a list of current users in the current voice session
Stores.VoiceStateStore.getVoiceStatesForChannel("1234")
i was planning on just hooking whenever a user joined and then querying the channel but I have a better idea I'm just going to patch
Stores.VoiceStateStore.getVoiceStatesForChannel(Stores.VoiceStateStore.getCurrentClientVoiceChannelId())
patch what
createUser on the type with the first couple lines
class O extends f.A {
mediaEngineConnectionId = `Native-${N++}`;
goLiveSourceIdentifier;
selfVideo = !1;
codecs = [];
videoEncoderFallbackPending = !1;
videoDecoderFallbackSent = new Set;
desktopDegradationPreference = (0,
g.lE)().DegradationPreference.MAINTAIN_FRAMERATE;
although I'm not quite sure how I could select for a patch
why are you patching that though
oh to run some logic on every user that joins a call
every time something happens an event is sent out
thats how you listen for or send out events
could you send any documentation/sample code regarding that? i believe you're right that it would be a better idea to listen there instead of patching the type i found before
gotcha
this is separate but is r.A in this line a module?
if (null != n && r.A.setLocalPan(t, n.left, n.right),
i haven't looked at much expanded webpack code so I'm not familiar with the codegen for accessing modules looks like

, r = n(827343)
is n maybe the generated require?
how do you get findByProps in the console's scope btw I tried to do it with the esModule import but that didn't work
just a cjs require?
Vencord.Webpack.find<thing> or enable console shortcuts plugin
alr i did the latter i got it now
thanks
i noticed that in the dev array it was bigints for the snowflakes instead of strings; are userIds normally stored as BigInts?
discord only ever provides snowflakes as strings
vencord just uses bigints for the dev array
makes sense
take it up with V 
i noticed that a while ago when poking around good to know it's the same system
does findByPropsLazy have a significant profile? i.e should I hold onto the result or is it performant to call repeatedly
uh it'll just wait til you use the object for the first time to resolve it
oh i see
so you can define StoreName = findByPropsLazy("function") and it wont try to resolve it on boot just when you first use it
then it'll never look it up again for that session
use findStore for stores tho
yeah
i was under the impression it needed to be called at runtime didn't realize that it wrapped the return value with a lazy getter
that's much more ergonomic
for the most part you should avoid findByProps and use findByCode
findByProps my goat tho
you know what broke when QuestsStore became QuestStore? findStore("QuestsStore")
you know what didnt? findByPropsLazy("claimedQuests");

at least for the module I'm targeting it's had setLocalPan and setLocalVolume exposed since at least 2021
so I don't think it's going anywhere
(i'm porting an older plugin)
horror?
const findDefaultSounds = findLazy(module => module.resolve && module.id && module.keys().some(key => key.endsWith(".mp3")), false);
...
defaultSounds ??= (findDefaultSounds.keys() || []).map(key => {
const match = key.match(/((?:\w|-)+)\.mp3$/);
return match ? match[1] : null;
}).filter(Boolean) as string[];
ah the setLocalPan/getLocalPan updates internal state but the internal state doesn't actually influence the media mixing
shaaaame
so this RPC method must just not work ebcause I'm using the same mechanism
i confirmed that I was actually writing it with getLocalPan
i guess i just have to patch back in panning
does anybody know how to get the current MediaEngine? (or rather, the methodology i should use to identify some internal tooling that would help me identify the method that could get me the current instance of MediaEngine)
Stores.MediaEngineStore.getMediaEngine()
?
sounds right
oh weird actually
im in Vesktop and it initalized MediaEngineWebRTC
shouldn't it initalize MediaEngineNative?
i'm not sure how it chooses
tried it on an inject and even there with a MediaEngineNative it doesn't work
sad
made a draft pr: https://github.com/Vendicated/Vencord/pull/4039
if anybody here has messed with MediaEngineNative before and would know where to start with manipulating the mixer please ping me
what if a module exports something like
export const resolve = 1;
export const id = 1;
export const keys = null;
you would typeerror
why not use Obejct.Keys
good thing they dont
INSANE
thats how they all do it
2318 modules with keys
well actually only 8 do it like that
all 2318 with a keys export though are non null
all with a .resolve and .id do do it that way
This should be pinned
Any idea how to fix this? tried using a native.ts with a simple fetch in it but doesn't work either
Should i use a proxy ?
From
async function uploadWithProgress(uiId: string, file: File, partNum: number, totalParts: number): Promise<string> {
const serverRes = await fetch("https://api.gofile.io/servers", { method: "GET" });
const serverData = await serverRes.json();
const server = serverData.data.servers[0].name;
// const server = "store-eu-par-7"
return new Promise((resolve, reject) => {
const session = activeSessions.get(uiId);
if (session?.cancelled) return reject(new Error("Cancelled"));
const xhr = new XMLHttpRequest();
if (session) session.xhr = xhr;
const form = new FormData();
form.append("file", file);
let lastPercent = -1;
xhr.upload.addEventListener("progress", (e) => {
if (session?.cancelled) return xhr.abort();
if (e.lengthComputable) {
const percent = Math.round((e.loaded / e.total) * 100);
const overallPercent = totalParts > 1
? Math.round(((partNum - 1) / totalParts) * 100 + (percent / totalParts))
: percent;
if (overallPercent !== lastPercent) {
ProgressUI.update(uiId, overallPercent);
lastPercent = overallPercent;
}
}
});
xhr.onreadystatechange = () => {
if (xhr.readyState === 4) {
if (session?.cancelled) return reject(new Error("Cancelled"));
if (xhr.status === 200) resolve(JSON.parse(xhr.responseText).data.downloadPage);
else reject(new Error(`Gofile Status ${xhr.status}`));
}
};
xhr.onerror = () => reject(new Error("Network Error"));
xhr.onabort = () => reject(new Error("Cancelled"));
xhr.open("POST", `https://${server}.gofile.io/contents/uploadfile`);
xhr.send(form);
});
}
-# 3rd line fails too
you can't the error says it
also what's https://best.discord.media ?
how do i store data permanently?
without being directly editable by the user in settings
DataStore
thanks!
where do i find that so i don't have to go digging around lol
found it :3
if its small data, settings api
if its big data, DataStore
how come there's a difference?
settings API is synced over vencloud
datastore isn't
ah, amazing
because settings is for small configuration data
and has tight storage limit in both cloud sync and browsers
ah, what's the limit?
“I ran doom in vencord’s cloud storage API”
just as a sanity check, this means create a second settings file right?
so i can have settings that don't show up in the settings bit of the plugin
don't give me ideas
hidden: true
technically mutable by the user through console but probably wont be
Uh oh
i rewrote it in rust and implemented it through a .node NAPI file
how come typing only shows up in TextInput if i set the value to a setting?
?
wait hang on
i figured it out lol
is there any way to do a text input in a modal that doesn't update per-letter typed and instead all at once, like with a "submit" button?
why
what for
because i want to run a function on the completed text and running it every time a new character is input or deleted is a waste of resources and would cause lag
what does the function do
why tf are u implementing crypto in discord 😭
because i want to
just dont run it on change
what do i do instead?
const [input, setInput] = useState("");
const onSubmit = () => {
doSomething(input);
}
return (
<div>
<TextInput value={input} onChange={setInput} />
<Button onClick={onSubmit}>Submit</Button>
</div>
);
ah, awesome
you can also use a normal html form with proper submit button and onSubmit handler
or a ref
that's exactly what i'm looking for
but state gives u more control
there are plenty of react beginner courses online
might be advisable to do one to familiarise urself with it better first
will do
well if you just want to make a simple plugin u should be fine probably
but something like Vencord isn't the best environment to learn React haha
Ah! Web dev jumpscare /j
100% of my react knowledge comes from vencord because i’m not deranged enough to use react anywhere else
back when i didn’t know about predicates i would display: show ? "block" : "none"
Hey yall, what's considered to be a substantial contribution? I did a minor bug fix to the Translate plugin but idk if that's enough to add myself as a dev. Would be nice to get sum insight ^^
this is a bit of a dumb question but
how do i reset all the settings for my plugin?
idk where the file is lmao
until now I've just added something that sets them to the desired values when the plugin is loaded
no but like a full reset
I think it's in LocalStorage
#TOTALSETTINGSDEATH
Should be a storage tab in devtools
cheers
Changing the plugin name is also a quick way to get fresh settings just for testing
rename the plugin 
do you still need help with this there's two ways to do it
fetch from native would work and you can also force add the domain to the csp rules from native
*but idk if the latter is a good approach
there's also vencord api to request adding to csp but I don't like the prompt
hey everyone, needed some help with radio buttons not showing that its selected when i select an option until i hover over another option or just re-open the submenu
the purpose of the plugin is to stay a certain status until you join a VC
i also tried to convert it into a react component but was hit with this error: Error: Menu API only allows Items and groups of Items as children.
the code: https://pastes.dev/Yg7KUHuDJy
also tried asking gemini (yeah i know no ai slop and stuff but i figured if i could solve it myself, yay) and it gave a component solution which failed and then was just adding random ids to the radiobuttongroup so that was no help either
EDIT:
thought this might be needed, when i select an option, it does exactly what it needs to but the UI just doesn't show it as selected until i refresh the menu
Bumping this for Leah
Feature addition pretty much. Then it's up to maintainers if the feature was big enough. So no a bugfix isn't really enough. Unless the bug was somehow fundimental enough you had to rewrite a bunch of the plugin. But you said minor bug so probably not.
Thanks, good to know. My time will come tho >:D
is there anyway to get around settings.store returning a proxy? it's a huge pain as i can't figure out how to unwrap it which i need to do
bro using webstorm
why
sounds like youre doing something strange
Because I'm storing an uint8array in an object in settings and I need the array
I'm storing it in settings so it can be synced with vencloud
u8a is not json serializable so you literally cant
ohh i didn't know that
okay so i convert it to a normal array then back to a uint8?
an exported CryptoKey
why r u cloud syncing ur encryption key
settings are stored in plain text in our database
an encrypted* cryptokey
encryption keys should be stored locally and per device
and settings arent for binary data
binary data belongs into datastore
if its encrypted then why even have a key in the first place
you either have a key for your key
or you use a password in which case you dont need a key
because i'm going to decrypt it with a local master key
and there's different keys for different channels
if the master key is local what is the point of syncing the encrypted key
you cant decrypt it without the local key so syncing is pointless
because it will be decrypted on every device the master key is inputted in
IDEA but yeah
that is already implemented
i am further encrypting that with the master key
I dont understand why you need to sync any keys if you use KDF
the entire point of KDF is that there is no need to sync keys, you just need password and consistent parameters like iterations + salt
so there is nothing to sync other than parameters
the user then enters the password and it can derive the key
no need to sync any keys
because every channel has it's own key
so to save the trouble of having to input every channel's key individually on each new device we sync it
and the keys are pgp keys for e2ee?
no they're AES keys
what for
It really sounds like you're trying to implement something in a very bad way
And cloud is absolutely not for syncing binary data like encryption keys
AES-GCM encryption/decryption
and what are you encrypting
messages
Why we using green needle?
end to end encryption?
i'm not sure how it's bad. Channel password is hashed with pbkdf2 which is encrypted with master password, and the result is stored in the settings for synchronisation
yes
wait i can convert the uint8Array to a base64 string
that should fix it
I think we could get around all the problems by just storing the different keys for the different channels as a Map<string, string>() where the key string is the channel id, and the value string is the base 64 encoded channel key. We could then make a keyStore, turning which wraps this map. the value strings from this map should also not be inside a proxy, since strings are immutable
bruh
no... stop abusing settings for binary data 
not technically binary data if it's a string :p
Probably true for the long run tho. We do gotta find a better way to sync keys (besides using another platform ofc lul)
we could set up a dummy account as a key exchange
Tho tbf, for now, its not that bad since keys are only 32 bytes per encrypted channel
which gets multiplied by like two if u use base 64
or host the key exchange on your website
you should simply not try to add encryption to discord
use matrix, signal, xmpp
and just dont sync keys, have per device keys and add additional devices similar to how proper e2ee services like Matrix do it
Im sorry, but thats not the point
we're not going to push it to the main repo or anything
bump :(
I think there's a MenuControl or something along those lines that lets you put a react component in a MenuItem
what even is a radioitem
in relation to a context menu anyways
only radio items I know about are these type
Probably that
Right click settings and go to appearance, I'm not on pc atm but I'm pretty sure the light/dark selection is a radio item
insane
isnt the fix for this just to use a stateful variable
const [currentStatus, setCurrentStatus] = useState(whitelist[id]);
or smthn
index.tsx: Line 58
const [pasteMaskedByDefaultChecked, setPasteMaskedByDefaultChecked] = React.useState(settings.store.pasteMaskedByDefault);
yeah I use a ton of stateful variables for questify settings lol
idk if ive done it for context menus though
It was a long time ago
doesn't this break some rule of hooks
it works
yall are goated @quick zephyr @humble tulip worked for me, initally got the same menu api accepts only blah blah error so i converted it into a function and got it done, a snippet for future travellers who run into this:
https://pastes.dev/x7yiUy0Ic0
Is there such thing as an offline mode so I can test my plugins and code when I don't have WiFi?
Network tab in dev tools can emulate different connection states
Doesn't really work when it's stuck on checking for updates
Can't open Dev tools I think
Oh, no you misunderstood
When I actually don't have WiFi lol
Gotcha, I thought you meant you wanted to test for when you don't have wifi
but in that case, I don't think so, no
You can maybe launch discord.exe directly rather than update.exe
Assuming windows anyway
Oh that's a good idea
No way to load a clean server/DM
Maybe I should make an offline plugin....
That would be pretty cool but I'm nowhere near good enough
Yeah I think you'd have to. #🎨-css-snippets message This css snippet reveals the app behind the disconnection screen but I think without anything cached you'd just be looking at infinitely loading chats at best
I could make every chat click re-route to a dummy dm
is there a way to load images from my file system in a userplugin lol
i know im SUPPOSED to upload them to some image hoster but i'd rather not
Not without natives
That or localhost server which is no less work unless you already have it
what a hassle lol
i have determined it is not possible while contained in a plugin
actually i don't know why the vencord:// one works but mine throws a fit about CSP
while there's no calls to register a privileged protocol
tempted to just allow the vencord one to load any file 
oh there's a bunch of random csp stuff, though idk where it allows vencord:// to do whatever
just wondering, how would you even go about doing something like a dummy dm?
I haven't the faintest idea
if i have multiple plugins running addMessagePreSendListener for example, how do i ensure that my one runs at the very last?
is there a way?
I think it registers on plugin start, so you can use StartAt but that's about it
ordered alphabetically
And that
or use startat yeah
ah thanks
Mandatory reading https://devblogs.microsoft.com/oldnewthing/20050607-00/?p=35413
Hello, i'm having a hard time figuring out how to debug the selectors etc for this popup as it just disapear if i try to use ctrl+shift+c
You can also click the :hov button in the styles panel and tick this box
i tried it did not work
Doesn't catch everything but it works for that menu for me

didn't think of this
thanks
Plus f8break breaks react dev tools anyway
?
oh yeah it doesn't
you can run setTimeout(()=>{debugger}, 3000) in the console
You can't inspect with react dev tools when paused in a breakpoint
I know they're not trying to use that right now but still a down side
it doesn't work for me for some reasons
emulate a focused page does work for me, but the timeout debugger will work too
what's the clean way to simulate clicking on the top right search bar, selecting a filter and filtering someone. Rn i'm using fake events etc but i feel like this is the wrong way to approach this. i'm fairly new to react

the cursed way to do this is to f8 break, click on the frozen client area, move mouse to hover over dev tool but don't click to transfer focus, then f8 again to unbreak. then as long as you don't move your mouse back over the client things should stay stable.
sometimes something random will cause a rerender and you'll have to do it again but oh well
Maybe see if you can find how the new filters modal does it, 99% likely it'll be a dispatcher event
what the heck is the custom OptionType and how do i use it 
oh i get it, it's not actually shown in the settings, it's just for automatic serialization
use component if you want a custom button or whatever
does stop() get called when you reload/close discord?
i would assume it's supposed to but im having issues, doesn't seem to get called
oh, i forgot an await 
async/await was a mistake
ive been making like, an alt cdn for big files
but i didn't figure out the method for file upload
so i don't really know what to intercept lol
but i got it working basically
Does anyone know how to inject/add an option into this container to add an new section?
I can't find the internal component name or the Webpack module I should target for the injection.
Check out #1272186590214619281
that is the easy part,
i meant on drag and drop
like intercepting the actual file upload stuff
yk when you normally upload it would still say 10 mbs max
but you have my cdn as a little button
to click and send any file from it
i want to like override discord's behavior to instead use mine if the file is too large
which requires interception and stuff and i am very bake-d right now to re-read vencord's src not gonna lie
Sounds like you'd want to patch UploadHandler.promptToUpload (and its sister function, wreq(518960).V, which is in the same module but isn't particularly useful on its own to have a vencord alias)
It gets triggered when you drop a file onto the discord app, and it handles some common file upload errors
didn't work
oh and sorry for
the uh
3-4 hour
late response
i tried that already
and i patched before discord loaded
so i made it wait
until it fully loaded
but it then completely skipped trying to patch lol
and i hated whatever it was doing so i just went off without drag and drop for now
it works fine
ok so I made a plugin for selecting multiple messages and a plugin for screenshotting said messages, I forked equicord but lowkey their server is kinda just full of toxic people so I was wondering if this server is any better and if my plugin ""is legal"" for merging
https://github.com/kr1viah/Equicord/blob/main/src%2Fuserplugins%2FmessageScreenshotter%2Findex.tsx (screenshotter plugin, selecter is in the same directory)
the screenshotter plugin currently actually doesn't screenshot (because I tried and don't know how), but instead opens a model with settings on how to treat the messages (censoring name, pfp, etc) selectable per-user for you to screenshot
meta + shift + s
(meta = windows key)
also
sounds like a neat concept but
eh idk it just is so easily replaceable by
so many metrics
it wouldn’t be accepted
doable with a bot
^
this seems kind of niche and like it'd encourage creating spliced screenshots to slander people
I don't think it can be accepted sorry
I can make the background slightly not dark theme discord if you want
to be able to distinguish it (though not really visually) from actual screenshots
for what reason?
the ones I just said
as for the niche thing, ~75% of people who I've shown this (like... 30?) would use it
as for the other thing, yeah, idk, that'll happen anyways, I don't think it's my/our/your issue
note that it does dom editing on the model opened, to replace the pfp image, names, (basically anything), because I tried to find a way that doesn't use dom editing but i couldn't find a way to make that work. if there's a better way, please let me know, but I believe this to be the only way
btw i suggest using this to automatically create a perfect screenshot of the messages
https://www.electronjs.org/docs/latest/api/web-contents#contentscapturepagerect-opts
you can pass the rectangle to screenshot which you can easily get for your message container with Dom apis
to screenshot the perfect area
you'll need a native.ts exporting a async function takePageScreenshot(event, areaRect): Uint8Array
look at other plugins to see how to use that
but is this fine?
(I'm gonna be honest I have no idea what I'm doing for the most part, I barely know what react is still lmao)
after thinking about it for a while and looking things up, there's no better option other than to edit the dom and to use hardcoded classes
whats so bad about hardcoding classes anyways
@dull magnet wdym 
🤷
does it support transparent backgrounds
ngl that's like the only thing I'd want from a screenshot plugin
cuz having the ugly ass gray background visible is so meh, especially when discord has like 15 different themes now
svg exports would be even better but that would be a pain in the ass to implement
(in fact I had to set the background colour manually)

what
your video has brave in it
so?
so they replied with the brave logo
why would they do that
why not
would this plugin be accepted?
- when someone sends a soundboard, it sends the soundboard mp3 link in chat like this:
meow - the recipient clients then check if the message contains a soundboard-sounds link like this and plays the sound.
the soundboard link would only play when youre in the same channel call.
ig the main concern is that its gonna spam the chat, so maybe this idea is bad
self botting and sounds over-engineered. something like that was rejected by vee a long time ago as well
no
something like fake nitro where it just sends the link on click maybe though
But that's what I meant, no?
It sends a link, and the client listens to on message event, just like the deleted messages plugin and plays the soundboard MP3 automatically if the message contains the soundboard link
the latter half is probably too shitposty for most official plugins nowadays
even moyai plugin isnt around anymore (hasnt been for years actually i just keep forgetting)
it has not been gone for years. it's almost been 1 year (also i don't think i even realized it was gone lol) https://github.com/Vendicated/Vencord/commit/600a95f751c5977f47d64aaa97fdbfd3f324504e
This plugin is funny but ultimately useless and leads to a
lot of confusion from users enabling it by mistake
who has a vencord plugin graveyard
see all of my published Vencord userplugins
also
@hushed loom satan
Rest in peace moyai
I have an idea how its tombstone could look
can vencor patch into fast connect
doesnt seem to let me
i guess its not a webpack module so thats why

patches won't do it
you'd have to do it manually
i monkeypatched WebSocket prototype for my use but ended up not needing the plugin anyway
thought something wasn't working becasuse gateway sesison was web rather than desktop so i tried setting it to desktop but the issue was different thingie
Hi! I've been trying to find a way to retrieve registered user application commands, but I've been quite failing to find the relevant functions
by bots?
I tried some basic reverse engineering, but because no UI element directly fetch that information (ie. the button to open the command drawer just dispatch an event), I've been having quite a hard time
by applications, registered on the user
user installed apps?
yeah
Enable ConsoleShortcuts
then look at the Stores object in console
these seem most promising
Stores.ApplicationStore
Stores.ApplicationCommandStore
Stores.ApplicationCommandIndexStore
for some reason the Stores object is empty and only ApplicationStoreexists globally, I'm not sure why it's different on my install
I've previously tried a findByProps("ApplicationCommandStore") but the test find fails
Okay I've managed to take a look at both stores. It seems like the ApplicationCommandStore doesn't hold much information, while ApplicationCommandIndexStore doesn't let me execute the command, although at this point a simple REST call should do the trick?
yes
i made a plugin for myself rn that disables the in game soundboard overlay. It's literally 2 lines. I'm assuming that would be too simple to be merged?
I made it because I use CTRL + ` as my mute keybind in Discord, which is the same UNCHANGABLE keybind used for the soundboard overlay which constantly makes me play the loudest sounds when trying to mute
what's considered niche here and generally accepted just curious
because i've seen quite a few PRs come in here and the acceptance rate is low
i'm just wondering what are the best places for me to contribute and what can i actually submit which will be accepted
and is there any limitations to the number of patches i can use?
ask before PRing
as much as necessary
fair enough then
you mean ask the general public whether they'd see a use in the plugin?
All low hanging fruit plugins have already been made
Coming up with a new, genuinely useful idea isn't easy
ask here
else you're gonna waste your time
Hello 👋 I made a small QOL plugin that I talked about some time ago
I'm not sure it's been done? But correct me if I'm wrong
I thought I explained it decently in the Readme
Also if yall could give feedback on it that'd be great, I'm hoping to PR this soon if it's not a stupid idea or too niche lol
https://github.com/Calebh101/VC-MessageCorrector
-# also ping me when responding plez
https://github.com/Calebh101/VC-MessageCorrector/blob/11371605787502633fdcb8226fb5b9a64435f805/index.tsx#L68
https://github.com/Calebh101/VC-MessageCorrector/blob/11371605787502633fdcb8226fb5b9a64435f805/index.tsx#L72
why
https://github.com/Calebh101/VC-MessageCorrector/blob/11371605787502633fdcb8226fb5b9a64435f805/index.tsx#L16
https://github.com/Calebh101/VC-MessageCorrector/blob/11371605787502633fdcb8226fb5b9a64435f805/index.tsx#L83
also why
index.tsx: Line 68
if (enabled) logger.log("Started in " + (debug ? "debug" : "standard") + " mode");
index.tsx: Line 72
if (enabled && debug) logger.log("Stopped");
index.tsx: Line 16
const enabled: boolean = true;
index.tsx: Line 83
predicate: () => enabled,
https://github.com/Calebh101/VC-MessageCorrector/blob/11371605787502633fdcb8226fb5b9a64435f805/index.tsx#L80
why are you using\w+here instead of\itwice
index.tsx: Line 80
match: /(\i)=\(0,(\w+)\.(\i)\)\(\{messages:(\w+)/,
https://github.com/Calebh101/VC-MessageCorrector/blob/11371605787502633fdcb8226fb5b9a64435f805/index.tsx#L33
why do you have a command to toggle your plugins' setting
index.tsx: Line 33
const commands: Command[] = [
https://github.com/Calebh101/VC-MessageCorrector/blob/11371605787502633fdcb8226fb5b9a64435f805/index.tsx#L63
this will error if someone tries to install it as a userplugin
index.tsx: Line 63
authors: [Devs.Calebh101],
also what is even the point of the plugin
Cuz I didn’t like always having the timestamps on, and I didn’t like going into settings to turn them on to check if it’s reordering correctly
Oh
Uh, how would I fix that lol
Debugging
put the value you put in the devs constant into the array
When I was trying to fix some weird issues, like random crashing
I was testing if MessageCorrector was causing it
I can remove them if they’re not preferred
Kinda hard to explain, but basically, when Discord receives a message into its stores, it just kinda accepts it ig. So it doesn’t matter if you just sent the message, or someone else. But that creates some inconsistency, cuz if you send a message right after someone else, on your client it’ll show that your message is first, even though it’s not on the server. I’ve found myself restarting the client a lot because of this, to check where my messages were “broken up” if that makes sense. MessageCorrector reorders the messages based on the timestamp property, which represents when the server received the message; not the client.
Does that make sense? It’s a bit hard to explain and I’m not the best at explaining lol
TLDR is discord client sucks, this fixes a small issue with it
I think it fixes when it looks like you sent a message before someone else on your client, but you actually didn't (and when you refresh it'll be fixed)
Yeah exactly
not the worse plugin idea i can see the use-case in this
I personally find it rly useful, idk abt yall tho
this seems kinda niche, so it would be a good fit for #1256395889354997771
just address the messages above
everything niche in vencord plugin submissions lowk
Alr I removed some debugging stuff,
Replaced \w+ with \i
I didn't remove the command cuz I find it helpful tho
I changed the devs field to not use constants
Anything else yall see that I can improve?
Original message: #🧩-plugin-development message
these days the only plugin submissions we get are ai garbage
Finna change that fr 👍
Questify is purely human garbage
-# this message is brought to you by GitHub Copilot

would this be too sketchy or does it work
oh my god just define yourself as a plain object
tbf it isn't exactly like a ton of new plugins are being added to the list of supported plugins. I mean, Vencord has BD beat in terms of stability and performance, but chances are, if you can think of it, there already is a plugin for it on BD.
Just by nature of the way vencord's plugin onboarding works, it invites people to use AI to build plugins that add the niche thing people want.
Doesn't make it easier but it does explain it.
Stuff like this, seems small and niche, but actually I'm curious why it isn't possibly a silent function of vencord itself. Like this seems less of something that belongs in a plugin and more something that belongs as part of the core functionality of the project itself as a bugfix for the client itself.
nah there would be someone that notices and complains lol
think it's fine in a plugin, maybe default enabled would be a discussion? but i would probably lean towards no
I was just playing around with it, that’s why I asked
The snippet does say to add yourself to the devs constant iirc
this is ai gem
K so after undoing this lol, I'll prob make a PR some time in the next few days cuz I think my plugin's ready for that
i think i agree with the other guy saying it shouldn't be a plugin but rather built in by default
that'd make more sense
for its functionality and stuff
I'm thinking of PRing it yeah, and including that if it's deemed a good idea it can be made built-in
Cuz you can define a plugin as builtin/required really easily so yeah
Making it built-in makes sense
as of now plugins shouldn’t be enabled by default, none of them are just because they’d be useful for a majority of people
imo
this is planned as "tweaks"
it would be a separate settings page with a bunch of categorised small tweaks
all very simple plugin that basically just change one small feature without settings would be changed to a switch there
Things that are objectively useful would be enabled by default, everything else disabled by default
for example BetterRoleContext makes an objective improvement to the role context menu without downsides so it could be enabled by default
So... sorry if I'm dum for asking, but since you kinda made vencord lol, what would you suggest I do with my plugin before PRing it? Make it built-in, enabled by default or both?
The 2 settings I have for it aren't really necessary to show to the user if I need to hide them btw
will you have usertweaks
That's a solid idea.
Oh tweaks doesn't exist yet
Well uh
sry for the unrelated ping
I genuinely have no idea if I should make this builtin, enabled by default, both, or neither lol
probably just make it a normal plugin
<@&1073655264923881602> well technically betterrolecontext has settings (which like 2 people change probably)
why the fuck is there an @ silent role

funny
looks vibecoded
has too many comments
yeah they said it's ai
@hushed loom
can someone archive everything from this year's Discord April Fools?
like the images and the css of it, i wanna do an port of every Discord April Fools to this day, and i wanna make them work again
it's alot more than just css and images lol
There are chrome extensions to take snapshots of web pages
ik ik
I submitted a PR to the FakeNitro plugin a few months ago:
https://github.com/Vendicated/Vencord/pull/3993
Wanted to ask what the process with PRs was and if I had to do anything or if "unsolicited" PRs are always ignored (instead of closed?) without any comment?
I have it running locally and it works fine but just noticed the PR still had no response etc.
Thanks a lot!
PRs are either looked at immediately or within a few months to years
just leave it opened and wait
if your pr is bad it gets instantly closed
I see thanks for the response!
Good to know how you all do stuff around here.
See you in a few years ig 😂
if your pr is really bad such as ai slop it gets instantly closed. if it's your average brand of bad then you gotta wait like normal, maybe get feedback one day, address the feedback, then wait another few months to years
Yea understandable.
I couldn't care less if my contributions get accepted, did it mainly for myself as I was missing that feature, so
. But now I know for next time to not bother, thank you!
eh when you get a pr review it goes quite quickly from there
i dont know if this is intended, but when using the platformIndicators plugin vesktop users get detected as web users probably because of how vesktop is built
It is indeed intended
i found this method in mediaEngineStore, and im wondering if there is any way to make this always return false. im trying to mute that notification that shows up when ur mic is picked up while muting
this was my attempt, i based the patch off of https://github.com/nicola02nb/notifyWhenMuted/tree/main
i saw that you can mute it with css, but i also read that the tag changes from time to time so im trying to make it more permanent
You're replacing the whole string getSpeakingWhileMuted(){return \i with something else which causes a syntax error
Try writing the regex in the patch helper, it will warn you when that happens
Lmao I forgot I had this nitro profile picture
ayyyy i think i got it
find: "getSpeakingWhileMuted(){return ",
replacement: {
match: /(getSpeakingWhileMuted\(\){)(return) (\i)/,
replace: "$1return false"
}
}```
can someone fact check me. since enabling the plugin i haven't been able to trigger the tooltip
Has there been any mentions about messagelogger not being able to log components v2?
Can i convert Message <-> api defined json??
you can get this from a message. not sure what you mean by api defined json
{
"type": 0,
"tts": false,
"timestamp": "2026-04-13T15:47:52.791000+00:00",
"pinned": false,
"mentions": [],
"mention_roles": [],
"mention_everyone": false,
"id": "1493276548047044911",
"flags": 0,
"embeds": [],
"edited_timestamp": null,
"content": "Can i convert Message <-> api defined json??",
"components": [],
"channel_id": "1032770730703716362",
"author": {
"username": "dittonut",
"public_flags": 256,
"primary_guild": null,
"id": "917369499597033502",
"global_name": "디또넛",
"display_name_styles": null,
"discriminator": "0",
"collectibles": null,
"clan": null,
"avatar_decoration_data": null,
"avatar": "edea47e5f68cf4616e873ab08e1313b8"
},
"attachments": []
}
is there a good way to hide a setting if anohter one is checked
I'd like to make my chat bar button appearance to change depending on the content of the chat input box, is there an easy way to get a reactive version of the chatbox content?
isnt it just a modal now
thanks