#🧩-plugin-development
1 messages · Page 53 of 1
name it section
you should be able to do it client side, but it won't show for other people
this is github not philosophy 101
is there some kind of api for message menu?
You mean for context/right click menus?
yup
Just grep for ContextMenu in existing plugins
Global apply to all menus anywhere; it's never used
i see
Non-global apply to those with a specific navId
is there a way to store a file seperate from settings?
Grep DataStore
do these save locally?
datastore uses indexdb
much similar to local storage
yeah DataStore is what you want
you can dump raw blobs/file instances in there
its awesome
theres no limit to the size, you can store gigabytes of data there
(but have fun with memory usage
)
you could probably dump your newborn in indexeddb and it would come out alive
lmfao
I think your plugin might not get merged if you store literal gigabytes without good reason
Unless the user (or the plugin) deletes it, it should
^
interesting
stored on disk
The message has the channel id
but i need guild id
Which is easy to get from channel
ChannelStore.getChannel(message.channel_id).guild_id
does datastore has something to check it a key exist?
await Vencord.Api.DataStore.keys().then(keys => keys.includes("<the key you want to check>"))
so im getting this error
index.ts:83 Uncaught (in promise) DOMException: Failed to execute 'put' on 'IDBObjectStore': The object store uses out-of-line keys and has no key generator and the key parameter was not provided.
not sure what exactly means
NO
there's a .has iirc
if not, just .get
"and the key parameter was not provided"
would it be a bad idea to add a custom route with a plugin?
so far from what I've been trying it's fine except it will 404 when I ctrl+r while on the custom route
I can't see why you'd want to
why would you do that
the other buttons are links to routes so I figured it'd be best to make a custom route to add a new button here
it seems to be working fine except ctrl + r doesn't like it
maybe I should detect ctrl r and change route to /app or would that be a silly temporary non ideal solution
so this is not acceptabled?
await DataStore.set(notebookName, {}, HolyNoteStore);
why should i not use custom store?
Hi guys!
Is there any way to install Vencord using a batch script with "silent" option?
Like this: powershell Start-Process "VencordInstaller.exe" -ArgumentList "/silent" -Wait
use the cli instead of the normal version
but the cli gives no option to silent install
i'm creating a post-install windows programs after new Windows installation
it literally does?
VencordInstallerCli.exe -install -branch auto
guh this so hard to explain without pictures but
since i should not use custom store how should i be able to get values from the notes
return await DataStore.values(HolyNoteStore);
i mean would i have to do it the traditional way of object.values()
Literally just grep how other plugins do it
@remote kestrel
grep?
You know, the singular most important tool for reading any codebase?
you can also use a custom store but it's more complicated
you can patch the router code to render your component
why is it normal
.eant to reply to this
Presumably that 404 is sent from discord's servers as response to the page load, not part of rendering
hater
nuh uh
Script:
@echo off
mkdir %userprofile%\Downloads\Post-install
set softwarePath="%userprofile%\Downloads\Post-install"
echo Installing Vencord...
powershell Invoke-WebRequest -Uri 'https://github.com/Vencord/Installer/releases/latest/download/VencordInstallerCli.exe' -OutFile "%softwarePath%\VencordInstallerCli.exe"
powershell Start-Process "%softwarePath%\VencordInstallerCli.exe" -ArgumentList "-install -branch auto" -Wait
PAUSE
Output:
I'm trying to make a plugin that enables friend nicknames regardless of if someone is your friend. I made a patch that makes it so the button appears, but if you try set a nickname is just doesnt. ```
{
find: "default.Messages.ADD_FRIEND_NICKNAME",
replacement: {
match: /d.default.isFriend(t)/,
replace: "true"
}
}
this is the patch i made, is it possible? or just downright undoable because of the api end
You need to find all other places where it uses those friend nicknames and remove the corresponding check there as well
Also don't hardcode variable names, use \i
make the request manually and see if it even works
I doubt it does without being a friend
Also that find hits two places
I believe it's the context menu and the modal it opens
It's so joever 😔
If you want only the context menu, perhaps ?"add-friend-nickname":"edit-friend-nickname"
Or just a user-context contextMenu
it doesnt matter it wont work
You'd probably have to implement a brand new client-side friend nicknames feature
Yup

