#🧩-plugin-development

1 messages · Page 84 of 1

eternal sparrow
#

I guess it makes sense

#

Gonna try that later

green vessel
#

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

cedar olive
#

but I doubt that would work

green vessel
#

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

cedar olive
#

they probably have it hardcoded to only work with https urls

green vessel
#

That is where my confusion is coming from if it supports b64 why not a blob??

green vessel
#

I am an idiot ignore anything I said 😭

cedar olive
#

did you get it to work

green vessel
#

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 thumbsup

grand haven
#

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 :/

bleak falcon
#

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

green vessel
#

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

normal wagon
#

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

eternal sparrow
#

and yet another silly question teto_sillyhat
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

humble tulip
#

Would it be easier just to spoof the deafening by setting your output volume to zero?

quick zephyr
#

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

hardy adder
#

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

quick zephyr
#

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

hushed loom
hardy adder
#

could a "view" be spoofed in theory

quick zephyr
#

messageloggerenhanced shows images so probably

hardy adder
#

oh whaa what’s that

quick zephyr
#

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

hardy adder
#

if i click the channel fast enough yeah but i think if you get it first hand, it stays around much longer

quick zephyr
#

get it first hand?

hardy adder
#

like if you view it before it’s deleted

quick zephyr
#

yeah cause your client caches it

#

im assuming they dont get cached the other way around

hardy adder
#

what’s “message logger enhanced”?

quick zephyr
#

userplugin

hardy adder
quick zephyr
#

guess it's not posted in there

eternal sparrow
eternal sparrow
quick zephyr
#

that is also obnoxious

eternal sparrow
#

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

normal wagon
#

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 😭

cedar olive
valid portal
#

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

#

💔

quick zephyr
#

oh but this is a client side thing not api

#

so it would be fine actually

quick zephyr
valid portal
#

wait hold on thank you sm wtf

quick zephyr
#

that just calls the dispatch for you. saves like 2 lines of code total lol Shrug

valid portal
#

might be able to help me figure this out

#

i got so low i was consideringf a CSS implementation 💔

quick zephyr
#

do you have the dev tools debugger enabled

valid portal
#

uhhhh

#

wdym

quick zephyr
valid portal
#

i don't think i do

#

yeah i do

quick zephyr
#

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

valid portal
#

oh thank you wtf

quick zephyr
#

button here if it wasnt clear

valid portal
#

dude this wouldve been so helpful on the zipPreview stuff 💔

#

wish i knew about this sooner LMFAO

quick zephyr
#

only useful tab there really is dispatcher in my experience

dull magnet
quick zephyr
#

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

valid portal
#

thank you bro

quick zephyr
signal goblet
quick zephyr
#

read

signal goblet
#

oh

valid portal
#

is this even a good idea to make it so you can apply newGuildSettings to any server even if ur already in it

quick zephyr
#

why not

signal goblet
#

if vee wants ill pr

valid portal
#

so it isn't restricted to JUST new servers

valid portal
quick zephyr
valid portal
#

also works from this area too

quick zephyr
#

thats already how it works right

valid portal
#

no

#

it only applies to NEW servers

#

this just makes it so you can apply it to a server you already are in

quick zephyr
#

if you right click a server is there not a "Apply NewGuildSettings" option?

#

have I been equicorded again

valid portal
#

i'm pretty sure there isn't

#

once applied

#

then disabled

#

so u can easily go back to ur original notification settings

quick zephyr
#

shows as merged

valid portal
#

whar

#

i swear the feature wasn't there before

#

ok nvm then

quick zephyr
#

bro has dementia

valid portal
#

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 💔

quick zephyr
#

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

valid portal
#

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

analog lintel
#

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

quick zephyr
#

you pray

analog lintel
#

And my PR for the plugin didn't get pulled

#

I sent it in like 3 months ago

quick zephyr
#

give it another year or two

analog lintel
#

Is there no way to speed it up?

#

I can't handle all these DMs :/

quick zephyr
analog lintel
#

I got one just now

quick zephyr
dull magnet
#

^

#

your documentation is very lacklustre so you can't really be surprised

analog lintel
#

Mine?

analog lintel
#

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 :/

quick zephyr
#

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

analog lintel
quick zephyr
#

Well your installation instructions in your repo aren't even right

analog lintel
#

I get that I should add some documentation but that really wasn't the original goal of the plugin