why do you think it's called "friend nicknames"
css
What's the best way to show an alert before a user tries to send a message? i can't really think of a way to intercept it
ok ...await DataStore.values(HolyNoteStore) is something i need but every single time i get `
guh im fucking going to
I need to get { "Main": {} }
but i keep getting {"0": { "Main": {}, }, }
return { ...await DataStore.values(HolyNoteStore) } ;
Are you sure you're not supposed to use .get()?
Because .values probably returns an array of something
in get i need to use a key
Then do that
Store your whole object under that key
i wish i could show u a picture of what im trying to do
Do some magic with Object.fromEntries() if the DataStore object doesn't have some method for this.
Or just make a custom sortDataValues func that does this. If you don't plan to use it twice, just inline it.
Why is it that you need a custom store, which is something no other plugin does
ok im not sure what im doing anymore
maybe im doing something wrong or not but how can i make my noteHandler not use await
You cannot perform asynchronous operations synchronously
ok so
You can have a local, sync copy and have it asynchronously update datastore when edited
how would i be able to do this
Or you can use useEffect + useState to run stuff asynchronously and update when done
you're spreading an array into an object, that makes no sense
use the DataStore.entries() function
is there a way to actually show a example of what im actually trying to do?
can you listen for all flux events?
I am trying to find the automod rules without making patchs
Listening to flux events won’t help with that
I’m not sure if it’s possible with patches though cause that data is never on the client
Unless you have permission to view/edit auto mod rules
You could listen to MESSAGE_CREATE and gather a list of them but keeping track of deleted/new rules is tricky
Assuming you have perms for whatever channel auto mod goes into
I have the perms, and I don't think I need to keep track of changes, what i am looking for is getting the rules when they are fetched by the client
saw function called syncRules but doesn't look its dispatching anything or i am just blind
Look at the requests tab when you open the auto mod tab and see where the request is called
Then add a breakpoint and figure it out
add a breakpoint? good idea, I hate when I forget basic things
I want to subscribe to events on the BrowserWindow from a plugin that otherwise works without a native module
Just dropping a native.ts in does not work
Would making a plugin for native code and marking it as a dependency be a good idea?
wtfffffffff shit not working for no reason Thinkies
i forgot to restart the app
ok fuck i will admit i am still asking xy
W descriptive commits
(I was shortening some functions to be arrowed (they were only one line so 🤷♂️))
just do it by modifying the user store and saving it in the plugin settings as an array of ID's and nicknames, and load them into the user store at start-up
is there a way to clear everything from the datastorage?
There's a .clear method so I'd assume so
@balmy sky have you tried this? ^^
so ive reach a dead end not sure why but i keep getting undefined on this part of my code
https://github.com/Wolfkid200444/Vencord/blob/22def634add279dfc9133a2f2edc5cbef5db902e/src/plugins/holynotes/components/modals/RenderMessage.tsx#L49-L115
**src%2Fplugins%2FfakeAvatarDecorations%2Findex.tsx: **Line 81
FakeDecorationSection: ErrorBoundary.wrap(function () {
example for error boundary
oh, I think you missed a return there
im logging why is it undefined i remove the return but im logging render
you need to return it though
Function that does not return anything gives undefined. Hmm.
^^^
error boundary maybe?
example ^^^
you need to render it somewhere

Obviously
I was trying to make it work with friend nicknames though
Does <Flex/> not have align prop?
Not sure about vencords's, but discord's sure does
I don't know why vencord has its own instead of just exporting discord's
so what should i do?
Well, easiest is just style=
ok where the types
Right there in your autocomplete
// TODO - type maybe idk probably not that useful other than the constants
export type Flex = ComponentType<PropsWithChildren<any>> & {
Align: Record<"START" | "END" | "CENTER" | "STRETCH" | "BASELINE", string>;
Direction: Record<"VERTICAL" | "HORIZONTAL" | "HORIZONTAL_REVERSE", string>;
Justify: Record<"START" | "END" | "CENTER" | "BETWEEN" | "AROUND", string>;
Wrap: Record<"NO_WRAP" | "WRAP" | "WRAP_REVERSE", string>;
};
it gives me error trying to use Align
Type '{ children: Element[]; Align: string; className: any; }' is not assignable to type 'IntrinsicAttributes & { flexDirection?: FlexDirection | undefined; style?: CSSProperties | undefined; className?: string | undefined; } & HTMLProps<...> & { ...; }'.
Property 'Align' does not exist on type 'IntrinsicAttributes & { flexDirection?: FlexDirection | undefined; style?: CSSProperties | undefined; className?: string | undefined; } & HTMLProps<...> & { ...; }'.ts(2322)
(property) Align: string
yeah not align is not working
ok
is there any reason why my Flex has horizontal?
of all classes
flex_f5fbb7 horizontal__992f6 justifyStart__42744 alignStretch_e239ef noWrap__5c413 vc-notebook-flex
Probably you set direction to horizontal (or undefined)
cant be
<Flex className={classes("vc-notebook-flex")} flexDirection={Flex.Direction.VERTICAL} style={{ width: "100%" }}>
is correct
Isn't it just direction=
maybe u were right
there use to be some classes for emptyResultsWrap but it doesn seem to exit anymore i think i have idea on how to find them
actually
they exist
but they only appear when searching something on the search bar and not finding a result
nvm
is there somekind of api to add button where the hide member list button is?
also why are the DataStore.entries() like this?
[
"Shiggy Collection",
{}
]
is there no way to maybe get them like
[
"Shiggy Collection": {}
]
i figured this out but kinda sucks
im trying to add button on messagecontextMenu but it seems i cant add a button on a button
children.push(
<Menu.MenuItem label="Add Messagge To" id="add-message-to-note">
{Object.keys(await noteHandler.getAllNotes()).map((notebook: string, index: number) => (
<Menu.MenuItem
key={index}
label={notebook}
id={notebook}
action={() => noteHandler.addNote(message, notebook)}
/>
))}
</Menu.MenuItem>
);
**index.tsx: **Lines 122-143
<Menu.MenuItem
label="Unholy Multi-Greet"
id="unholy-multi-greet"
>
{WELCOME_STICKERS.map(sticker => {
const checked = multiGreetChoices.some(s => s === sticker.id);
return (
<Menu.MenuCheckboxItem
key={sticker.id}
id={"multi-greet-" + sticker.id}
label={sticker.description.split(" ")[0]}
checked={checked}
disabled={!checked && multiGreetChoices.length >= 3}
action={() => {
s.multiGreetChoices = checked
? multiGreetChoices.filter(s => s !== sticker.id)
: [...multiGreetChoices, sticker.id];
}}
/>
);
})}
or hmm
something you did wrong, but I'm not sure what
I know you dont want a checkbox item
nvm I see
you are once again trying to use async in a place where you can't
no way
please just cache your stuff in a variable and use that instead
you can have a allNotes variable which is a cache
when you update the datastore, also update the cache
and when you load your plugin, load the data into the cache
how do i make a cache
a cache is just a fancy name for a variable which contains the same stuff you have in your datastore
but already loaded into it
so you dont need to always request it again
let me show you an old example
see how ignoredActivitiesCache is used
it's worth it
requesting the datastore everytime is only going to bring issues
because it's async
I am adding a new feature for the MoreUserTags plugin, but for some reason when changing the name of any tag, it breaks with reading "ShowInChat" undefined. did someone tried to modify it before?
so i think im missing one more thing is that conextMenu when trying to switch like sort type and contextMenu when u right click on messages in notes
This one is weird since when i right click it instantly sends me discord.com browser
https://github.com/Wolfkid200444/Vencord/blob/79621f67ef4c778b5ee13e0d95ac5ca51c8b60b1/src/plugins/holynotes/components/modals/RenderMessage.tsx#L124-L150
**Notebook.tsx: **Lines 133-160
ContextMenuApi.openContextMenu(event, () => (
<>
<Menu.MenuItem
label="Ascending / Date Added"
id="ada"
action={() => {
setSortDirection(true);
setSortType(true);
}} /><Menu.MenuItem
label="Ascending / Message Date"
id="amd"
action={() => {
setSortDirection(true);
setSortType(false);
}} /><Menu.MenuItem
label="Descending / Date Added"
id="dda"
action={() => {
setSortDirection(false);
setSortType(true);
}} /><Menu.MenuItem
label="Descending / Message Date"
id="dmd"
action={() => {
setSortDirection(false);
setSortType(false);
}} />
</>
**RenderMessage.tsx: **Lines 124-150
return (
<div onContextMenu={e => {
ContextMenuApi.openContextMenu(e, () =>
<Menu.Menu
navId="holynotes"
onClose={() => FluxDispatcher.dispatch({ type: "CONTEXT_MENU_CLOSE" })}
aria-label="Holy Notes"
>
<Menu.MenuItem
label="Jump To Message"
id="jump"
action={() => {
NavigationRouter.transitionTo(`/channels/${note.guild_id ?? "@me"}/${note.channel_id}/${note.id}`);
closeModal?.();
}}
/>
<Menu.MenuItem
label="Delete Note"
id="delete"
action={() => {
noteHandler.deleteNote(note.id, notebook);
updateParent?.();
}}
/>
</Menu.Menu>
);
}}></div>
New chanel
O
Anyway, question,
in discord you can have 'intents' but when i import it using
import { Intents } from 'discord.js';
i get and error that it doesnt exist in my discord.js version, i keep uptating it and it always keep bringing this error,
the command i use to update it is
npm install discord.js@latest
is the command wrong, if so can you provide the new one? thank you
They have a server
yes
Are you aware that key={index} is literally what the docs tell you not to do?
ok
ok im finished
like the plugin works and everything "perfectly"
looks is something that can do better
but yeah
now to wait for next 5 months
Hey, I'm writing a plugin and I want to test it. I downloaded vencord and added index.ts in Vencord/src/userplugins/<PluginName>/, ran pnpm build, but it doesn't show up in discord, even after restarting
(Linux, Vencord installed from sh -c $(curl ...))
are you sure you're using your own build of vencord? you can do that with pnpm inject
nope, I wasn't, after using sudo pnpm inject it works well (sad there isn't a way to reload plugin without calling sudo each time tought, or that I don't know it)
you only need to inject once*
*except when discord updates and removes vencord
then you only need to build, or auto build on save with pnom watch
What pnpm inject does is that it patches discord to load vencord from your build directory
Not copy your current build into discord
ok, thx
is there a similar plugin to textReplace that edits (visually ofc) other users' messages when loading them ?
no
ok, is there any easy way to do so ?
make a plugin
Patching the message render function sounds fairly simple; probably want to inject something before it's sent to the markdown parser
actually you would want to make it an option in TextReplace
I'm trying to make a plugin that acts kind of like a middle man between discord's rich presence and applications so that they can have more control over it (specifically its name).
I was gonna make it use a websocket server but that doesn't seem to be possible to do from a plugin, what could I use instead?
Probably you'd hook into the existing rich presence handler, rather than making a secondary channel
Keeping those in sync sounds like it'd be a hassle
how would I do that? I don't know where to look
look at the CustomRPC source
yeah my plugin is based off of that, I'm able to spawn activities through it but I dont know how I would hook into the handler
is that a javascript thing I should look into?
maybe get the presence update event and modify it 🤔
@north flame I remember you said something about adding a new tab to the friends page, did you ever end up making that work?
not me
There was someone trying to add a new entry below the shops but ran into issues with the router
Hmm
No, I do remember somebody trying to remove the friends and shop tabs, but they got redirected to just use css
I kinda wish Discord had tabs like a browser.
I basically have a nasa computer, so I should be fine lol.
nop
because it's way faster than just switching channels or?
discord will still lag
No it is implemented literally just by switching channels
i have a 1990 nokia laptop 
XD.
Nokia make better phones.
bedrock phones
guys what's the difference between userplugins and Plugins?
userplugins are gitignored
Do you guys have any idea on how to resolve cors issues when fetching data?
Don't fetch stuff that doesn't allow it
Or I guess there's a couple of cors-stripping proxes out there
cors stripping proxies do not work 😦
This is what I've been trying to query
Im specifically trying to query the "rich presence"
💀
is there some kind of api for toolbar?
Check what the toolbox does
i mean i know what toolbox does but why is there no toolbar api
Because it's not common enough
That's how you do most things yes
Skill issue
Learn how to make patches, then make a toolbar API and make VencordToolbox use the new API
no
im not sure how to explain this but is something weird which i actually cant explain with words but can datastores cross with each other?
yeah i can access other plugin datastores thats not good
any way to prevent this?
ok, but u see, that can be a problem on my end if u have seen the picture
I have no idea what that picture depicts
The names show there are notes that people can store messages, but since it can access other plugin datastores, they show names from other datastores that users didn't create, leading it to breaking or erroing
what i ended up doing was creating custom store
Usually each plugin would have a single top-level key
And then you can put whatever you want under that
usually yeah
instead of creating a new store have a single top level item which is an object or array
very easy to fix
actually using a dedicated store is not a bad idea, although at that point you might want to manually manage your store so you can create an index and gain a huge performance gain
if you use a dedicated store with an index, you basically gain equivalent performance to an sql database
which would mean you could technically store millions of notes with no performance loss
this is also why i recommend usage of it for message logger enhanced
actually, i took inspiration from MLE for storing data stuff mostly
i don't think having such a plugin makes sense
discord will likely fix it soon
and just don't dm weirdos who'd use that
there's people willing to use it
#🏥-vencord-support-🏥 message

that's what I said as well
it's not ip logger
is it that worrying?

seeing javascript in jetbrains ide looks weird
it gives me java and c++ flashbacks
it's instantly clear for me
blocking vercel.app isn't a great solution
how is exposing ur ip to the person any better than exposing that u saw the message
it's even worse xd
wait, you use the whole content as url
me omw to send a vercel.app link to grab ur ip

wow this is a nice fucking ip did u make it yourself
horror
can we just add a plugin which requests every image directly to make ip loggers happy
because discord doesn't use that discordbot agent always
they have another user agent
"This is an intentional design decision, and is working as intended. when discord crawls a URL we perform that action as a bot. however, when we proxy images we are acting in response to a user loading that image. because of this distinction we provide a user agent of a user, not a bot."
night has not understood how user agents work
he could have just said "we don't want to be flagged as bot"
this is the other UA they use Mozilla/5.0 (Macintosh; Intel Mac OS X 10.10; rv:38.0) Gecko/20100101 Firefox/38.0
they can fix the read receipt problem by only using one single user agent from what i gathered
or always fetching the media even if you don't open it
huh?
it shouldn't matter
basically yeah
just don't do anything
why do you care if someone knows you saw their message
it's not that bad
and discord will probably fix it soon anyway just wait 
then why make plugin 😭
you could just disable embeds in settings
and it'll likely fix it
huh how
just use canary
Wtf lmao
is there a way to make this into a scrollable?
https://cdn.obamabot.me/bar.png
overflow scroll probably
thats uh css right?
why do you use img links that don't embed :(
look at my roles
.class {
overflow: scroll;
}
i made a quick memeish plugin how do i get it into #1032200195582197831
or smth
oh
How do you even get the brain rot role
dont ask
i guess this is success
https://cdn.obamabot.me/scrollabel.png
div {
overflow: auto;
}
should do it
Dm Vee about it
what does it do
could someone give me their opinion about this scroll thingy
not sure how it would look
https://cdn.obamabot.me/gray_bar.png
adds a slash command that turns your messages into this 𝓬𝓾𝓻𝓼𝓲𝓿𝓮 font
Why why is toad timed out lmao
Use an image host that doesn't suck and maybe people will be more inclined to look
catbox.moe 
sorry but got no embed perms
this is honestly the only way to show something
Lmao
I was about to say if every contributor has embed perms, but you have the “brain rot” so you don’t literally don’t have perms
In bed
bed perms
The server just has a bedroom you can eep in if you're a contributor
Shut up, I’m an American. I’m not good at English.
so true
this is honestly affecting me to get help
i think red scroll bar would look sick
Could consider an overflow menu like in devtools, too
interesting
sounds husktastic
@tropic raft gave role
thankyou
yeah this is the most huskworthy thing i've seen in a while
Mods, lobotomise this user
🧠🔨
i dont really know what possessed me to even make this
not sure if this is the correct module but im trying to find what react component they used to do this since they probably do right?
anyways i found this one
ResizeOrientation.VERTICAL_TOP
Just grep for overflowChevron_c06200
thats just a css class isnt it?
Yes, and finding that will quickly point you to the implementation
i mean i already found the implementation
plugin is coming along somewhat nicely, still learning how the RestAPI works in Vencord but other than that itspretty good
Trying to sort an array of {guildId, channelId}, I have sorted by guildId using ["@me", "@favorites", ...SortedGuildStore.getFlattenedGuildIds()]; then a comparator function of ```js
const agp = sortedGuilds.indexOf(a.guildId);
const bgp = sortedGuilds.indexOf(b.guildId);
if (agp !== bgp) return agp - bgp;
Is there a proper way to then further sort by channel order shown in the sidebar?
I have been looking at GuildChannelStore.getChannels(guildId)
It has some weird keys
anyone know why this gives me an error? It's supposed to get the webhook's username but instead it errors out.
await RestAPI.get({
url: "" + findOption(option, "url")
}).then(response => response.json())
.then(response => {
sendBotMessage(ctx.channel.id, {
content: "Webhook Information: \n " + response.name + "\n "
});
});```
TypeError: o.json is not a function
at VencordRenderer:218:33702
at async Object.execute (VencordRenderer:218:33657)
at async handleSendMessage (WebpackModule176347:2:7059)
shitcode
do not use the RestAPI module
it returns something else
use fetch()
alright
Does anyone any idea on how to fix the dead Vencord “ contributor” and donor links on this plugin. I reached out to the Devs of it and honestly I know one was banned (ryan), I haven’t seen any of the other one (Shalev), and I’m not too sure about the second one(fres)
(honestly I probably just need to be patience and see if they get back to me)
contributor: cdn link expired. you need to use a different url
badges: moved to https://badges.vencord.dev/badges.json
anyway you should not manually fetch these
just make the badge api plugin export them and import from there
That sounds like beyond my skill level right now
so I need to find a way for this plug-in to read .json files is the problem
got any idea to a more permanent solution to the contributor badge so it doesn’t expire
?
wdym
do you think an imgur link would fix the problem of cdn links expiring
unless it’s just my computer being shitty like it normally does for some reason some donor badges don’t render
those badges that aren’t loaded in are the letter badges
An imgur link would fix the vencord contributor badge, but I honestly don’t know what to do about the donor badges
am I even allowed to use imgur links?
was not aware that there was a BadgesAPI
Also, where does one find it?
nvm I was just being stupid and overlooking it
I switched to using fetch() and now I'm getting the error "Object literal may only specify known properties, and 'webhookthing' does not exist in type 'Request | URL'."
var webhookthing = findOption(option, "url");
await fetch({ webhookthing }).then(response => response.json())
.then(response => {
sendBotMessage(ctx.channel.id, {
content: "Webhook Information: \n " + response.name + "\n "
});
});```
I had done this previously in JS+HTML and it worked fine, so I don't know what's causing it since the wording on the error is a little funny
Aren't you supposed to give it an url
oh shit i forgot to fully put the code
it should just get the value of the url command and then input it in fetch
fetch() does not know any webhookthing parameter
okay you need to search the docs for the fetch api
quick search and you will know what you are doing wrong
Could it be that you are not aware that { foo } is shorthand for { foo: foo }?
oh
wait
ok yea i think that solved part of it
didn't notice i had curly braces inside
alright i think i fixed it
just a silly oopsie on my end
got it
i don’t know how to use the BadgesAPI, what do i import and how do i get the code to read it
(I’m honestly kind of stumped)
(also sorry i’m still new to this)
Is there a flux event to handle file downloads?
I just wanna rename them before saving
Actual lifesaver, thank you
in my video you can see its already patched by the "WebContextMenus" plugin but you can just add ur own patch with ur own plugin, as long as you make sure they are compatible