analog lintel
#

Tell me where I'll fix it

quick zephyr
#

Place it in your Vencord plugins/ folder.

#

Only official plugins go there.

analog lintel
#

That's mb

#

Ill remove installation instructions and just point it to the docs I guess

quick zephyr
#

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

hoary pilot
#

your plugin is also broken

it references a Devs entry when you’re not a contributor

#

unless i’m wrong

analog lintel
hoary pilot
#

yeah i guessed

but it makes it unusable as an unofficial plugin

quick zephyr
#

userplugin*

analog lintel
#

I meant for it to be an official plugin. Unofficial is unintended for me

quick zephyr
#

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" ...

analog lintel
#

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

analog lintel
quick zephyr
#

you also put credit to yourself as a header in the message search model SKULL_SKELETON

#

and ignored dolfies comment about using discord's message component to render messages

analog lintel
quick zephyr
#

gonna let you in on a hint, this won't be merged even if you waited a decade with how it is rn

analog lintel
#

Hold up one sec

analog lintel
hoary pilot
#

it probably won’t be merged altogether since that’s becoming an official feature

analog lintel
analog lintel
#

I'll try to make a PR after my exams finish

clear parcel
#

don't put any more time into this gng

#

it became a vanilla feature

analog lintel
#

Waaahhh I wanted a vencord badge :(((((

#

Guh and also to have a cool plugin

quick zephyr
#

saw that get pinned then removed in real time

hoary pilot
#

i unpinned because i forgot this channel’s pins were reserved for meaningful things

quick zephyr
#

what is the meaning behind this pin lol

analog lintel
#

Hall of fame 💪

hoary pilot
tropic ice
hoary pilot
#

no that’s X DMs

tropic ice
#

oh, twitter?

hoary pilot
#

no X

#

it’s not twitter anymore ykyk

analog lintel
analog lintel
#

very sharty app but meh

tropic ice
hoary pilot
#

and me

vast karma
tropic ice
#

wow so nin0 isn't worth listening to, ty

valid portal
#

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.

elder forge
#

How can I get the most recent DM message in a specific DM-channel using the userID?

royal ginkgo
#

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.

humble tulip
#

In onBeforeMessageSent you can return { cancel: true } and then create the new message with the upload and send that instead

royal ginkgo
#

How do I use onBeforeMessageSent (I am new to vencord plugin development)

royal ginkgo
#

Figured it out. Now how to I send a message with attachments

acoustic echo
#

How do I use the pre-existing components? more specifically the clan tag.

green vessel
hoary pilot
#

then you get the react function for the component

acoustic echo
hoary pilot
#

see how its used

dull magnet
#

react devtools

#

and read code

signal goblet
#

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

humble tulip
#

Dumb question but you don't have this enabled do you?

#

In notification settings

rapid crag
#

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

dry reef
#

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?
silk sorrel
#

are you using VencordNative.pluginHelpers.HelperMenu to access the native.ts exports?

dull magnet
dry reef
#

Even with an empty native.ts, it's throwing this error

signal goblet
signal goblet
dry reef
#

Nope, my index file is in JSX though. That shouldn't be a factor though right?

dry reef
#

Welp, that was the issue 🤣

#
              for (const file of ["index.ts", "index.tsx"]) {
royal ginkgo
#

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)
dry reef
#

For addMessagePreSendListener(), when I return {cancel: true} how do I clear the message text box?

royal ginkgo
dry reef
#

Also, that just sends an unecessary request to the Discord API

royal ginkgo
#

ah, fair

humble tulip
#

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

dry reef
#

Otherwise, it still stays as the old text

humble tulip
#

Even better, there's a CLEAR_TEXT event, just dispatch that

dry reef
#

Yes, just found it now

#

Thanks.

royal ginkgo
#

How do you dispatch a event?

royal ginkgo
#

when I do `FluxDispatcher.dispatch({type: "CLEAR_TEXT"}) I get a error that clear_text is not a event

humble tulip
#

But without the rawText and plainText

royal ginkgo
#

Thank you

humble tulip
#

Discord chickened out of letting you put newlines in commands because of mobile ux or something

quick zephyr
#

commands v2 my beloved. :(

azure fossil
azure fossil
#

By copypasting text with newlines

humble tulip
tropic ice
#

i'm counting on it

vast karma
humble tulip
#

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

azure fossil
#

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

humble tulip
#

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

azure fossil
humble tulip
#

Ah yeah, that works too

azure fossil
#

Basically i do what i can without space, ^a, ^x, edit in notepad++ then paste back

humble tulip
#

Took me ages to figure out yesterday though, I was trying to find where commands blocked the input

azure fossil
humble tulip
#

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 suffoPeepoShrug

azure fossil
#

...

#

I can't make UX good so i'll make no UX and not leave an option

#

Thank you...

humble tulip
#

Pretty much

humble tulip
#

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

eternal sparrow
# eternal sparrow and yet another silly question <:teto_sillyhat:1356748881152442449> how does Dis...

I've been trying for 3 days INSANESHUMO

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 KitaDefeated

cedar olive
#

😭

#

inspect the deaf button onClick

eternal sparrow
#

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

cedar olive
#

yes, so check the listeners more carefully

#

search for AUDIO_TOGGLE_SELF_DEAF:

silk sorrel
#

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
cedar olive
#

hacky tho

eternal sparrow
#

that would mean basically rewriting the deafen button's logic tho

silk sorrel
#

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

eternal sparrow
eternal sparrow
#

like this would make 100% sense but o is always null

quick zephyr
#

@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
dull dagger
#

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

hushed loom
#

I would look into the volume booster patches as a starting point

dull dagger
#

the discord side seems pretty feasible if not a little hard but obs is gonna be a pain

hushed loom
#

yeah

dull dagger
hushed loom
#

idk how you get the audio out of discord

dull dagger
#

im uhh

#

currently thinking i do audio routing for each user with pipewire

#

but thats linux only

hushed loom
#

tbh i'd do a POC with a simple electron app before i did it in discord

dull dagger
#

just gotta make an obs plugin that dynamically captures those pipewire sinks or whatever they are called and assigns them to an audio track

dull dagger
#

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

quick zephyr
#

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.

silk sorrel
quick zephyr
#

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

silk sorrel
#

Hmm

quick zephyr
#

the error it always gives me is 1009 Unable to ensure client is up to date

#

but I literally re-cloned today so

silk sorrel
#

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

humble tulip
#

You're probably staying in a breakpoint too long and disconnecting from the gateway I think

quick zephyr
#

I dont have any breakpoints

#

oh them

quick zephyr
#

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

humble tulip
#

@hushed loom

#

He'll probably read this back anyway

quick zephyr
#

bro ignored my friend request and my ping about it here so I think he hates me actually

humble tulip
#

Understandable suffoPeepoMischief

#

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

quick zephyr
#

sadan's recent changes have been pretty goated

humble tulip
#

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

hushed sable
#

How do i make a plugin which sends skibidi message to everyone in discord the moment i open roblox steal a brainrot

quick zephyr
#

do you go around dming people about skibidi brain rot

hoary pilot
hushed sable
#

Wait

#

Im still here

#

??

hoary pilot
quick zephyr
#

massive oversight

hoary pilot
hushed sable
hoary pilot
#

ask satan

#

@hushed loom

hushed sable
#

@hushed loom huskein pls tell me how make skibidi plugin

quick zephyr
#

now bro is gonna ignore suff's ping cause it looks like part of the nonsense

humble tulip
humble tulip
#

Don't know til you try

hushed sable
#

Aight brb

#

It didnt send skibidi u lied

humble tulip
quick zephyr
#

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

hushed loom
quick zephyr
normal wagon
quick zephyr
#

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.

cedar olive
#

how does only the latter work

quick zephyr
#

the former causes errors on startup

#

let me get a specific one

cedar olive
#

they both do the same

quick zephyr
#
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
cedar olive
#

first is a path alias

quick zephyr
#

only get this when importing from @webpack

cedar olive
#

the second is a path relative to baseUrl

#

because baseUrl is src, when u do webpack it's just doing src/webpack

#

iirc

quick zephyr
#

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

cedar olive
#

yes

#

exactly what I said

#

index.ts exports everything from webpack.ts

quick zephyr
#

so you're saying I shouldn't be getting the error I'm getting

cedar olive
#

now why it doesn't work, probably some circular import

#

you can use debugger on discord to see if it's a circular import

quick zephyr
#

how do I do that

cedar olive
#

breakpoint where you do the import or where you use the function

#

it's hard to explain tbh

hoary pilot
quick zephyr
quick zephyr
#

that'd be pretty useful NODDERS

#

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..."

quick zephyr
#

is "Open in Patch Helper" supposed to open a file with the module just like View Module

hushed loom
#

it opens the module to the side, any changes to the patch will be updated in the module

quick zephyr
#

uh is it supposed to be live? I dont see changes unless I click the button again

#

nvm suddenly working

quick zephyr
#

useful thanks

eternal sparrow
#

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

eternal sparrow
#

I deleted all of them and it's still working the same BocchiDeadBocchiDeadBocchiDeadBocchiDeadBocchiDeadBocchiDeadBocchiDeadBocchiDeadBocchiDeadBocchiDead

dry reef
#

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

eternal sparrow
#

FINALLY FOUND THE FUNCTION

#

AFTER A WEEK

#

I used to pray for times like this

#

dumb patch but for test purposes only

quick zephyr
#

I feel like I tested that and it didn't work but maybe I'm misremembering

eternal sparrow
#

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?

cedar olive
#

they mentioned the exact function you found

eternal sparrow
#

a wait

eternal sparrow
#

and now even better, stuck on removing the undeafen logic from the mute button

#

which works completely different

dry reef
#

For commands, if I add an attachment as an option, how do I actually access the uploaded file?

normal wagon
#

when jumping to a message from inbox, how would i detect that i'm jumping from there?

silk sorrel
#

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

eternal sparrow
#

but not giving up

#

schizo till I make it

eternal sparrow
#

I give up BocchiDead

azure fossil
#

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 ?

azure fossil
# hoary pilot wrong channel

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

normal wagon
#

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

silk sorrel
#

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");
rare glade
#

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

humble tulip
#

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()

rare glade
#

aight thanks a lot ^u^

quick zephyr
#

Vencord.Webpack.findStore("SelectedChannelStore").getChannelId()

humble tulip
#

Oh yeah, DMs wouldn't be in GuildChannelStore lol

quick zephyr
#

damn this store is so ass

#

has duplicate functions

dull magnet
#

no?

quick zephyr
#

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

dull magnet
#

nope they're different

quick zephyr
#

if you pass arguments they do dif things

quick zephyr
#

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 🤔

hoary pilot
quick zephyr
#

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
hoary pilot
#

idk trolleyzoom

quick zephyr
#

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 🤔

hoary pilot
#

DiscordNative exposes its natives in renderer

#

so you cannot call discordnative from vencordnative

quick zephyr
sly quiver
#

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

silk sorrel
#

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

leaden fable
#

Any idea how to get guildid from VoiceState?

dull magnet
#

show code

frigid aspen
#

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.

hushed loom
frigid aspen
#

How does one impliment that?

hushed loom
#

VencordNative.csp.requestAddOverride

#

grep for requestAddOverride in the code to find it's usage

frigid aspen
#

thx so much :3

hushed loom
#

np

quick zephyr
#

can someone try enrolling in a quest on canary and let me know if it 403's in the network tab

#

canary specifically

frigid aspen
#

yes

quick zephyr
#

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

frigid aspen
quick zephyr
#

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

quick zephyr
#

the copy value button doesn't work. only the store as variable one does. is this an electron issue or soemthing else 🤔

hushed loom
dry reef
#

Does anyone know what's causing this? Just copped a Macbook and it's showing this

#

Building works fine.

normal wagon
#

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

dry reef
#

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

tranquil hemlock
#

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)

dull magnet
tranquil hemlock
#

I restarted vesktop,
quit vesktop then opened it again
rebooted my computer and opened it

to no avail

dull magnet
#

also there are web encryption apis so you shouldnt need a native

tranquil hemlock
dry reef
#

Do presend listeners just not work on Macbook?

tranquil hemlock
humble tulip
#

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

tranquil hemlock
dull magnet
#

you're probably not building, or using the wrong vencord

#

or it's erroring somehow

tranquil hemlock
#

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)

tranquil hemlock
dull magnet
#

show your code

tranquil hemlock
#

alr I'll just upload it to github in a sec

tranquil hemlock
tranquil hemlock
dry reef
tranquil hemlock
#

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

dry reef
#
    onBeforeMessageSend : (_, message) => {
        return;
    },

Appreciate your help bro, somehow this line alone made the listeners functional again 🤣

#

@tranquil hemlock

tranquil hemlock
#

epic, nice it worked

tranquil hemlock
#

I made a quick userplugin, is there a channel in this discord where I can post it?

humble tulip
tranquil hemlock
#

oh nice

#

thanks

hardy adder
#

yo has anyone else seen platform indicators show a platform (usually idle mobile) when a user is actually offline

#

ctrl+R fixes it

zealous tiger
hardy adder
#

hm, like to offline? it doesn't seem to change for me unless they come back online (or idle)

zealous tiger
#

yeh its really wacky but if i leave it long enough it just goes to offline with no platform indicator present

hardy adder
#

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

hardy adder
#

hm

silk sorrel
# hardy adder react moment

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 😭

hardy adder
#

how do i check the commit im on, just in case

dull magnet
#

/vencord-debug in #🤖-bot-commands

cedar olive
#

I experienced it too

silk sorrel
cedar olive
#

perhaps presence store is not updated when a user becomes offline

#

seems weird but I dont see how else it would happen

hardy adder
#

generally it works when someone goes invisible or turns off their pc or closes their browser i think

dull magnet
#

should investigate further

cedar olive
#

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

#

😛

hardy adder
#

i have someone in that state right now if you want me to check anything

late jolt
#

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

humble tulip
#

Translate should have one

humble tulip
#

I misunderstood, I thought you wanted to add an item to a the context menu on a message

quick zephyr
#

this perhaps

tranquil hemlock
#

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

vast karma
tranquil hemlock
hoary pilot
#

@fallen sandal review

tranquil hemlock
#

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

#

don't see any other option

#

it's actually really nice for private conversations

humble tulip
#

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

rough sage
#

in the asar bundle?

vast karma
#

The names, for all intents and purposes, do not exist

#

Which is why you can't match on them and should instead use \i

rough sage
#

sorry If I'm asking alot of questions, there isn't alot of spesific docs yk

vast karma
#

It expands to something like (?:\b\w+\b)

#

The exact expansion isn't important; it matches a variable name

#

Yes

humble tulip
#

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

covert nimbus
#

is there a way to add a global keybind (aka a keybind that works outside of the discord window) that calls an arbitrary function?

iron epoch
covert nimbus
hardy adder
#

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)

cedar olive
hardy adder
#

never seen that lul

#

always been mobile

#

but my sample size is like 2 or 3 and i cant replicate the behavior myself so

cedar olive
#

just set urself to invisible lol

hardy adder
#

it works properly for me

tranquil hemlock
#

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

hoary pilot
#

is there a way to add the mana effect to the new buttons @components/Button

#

or whatever its called

dull magnet
#

but why lmao

#

i added it for the memes but it's ultimately useless xD

hoary pilot
hoary pilot
#

-# # @hushed loom

#

how do i grab for example channel context menu and put it on some element of my choice

silk sorrel
# hoary pilot how do i grab for example channel context menu and put it on some element of my ...

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

upper vessel
#

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

cedar olive
#

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

upper vessel
lime haven
#

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?

upper vessel
humble tulip
#

Or getIntlMessageFromHash if you have the hashed key

dull magnet
upper vessel
#

That will be the primary method, it seems that it’s possible to do in-client as well similar to I think decor

cedar olive
#

depending on what u do it will do more requests and more traffic

upper vessel
#

It prefetches all the images?

cedar olive
#

huh

upper vessel
#

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

ripe smelt
#

is there a way to expose webUtils.getPathForFile to a plugin without modifying Vencord files such as preload.ts?

dull magnet
#

oh

#

why do you need that

#

what would you do with the path

ripe smelt
#

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

dull magnet
#

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

ripe smelt
#

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

dull magnet
#

what would you even do with the full path in the renderer

ripe smelt
ripe smelt
#

which is

const stream = fs.createReadStream(path);
dull magnet
#

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

ripe smelt
#

so just totally avoid having drag and drop functionality and keep it button/selector only?

dull magnet
#

yea

ripe smelt
#

I was afraid that'd be the case, but oh well

#

security matters more than convenience after all

dull magnet
#

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

ripe smelt
#

yeah I was thinking that, I'd just have to set a file size limit

quick zephyr
#

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.

quick zephyr
#

Ah, found the endpoint.

await RestAPI.get({
    url: "/collectibles-products/1282816431985004594",
})
#

wish there was a way to batch it

vast karma
#

Is there any plugin for exterminating the top bar or am I gonna have to make it myself?

hoary pilot
#

i'll exterminate you

hushed loom
hushed loom
#

Way too many edge cases

vast karma
#

I'll make one then

vast karma
#

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

hushed loom
hoary pilot
#

LBTM

#

vsp @vast karma

#

you can post now

vast karma
#

Thanks

violet hawk
#

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)

tropic ice
violet hawk
#

Well, that would be easy to do but I should be more specific that I wanted to implement so discord things into the camera.

zealous tiger
#

discord things being what exactly

violet hawk
#

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

violet hawk
#

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 */
}
tropic ice
violet hawk
#

I know, that’s why I said it would be client sided

modern oak
humble tulip
#

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

daring holly
#

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

Gist

Complete Recent Discord Quest. GitHub Gist: instantly share code, notes, and snippets.

daring holly
#

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 ?

broken cedar
#

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 PEPW

#

okay actually this might be an issue

#

searching for json2ts also does not locate it

daring holly
daring holly
broken cedar
#

yeah idk

daring holly
dull magnet
broken cedar
#

maybe its because im using code package for vscode? idk if that would affect the available plugins or not

dull magnet
#

they use a different marketplace that's missing many extensions

broken cedar
dull magnet
#

yeah

#

on arch?

broken cedar
#

ah

#

mhm

dull magnet
#

install this

broken cedar
#

got it ty

dull magnet
#

microsoft has cringe terms that only official branded (proprietary) vscode may use the official microsoft marketplace

#

so code oss doesnt use it

broken cedar
#

and this package gets away with it how..? lemmeThink

dull magnet
#

who cares about microsoft terms

dull magnet
#

anyway you really dont need that extension dw

#

it's just nice to have

broken cedar
#

lmao ok

#

thanks anyway tho

broken cedar
daring holly
#

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

broken cedar
#

@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

dull magnet
#

just make it a user plugin for the time being

broken cedar
#

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

tranquil hemlock
#

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

vast karma
#

That's not normal, no

broken cedar
#

should a plugin id just be determined at random or what

dull magnet
#

wdym plugin id

broken cedar
vast karma
#

That's your discord user id

dull magnet
#

your user id

broken cedar
#

i might be stupid

#

yeah okay that checks out

dull magnet
#

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

broken cedar
#

ooooh noted

atomic sierra
#

How can I add a button to the message right-click menu?

tropic ice
dull magnet
#

guys it's nothing like going to McDonald's

vast karma
#

It's like going to the hardware store and asking for a cheeseburger

atomic sierra
#

It's like doing create-react-app and expecting a SvelteKit project

broken cedar
#

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 FeelsDankMan

broken cedar
#

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

dull magnet
#

you dont need any patches

#

just add a context menu entry or smth

broken cedar
#

wanted to make so it would just

#

open vlc when attempting to play video

#

but sure context menu entry works i guess FeelsDankMan

#

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

#

but i am..?

#

src/userplugins/vlcWorkaround/native.ts:7:32:

#

oh wait im importing into the browser code wrong

tropic ice
runic wave
#

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 owoSadness

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 pls

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
});
dull magnet
#

you can't dispatch message updates like that

#

editing messages is difficult

runic wave
#

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.)

dull magnet
#

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

runic wave
#

Okay, thank you very much, I'll take a look gx_hug

dull magnet
#

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)

runic wave
meager palm
#

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

dull magnet
#

why

meager palm
#

because clicking on the avatar does absolutely nothing other than prevent me from reacting

#

like is that intended

dull magnet
#

it's supposed to open the profile

meager palm
#

oh so its a bug

atomic sierra
#

ok so how can i just add a simple button to the message right-click menu, it cant be that hard right?

quick zephyr
# atomic sierra ok so how can i just add a simple button to the message right-click menu, it can...

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.

humble tulip
#

Use the context menu API, have a look at how existing plugins like Translate do it

atomic sierra
#

ok thanks for telling me which plugins already do it that helps

humble tulip
#

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

atomic sierra
#
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?

cedar olive
#

unsure, it seems right

lime haven
humble tulip
#

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

lime haven
atomic sierra
#

i dont understand what that is, i am too dumb

#

sorry

dull magnet
#

don't mind them they're just wrong

atomic sierra
#

then tell me what the correct way is 😭

lime haven
#

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

#

🙏

atomic sierra
#

so what's the solution now

atomic sierra
#

ok i didnt change anything and the button appears now

#

thanks people

atomic sierra
#

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?

dull magnet
atomic sierra
#

i just use "copy-link" now

opal dock
#

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

dull magnet
#

you cant no, and you shouldn't

#

that's very insane design from them to allow any image url

opal dock
#

gotcha, and fair enough
I'll just keep my CspPolicies to allowing pluralkit's own domain and nothing extra

dull magnet
#

what you could do is use an image proxy

opal dock
#

I'll note that down and look into that at some point, thanks for the suggestion

hoary pilot
#

patch or something

quick zephyr
#

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 .-.

dull magnet
#

maybe one day I will port ipc commands from vesktop to vencord

quick zephyr
#

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 🤔

dull magnet
#

what is your use case

#

and why do you need to verify an svg

quick zephyr
#

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 🤔

dull magnet
#

why do you need to validate it though

#

what would be the harm in someone saving a malicious svg

quick zephyr
#

could you not just lie about it being an svg and instead have it be evil virus data

dull magnet
#

I really don't understand what you're trying to do

#

you can already send arbitrary files on discord and have users download them

quick zephyr
#

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

dull magnet
#

what are you making exactly

quick zephyr
#

still working on downloadify rewrite

dull magnet
#

which does what exactly

quick zephyr
#

adds downloads to a ton of context menus and adds context menus where there arent currently

dull magnet
#

does the download option just prompt the user to save the file by opening the file save dialog?

quick zephyr
#

it does unless they have a default dir set

#

then it just goes there

dull magnet
#

show your code

quick zephyr
#

you already yelled at me for how virusable this was in the ticket so im rewriting it lol

dull magnet
#

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

quick zephyr
#

ill just not validate svgs ig

dull magnet
#

there's no point validating svgs

#

you just mustn't embed untrusted svgs in html

quick zephyr
#

it's not arbitrary

#

anymore anyways

#

original it was

#

the location is decided in the download function now

dull magnet
#

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

quick zephyr
#
/** 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

dull magnet
#

it's the same risk as saving a html file

quick zephyr
#
/** 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

dull magnet
#

if you're just downloading discord svgs then there's nothing to worry about anyway

quick zephyr
#

well yeah but you could call it from command line with any args is the thing

#

hence the attempt to validate it

dull magnet
#

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

quick zephyr
#
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

dull magnet
#

just push to github

quick zephyr
#

will when closer to done. rewrite has like half the old code commented out lingering

dull magnet
quick zephyr
#

already gonna have to squash all my commits before pushing cause they're so ugly

#

yeah lol

dull magnet
#

security hazard meow_salute

quick zephyr
#

skill issue

hoary pilot
#

vee loves old UserpluginInstaller

dull magnet
#

one line sandbox escape into arbitrary code execution on the host system

quick zephyr
#

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 😭

dull magnet
#

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

dull magnet
quick zephyr
#

tell me how you really feel 😭

dull magnet
#

wdym

quick zephyr
#

it's an expression for when someone has ripped into you by being blunt with their thoughts

dull magnet
#

oh :p

#

I mean your rewrite is probably better

quick zephyr
#

it's made me even more aware of how annoyingly discord's assets are stores and served

#

nameplates and especially profile effects are pain

dull magnet
#

what's annoying about it?

quick zephyr
#

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

hushed loom
quick zephyr
#

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;
}
silk sorrel
#

kid named findByProps("getURL", "applyPlatformToThemedEmojiColorPalette").getURL("🥺")

amber mantle
gloomy terrace
jagged geyser
#

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

silk sorrel
#

Use @hushed loom's version of the dev companion, it's peak blobcatcozy

quick zephyr
#

real

jagged geyser
#

where does one find that?

quick zephyr
#

any specific component you're looking for?

jagged geyser
#

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

quick zephyr
#

neat the dev extras tab got its own button. no longer grouped with the bug button

quick zephyr
#

:)

#

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

quick zephyr
#
(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.

silk sorrel
quick zephyr
#

if it has the raw data available then it will be great

#

I only have 108 at the moment

#

and apparently im missing application data cause the claimed endpoint doesnt return that

#

it does have the raw data available