i’m going to give up on this for today and try again tomorrow (since it 11:30pm for me) but if anyone wants to help me do this since I’m new to this please let me know or Dm me
u think is posssible to find what kind of component discord is using in this code?
(h, {
id: t,
selected: r === t,
ref: e=>{
var r, a, n;
let i = null !== (a = null === (r = m.current.get(t)) || void 0 === r ? void 0 : r.width) && void 0 !== a ? a : 0;
m.current.set(t, {
node: e,
width: null !== (n = null == e ? void 0 : e.getBoundingClientRect().width) && void 0 !== n ? n : i
})
}
,
onClick: r !== t ? ()=>i(t) : void 0,
children: n
}, t)
```?
do you mean find what h is
h
set a breakpoint, trigger it, then you can hover all variables to see their values
yup
this indentation is killing me
Son please use a prettier before sending
im not sure if im using it right
or at least hit shift-tab a couple times
uh thats uh interesting?
function h(e, t) {
for (p[e] = t,
e = 0; e < t.length; e++)
f.add(t[e])
}
^
getCurrentDate(): string {
const date = new Date();
const hour = date.getHours().toString().padStart(2, "0");
const minutes = date.getMinutes().toString().padStart(2, "0");
const seconds = date.getSeconds().toString().padStart(2, "0");
const day = date.getDate().toString().padStart(2, "0");
const month = (date.getMonth() + 1).toString().padStart(2, "0");
const year = date.getFullYear();
return `${hour}:${minutes}:${seconds} ${day}-${month}-${year}`;
},
async saveImage(url: string) {
const data = await fetchImage(url);
if (!data) return;
const filenameData = getFilenameData(new URL(url).pathname.split("/").pop()!);
const name = `${filenameData.name} ${this.getCurrentDate()}.${filenameData.extension}`;
const file = new File([data], name, { type: data.type });
saveFile(file);
}
This getCurrentDate returns a hh:mm:ss dd:mm:yyyy timestamp string as intented, but when the "select download location" windows shows up it turns a hh_mm_ss dd:mm:yyyy
how
Example using this image, the first image is a print of file.name value, and the second one is the save file window ||im using fedora linux, i may test this later in windows to see if this is an out of hands issue if i get no response||
yooooo
based tooltip

lmao
why would u search the badges for fubuki
goofball behaviour
funny edge case
Why are my styles not applying
(I also enabled the styles via enableStyle(noticeStyle))
.ping-blocked [class*="contents"]> :is(div, h1, h2, h3, p) {
color: #f04747 !important;
}
{
find: "Message must not be a thread starter message",
replacement: [
{
match: /\)\("li",\{(.+?),className:/,
replace: ")(\"li\",{$1,className:(arguments[0].message.content.includes('@ping blocked: ') ? \"ping-blocked \" : \"\")+"
}
]
},
and now they are randomly applying 
Does the class show up in devtools
for the randomly applyed text?
yes
a
nvm now it works
wrong includes() string skulley
hey, I have been using vencord for a bit and can't find any info anywhere on how to make plugins. Is there documentation anywhere, or any good starting point? I am proficient in js and know a few other programming languages.
Did you check the docs folder
thanks!
also check existing plugins' code in the repo, PRs and #1032200195582197831
alright
@dull magnet Yippe got it working
A bit too much spacing I think, but nice
looks a bit flooded
Is there a way i can conditionally render a setting without making it a component?
I would check myself but i couldn't find the definition for some reason
think no
tried, but couldn't, because you can't access the settings inside the settings while initializing them
I’m sorry if i’m just being stupid or if this isn’t the proper place to be doing this. But, I don’t know how GitHub works. So I don’t know how to submit the changes, but I do know that with this plug-in if you do just one line wrong, you can accidentally turn it into a crasher. So I was just wondering if I could submit it as a whole new PR or uploaded to #1032200195582197831 because I’m pretty sure this is just abandoned by the original devs
Just wrap the component in an error boundary, that'll catch any error during rendering
I realized that I was supposed to make my plugin inside of the plugins folder, but when I did this I now get this error
It only seems to fix if I remove it from it's own folder (aka keep it as it's own .tsx file)
I don’t how Github works so i don’t know how to do that
Github has nothing to do with error boundaries or crashes, it's just where you host the code
i’m sorry i’m an idiot just don’t know how to submit the changes (or whatever) I made since I had to change a whole section of the code
Do you perhaps not have a plugins/WebhookManager/index.{js,ts,tsx}?
ah
ah
ah
ah
thats right
THANK YOU
i had named it wrong
i think what he meant to say was to put a try/catch in your code
for example
try {
// insert your code
}
catch (error)
{
// insert error handling
}
No, I mean a react ErrorBoundary
Instead of return <YourBadgeRenderer {...props} />, do return <ErrorBoundary><YourBadgeRenderer {...props} /></ErrorBoundary>
Basically the react counterpart of a try/catch
i have no idea the hell y’all are talking about i dont how to use GITHUB
its not in github
its in ur code
Github has nothing to do with the code you write
the code works 100% and it optimized
You did express concerns about crashing
yay
Yeah, yeah I figured it out why it was crashing and that was just I did the const wrong.
I just don’t know how to submit the changes to the GitHub PR because it’s a whole section I had to change
idk what to do
push to your fork and open a pr
Hey, I'm new to creating plugins (or trying third party ones) I don't get how to add third party plugins 😔. I cloned the Vencord repo, installed pnpm and installed the dependencies. I then installed a third party plugin and put it into src/userplugins/FakeBadges and I put in the index.ts of that plugin, then run pnpm watch but I can't see the plugin in the plugins list. Did I do something wrong in the process??
run pnpm build
then restart your client
You need pnpm inject first
fair i forgor that
Ah yes, I forgot to mention that I did it. I did pnpm build and pnpm inject after that, because I uninstalled Vencord with it's graphical installer
Ah wait, I need to restart Discord
If you have run pnpm inject and pnpm build or watch without any errors, then it should be successfully installed
Forgot to set a name on your plugin?
pnpm test should catch that when running tsc, right?
Oh no, sorry, it's because I was creating a plugin but then decided to try a third party one before coding my own, the watch failed because there is a folder with nothing inside of it in src/userplugins
Why is there an empty folder then
I created a index.ts file because I wanted to make a plugin, but then I decided to try a third party one before creating one right after I created the file and the folder. I forgot to delete them (or add the code to define it)
Yeah
how do i get a plug-in uploaded to #1032200195582197831
You upload it
Ok, everything works fine now. Thanks for the help everyone :D
I mean, do I need permission to upload it?
I mean my latest thing I posted there would never have gotten in if it needed permission
How would i go about getting a function that sets the users status?
unless it already exists and i'm insanely blind
I’m just asking because the old Devs said that I should just upload it to my GitHub and see if I can get it on third-party since that pull request is pretty much abandoned
You'd consider very very carefully if that is selfbotting
Oh yeah ofc
It's for a status preset thing
Where you can define statuses to quick switch to (manually ofc)
After that you'd find it the same way you find any other function
Sup
Just finished my first plugin
is there a guide or something to post them?
i've read that one must fork vesktop and include the plugin in there but i've lost that post
sooooo uhh
while trying to make webhooks send messages on desktop, it gives me the error
{"message": "Invalid request origin", "code": 50067}
I'd assume its because the origin is discord.com and discord doesn't like hat
execute: async (option, ctx) => {
var webhookUrl = findOption(option, "url");
var webhookMessage = findOption(option, "message");
await fetch("" + webhookUrl).then(response => response.json())
.then(response => {
webhookDefaultName = response.name;
});
const request = new XMLHttpRequest();
request.open("POST", "" + webhookUrl);
request.setRequestHeader('Content-type', 'application/json');
const params = {
content: webhookMessage,
username: webhookDefaultName ?? "User",
avatar_url: ""
};
request.send(JSON.stringify(params));
sendBotMessage(ctx.channel.id, {
content: "Message sent. Output: " + JSON.stringify(params)
});
}```
Maybe I'm wrong though, because on my website this exact code works just fine
why are you trying to execute a webhook from a plugin
its a webhook manager
send messages, delete, and get info
it can be considered a niche to some, but can also be utilized and having an actual purpose
well you can bypass this limitation by sending the request from nodejs
via native.ts file
native.ts only has these 2 functions (although im not sure this is the right native.ts)
no
files can have native code by creating a file called native.ts
search for it in the files and you'll find examples
okay i might be a little lost
// native.ts
import https from "https";
export function executeWebhook(_, url: string, body: object) {
const req = https.request(url, { method: "POST", ... });
req.write(body);
req.end();
}
// index.ts
const Native = VencordNative.pluginHelpers.YourPluginName as PluginNative<typeof import("./native")>;
Native.executeWebhook("https://discord.com/api/...", {
content: "hi"
})
probably needless to say that this makes your plugin not function on web
it should be alright, if people end up wanting to use this on web i'll consider trying to find out how to make it work on web
ooh true
this should be implemented properly now (although it tells me https.post does not exist), i gtg for half an hour but ill be back soon
// index
const Native = VencordNative.pluginHelpers.WebhookManager as PluginNative<typeof import("./native")>; // approx line 13 before definePlugin
Native.executeWebhook("" + webhookUrl, {
content: webhookMessage,
username: webhookDefaultName,
avatar_url: ""
}); // approx line 120 in the execute sendwebhookmessage
// native
import https from "https";
export function executeWebhook(_, url: string, body: object) {
const req = https.post(url,
{
method: "POST"
});
req.write(body);
req.end();
}
yep
got it
const iframe = document.createElement("iframe")
iframe.sandbox = "allow-scripts"
iframe.srcdoc = `
<script nonce="NDEsMjksMTM0LDU4LDIzNyw4OSw0NiwyMTY=">
fetch("http://localhost:8080")
</script>
`
document.body.append(iframe);
setTimeout(() => iframe.remove(), 1000);
but u have to somehow figure out the nonce or it will fail due to csp
I'm trying to make a checkbox appear next to the download button on a zip file but when I use patches it appears on videos instead? But shouldn't this be a zip because it has the class of nonMediaAttachment while a video has the class of mediaAttachment?
patches: [
{
find: ".nonMediaAttachment]",
replacement: {
match: /\.nonMediaAttachment\]:!(\i).{0,10}children:\[(\S)/,
replace: "$&,$1&&$2&&$self.renderCheckbox(),"
},
},
],
renderCheckbox: ErrorBoundary.wrap(() => {
return (
<input type={"checkbox"}></input>
);
}, { noop: true })
Yea it shows it on a video when I'm trying to only show it on zips but it wont show on a zip for some reason?
Cuz on a video it looks like this
I'm looking at the source for FixYoutubeEmbeds and trying to understand how it works. I was wondering how reloading the page with location.reload() fixes the issue, or am I looking at the snippet wrongly?
frame.executeJavaScript(`
new MutationObserver(() => {
if(
document.querySelector('div.ytp-error-content-wrap-subreason a[href*="www.youtube.com/watch?v="]')
) location.reload()
}).observe(document.body, { childList: true, subtree:true });
`);
check what d and t stand for and you will realise the problem
the watch on youtube is done by checking the parent origin
inside iframe in discord, the parent origin will be discord
but reloading the page makes it lose its parent so it wont have a parent anymore and their check fails
Ah I see, is losing the parent origin via reloading the page an intended interaction or is it more of a happy coincidence?
intended
Gotcha, thanks. I wonder if I can find a reason behind why that's so in youtube's documentation
Since right now I can't see the reasoning for why it would be designed that way
In that case should I be looking at chromium docu?
Either way I doubt I'll be able to find a concrete reason since this sounds like quirk territory.
I'm trying to figure out now why reloading the page in the iframe makes it lose it's parent origin
from mdn docs on window.parent:
When a window is loaded in an <iframe>, <object>, or <frame>, its parent is the window with the element embedding the window.
location.reload() reloads the youtube embed which makes it so that it's now loaded regularly and not by the iframe
this is a weird error (in console)
1170555935396216834:1 Uncaught (in promise) Error: Error invoking remote method 'VencordPluginNative_WebhookManager_executeWebhook': TypeError: Er.default.post is not a function```
Sounds like https library is not used how you expect
Doesn't pnpm test show any typescript output?
running that rn
ah
i wish i knew that command earlier, still new to pnpm / npm as a whole
i have no idea what eqeqeq is
It says exactly what it is
i dont even have a === in my code
Yes, that is what it's saying
ohhhh
i see i see
misread it lmao
aand fixed
no more errors
wait
didn't mean to delete*
1170555935396216834:1 Uncaught (in promise) Error: Error invoking remote method 'VencordPluginNative_WebhookManager_executeWebhook': TypeError [ERR_INVALID_ARG_TYPE]: The "chunk" argument must be of type string or an instance of Buffer or Uint8Array. Received an instance of Object```
```ts
export function executeWebhook(_, url: string, body: object) {
const req = https.request(url,
{
method: "POST",
headers: {
'Content-Type': 'application/json',
}
});
req.write(body);
req.end();
}```
I'm still a little stuck on this since it *SHOULD* work, unless I'm thinking about fetch()
Why do you not use fetch()?
^
previously i tried to use it, and a few other methods
but i get the uhhh
Yes, why do you not use fetch in nodejs
because it's not available in the nodejs version used by discord
i just learned that ^
you cannot
you need to fully restart discord to apply changes to your native script
oh you have a new error
well the error tells you exactly what's wrong
i see something about a chunk needing to be a string
now the way i counter this (which probably is not a good code practice at all) is by doing "" + whateverIneedtoadd
i could also just (string) whateverthethingis but sometimes that won't work
JS doesn't even have that syntax, does it?
maybe im thinking about C#
where you can cast
I FOUND WHAT I NEEDED TO DO
YUESSSS
🎉🎉🎉🎉🎉🎉🎉🎉🎉
a
you have no idea how much i wish vscode had a git ui manager intuitive as jetbrains environments have

i use this
super intuitive
I just use the cli, it works fine
i just use gitui cause i no no wanna use git commands and its good for visualizing
finally, I think I'll get somewhere asking things in this channel
forever finding myself asking things in the wrong places
anyway, hi \o
i'm new here
yes
i am looking into how that sidebar menu is opened
thanks for pointing me in the right direction
oh, that's discord jank showing up again
was that me?
👀
i didn't start a thread...
maybe I should? either way, does anyone know how I can be in more than once place at once in the desktop app?
like multiple windows viewing diff channels?
someone mentioned the channeltabs thing and I'm chasing that down rn trying to see if I can make it fit my use case scenario here
OH
btw when you click a message on the server home it also opens the sidebar
oh yeah
ok, thought that was something I did on accident... my bad
i'm more specifically talking about the theming but it doesnt really matter
shiny
I've only ever interacted with server side code (bot development)
new territory for me here
a lot of discord client modding is
- open devtools
- find something
- play with it in the console using vencord's webpack findByProps/findStore/findByCode
- profit
very useful
\o/
@green vessel so it seems like I've found how to open the sidebar
const { openChannelAsSidebar } = findByProps("openChannelAsSidebar");
takes an object of {guildId, channelId, baseChannelId}
baseChannelId should be the current channel id
current as in the one I want to open yeah?
seems easily usable
but hardly extensible
allowing more than one sidebar would be likely very hard
yeah
you might find Vencord's ContextMenuAPI useful
do note
there has been a major change to it in the past ~week
that's fair.
necessity is the mother of invention and I'm a firm believer of the KISS protocol
so, I just want to right click a channel and open it in the sidebar (and have it stay there)
that'll do enough for me
search for channel-context
I was thinking I could possibly run multiple instances of discord at one point, but I don't need it to take up that much ram. I just want to have the ability to monitor comms in a main channel while cycling through dms etc
admin problems...
you can now define context menu handlers without the old start/stop plugin add/remove context menu patch calls
https://github.com/Vendicated/Vencord/blob/main/src/utils/types.ts#L122
**types.ts: **Line 122
contextMenus?: Record<string, NavContextMenuPatchCallback>;
they don't know about the old way
they will find the old way by looking at existing plugins
this is where I suggest taking a look at existing plugins

really
yes
@vast karma I'm stupid
note to self
do not assume legacy code exists
pretend I said nothing about the old way of doing it
so, where's that channeltab plugin at?
a
see https://github.com/Vendicated/Vencord/blob/main/docs/1_INSTALLING.md for installation guide, you are on your own (mostly)
oh
well, it's already running
so
I made it that far
i kinda know what i'm doing
(i hope)
discord 
oh
make it to where yall aint gotta download this stuff
I got way to much files for this
what
STFU
Mods, literally rot this user's brain
oof
will the order of this change and break my patch?
that's a bad match
yes it is
it's too generic in the beginning
i know
ok
this is getting very xy
what I really need
is to capture the first argument
BROOO NOT WITH THAT FONT
real
PS
blame the fact someone linked the font in the server here 
THAT WAS ME

i will explode you
ok but really
what if i told you i programmed with splatoon font once
HORROR
Do i have a way to close the plugin settings dialog from inside of a component?
cant find the correct flux event for the dispatcher
how risky is calling closeAllMethods()?
why can't I use useState in my component?
i am getting this: https://react.dev/errors/300?invariant=300
export function InputBoxComponent(currentRules: null | Array<>) {
const [inputValue, setInputValue] = useState('');
console.log("hook setupped");
const handleInputChange = (e) => {
const newValue = e.target.value;
setInputValue(newValue);
};
return (
<div>
<TextArea
value={inputValue}
onChange={handleInputChange}
></TextArea>
</div>
);
}
you are returning somewhere before a hook is called
how are you rendering the component
this is the problem, i can't to seem to find the place where i am returning
wheres the function used
give me sec
using it in a patch
{
find: "return(0,a.jsxs)(\"div\",{className:L.categoryContainer,children:[",
replacement: [{
match: /return\(0,a\.jsxs\)\("div",\{className:L\.categoryContainer,children:\[/, // return(0,a.jsxs)("div",{className:L.categoryContainer,children:[
replace: "$&$self.renderTestText(), $self.renderInputBox(),"
}]
}
use react properly
renderInputBox: () => { return TestInputBoxComponent(currentRules); },
and wrapping it
that's not how you create a component
guess what. i am not a react guy
<TestInputBoxComponent rules={} />
alright, is there way to correct this?
(method) onChange(v: string): void
I expect an InputEvent
not a string
I've made a plugin to patch the built in +:emoji: add reaction command to add the reaction to the message you're replying to, what should I name the plugin?
reactions+ from what i understood that could be a good name
too misleading imo
idk i didnt really understand the plugin tbh
so you know how you can use +:emoji: to react to the last message in chat
my plugin patches that so that if you try to reply to a message when using that command it adds the reaction to the message you are replying to
discord doesn't do that by default 
idk thats the only thing that is coming to mind
let me stall for a few hours before committing this
every day i hate discord shitcode more and more
same
my brain no work when i see it
REAL
ong fr
guys, why i am getting a string on change?
how do I get the target value?
You get it as argument
can you elaborate?
You provide a callback. That callback gets the string. I don't see what is so hard to understand.
import it from webpack not react
fixed
I don't see why I can't get backspace or enter to update/insert it correctly
Well you haven't said anything about what your problem is yet, other than you're surprised that you're getting a string
going to test something hope it work
yes i am surprised, I was imagining getting an inputevent before
I don't really want to. I just want to get the updated value
when the box updates, I want to get the text inside
And do what with it?
I believe its going to be ugly if I put a button
I am seeing if that text matchs a list of keywords
anything in that text matchs a list of keyword*
That makes sense I suppose
But I don't see how that relates to changing value= every time the value changes
so I can just listen for the value changing
listen, can I just listen for inputValue changes instead?
it was a bad old code, i am just matching the logic of the old one with a refactor version.
this sounded like I just can listen for inputValue changes
All I'm asking is why you're doing value={currentValue} instead of value={initialValue}
to update it
And why do you do that
because onchange doesn't.
What
like it doesn't update it passes it to onchange instead
Yes
you gave me an idea, why don't I use useEffect and listen for inputValue changes instead
and remove onchange








