#๐งฉ-plugin-development
1 messages ยท Page 37 of 1
Then simple regex match lmao
could still be vulnerable if the developer has a skill issue
alright this worked thanks
Np
๐ฅ
is that your own chat app?
unsane
discord but better
looks like its written in kotlin which is in fact not electron making it substantially better
me building my client with electron
:(
just because electron is bloated doesnt make your own code bad :D
no idea if its any good
but rust = good
:D
๐
it do be a bit odd
how do i refresh the settings
i have a button for removing a certain field
easiest awy would be just refresh everything
make a force updater on the parent and just use that lol
idk what that means cuz idk shit about react
vencord has useForceUpdater()
it's a simple hooks that re renders the component when you call the function it returns
sounds great
discord client
kotlin rewrite?
thats cool
i want to do a rust rewrite but rust gui isn't there yet
i mean it's not the first but cool nonetheless
I srsly wonder how people interface with discord using fully custom clients
just like the official client does, sending http requests and connecting to the gateway
sounds like a bot lol
although maintaining a custom client is a very respectable feat, unlike maintaining a bot api framework (like djs, dpy, etc) you get no official docs or updates, you have to figure out everything in your own (previous implementation and datamining helps a lot tho)
yop it's pretty much self botting
but it should be fine as long as the custom client is sending proper headers
X-Super-Properties moment
i love x-super-properties
you send a request to /experiments, you get 50~90 experiments, add xsp now you get 100+
a very important header
lmao really?
yop i tested it when wworking on my user experiments rollout tracker
i didnt see that anywhere in userdoccers
the thing that doesnt get you banned when joining guilds
its in my pr
and doing some other stuff
not merged yet
i still have to document 30~ gateway op codes
@amber basin https://discord-userdoccers-9fn7lztes-discord-userdoccers.vercel.app/reference#client-properties

can someone give me an android client x-super-properties https://cdn.discordapp.com/emojis/1076697194993827981.webp?size=48&name=Cutie&quality=lossless
OH WAIt
i could but i'll have to setup mitm
no its on all http requests
ah nvm i misunderstood
there's a LOT more
YOURE PASSING INTENTS???
โ ๏ธ dont
ohhh ik why i did it
you need capabilities too
i assumed intents atleast helped specify what the client could parse so discord doesnt break their old clients
wait is that capabilities
ah
@amber basin you can pull a dpy-self and use dolfies' web service to create x-super-props https://github.com/dolfies/discord.py-self/blob/master/discord/utils.py#L1440-L1471
and yeah capabilities they're in userdoccers
(it only works for windows)
can i make a vendetta plugin to yoink x-super-properties from the http client
thatd be easiest i fink
unfortunately yeah it's desktop and web only
but mobile is no different
you are better off reading ^ this and making super props yourself
you dont even need a plugin
i dont wanna setup a proxy waaaaaaa
a a a test
oh right yeah
but i think plugin would be more effort :3
you can also use the debugging socket feature and get props directly
yeah thats what i meant
one sec let me start wsa
{ os: 'Android',
browser: 'Discord Android',
device: 'windows_x86_64',
system_locale: 'en-US',
client_version: '200.7 - rn',
release_channel: 'canaryRelease',
device_vendor_id: '07d966d0-79ac-49fe-9fbd-8f12daa750d8',
browser_user_agent: '',
browser_version: '',
os_version: '33',
client_build_number: 200207,
client_event_source: null,
design_id: 0 }
meow
a
guh why's my vendetta not on light theme
๐
tysm
i haven't documented design_id but there's 0 and 1
i am not really sure (maybe hard code them)
iirc design_id corresponds to 0 -> normal, 1 -> tabs v2
i might be wrong
me omw to pressure dolfies into adding linux
oki
wdym, linux is already there
really thinking about just saying im a windows client rn, cba to wait

yop just confirmed design_id, 0 is normal, 1 is tabs v2
since you're emulating the android client you should probably add that to your super-props/identify
while youre here erm,, just to make sure, im not missing anything am i? planning on replacing props with api endpoint onesso ignore those
oh yeah native_build_number is windows only thing, so if you're not sure what os it is i'd recommend avoid that
is it? oh wow
and you can add these for linux
(env.XDG_CURRENT_DESKTOP || "unknown") + "," + (env.GDMSESSION || "unknown")
can but cba because not required
you could just hard code it to be unknown,unknown if os is linux 
fair enough
ill just do this, ive been putting off writing an api module for too long
lgtm
also @amber basin you should set client_version and client_build_number dynamically
because discord has some goofy experiment filters based on client versions and api sometimes shits itself if it doesnt match the filter
the api is also tied to experiments
for example packs experiment had a minimum client version filter, any client sending version lower than that couldn't use packs api
How'd you do that?
I wanted to start making vendetta plugins but I didn't know where to start from
:3 .gg/bNyEn7Sb
no response means okay totally
vendetta via windows subsystem for android and https://github.com/Aliucord/debug-ws-server
although you dont need windows subsystem for android if you can expose your WS server and connect to it via adb
how are you using it
eh, so I should be fine with my phone, setting up wsa is a pain
yeah just make sure you're connected to adb and the debug-ws-server will take care of port forwarding
i google searched and it might have to do with useState?
best approach is probably to separate the return value of the map into it's own component
so you can use hooks properly
then just pass a and i as props to it
i have the tab open
just didnt wanna oop
guess im left w no choice unless i do something silly
rust ๐
but fungus named lang good :nod:
i love the concept of traits in rust
which are awesome
very much so
that looks really fucking bad but it also looks like something i'd do
so 
more readable than a class
no one mentioned classes, function components are a thing (and you are using them right now)
I'd say it's more data oriented
given that polymorphism in rust uses composition over inerhitance
in terms of normal data structures yeah
its basically just moving the methods into their own semantic scope
pls teach me on how to write a custom client
yay
the only thing i need now is
i wanna make the delete button an icon
how do i reduce the amount of space here
oh i guess NONE
didnt even work
I think it's an icon style
i just did an override of padding
hacky but works i guess
i found something called Hovers in the Button type thingy
but i cant find a way to use it
want the buttons to be black and then go red when u hover
padding override works so i guess it stays like that
still wondering about the hover thing tho
ok it works now
(the button is stretched because of the flex container)
the hovers is an unused type
at least from what I can see
only those props are used
and available
yeah hover effects need to be done in css
do you already have a css file for your plugin?
The textinput component interface in vencord only has an option for a prefix component
what is this
how??
(experiments search)
same with discovery, though it's using a custom component there
it also doesn't work
no
i have one single tsx file
i guess i could add a css file
import json
import asyncio
import websockets
async def send_heartbeat(ws):
payload = {
"op": 1,
"d": None
}
res = await ws.send(json.dumps(payload))
return res
async def keepalive(ws):
print("Starting Heartbeat")
await send_heartbeat(ws)
while True:
await asyncio.sleep(10000 / 1000)
print("Sending Heartbeat")
await send_heartbeat(ws)
async def standby_bot(token, status, activity):
gateway_url = 'wss://gateway.discord.gg/?v=10&encoding=json'
async with websockets.connect(gateway_url) as ws:
res = await ws.recv()
if json.loads(res)["op"] == 10:
print("Hello Recieved")
print(res)
asyncio.create_task(keepalive(ws))
payload = {
"op": 2,
"d": {
"token": token,
"properties": {
"os": "linux",
"browser": "disco",
"device": "disco"
},
"intents": 3276541
}
}
await ws.send(json.dumps(payload))
res = {"op":11}
while res["op"] == 11:
res = await ws.recv()
res = json.loads(res)
print(res)
res_gateway_url = res["d"]["resume_gateway_url"]
session_id = res["d"]["session_id"]
bot_id = res["d"]["user"]["id"]
print(f"Recieved Authentication from Discord {res_gateway_url}, {session_id}")
async with websockets.connect(res_gateway_url + "/?v=10&encoding=json") as ws:
res = await ws.recv()
if json.loads(res)["op"] == 10:
print("Hello Recieved!")
a = await send_heartbeat(ws)
print(a)
asyncio.create_task(keepalive(ws))
payload = {
"op": 6,
"d": {
"token": token,
"session_id": session_id,
"seq": None
}
}
await ws.send(json.dumps(payload))
res = {"op":11}
last_res = res
while True:
while res["op"] == 11:
res = await ws.recv()
res = json.loads(res)
if res != last_res:
last_res = res
opcode = res["op"]
if opcode == 0:
event_type = res["t"]
event_data = res["d"]
if event_type == "READY":
print("Bot Ready!")
elif event_type == "MESSAGE_CREATE":
message_content = event_data.get("content")
channel_id = event_data.get("channel_id")
print(f"Received a message in channel {channel_id}: {message_content}")
else:
print(event_type)
else:
print(opcode)
print(res)
if __name__ == '__main__':
token = "a"
status = 0
activity = "testing"
asyncio.get_event_loop().run_until_complete(standby_bot(token, status, activity))
discord keeps giving me op code 9
and im not sure what I did wrong
issue is with the 2nd reconnection part
i dont think I did it correctly, but as far as I checked, it matched discords docs
oops
i really dont care
its a test bot anyways
is it failing to reconnect?
are you getting d = true or false
your hearbeat interval needs to be set to heartbeat_interval provided in the HELLO payload
in regards to the opcode 9, you need to start a new session instead of trying to resume
try this
import json
import asyncio
import websockets
seq = None # keep track of sequence
async def send_heartbeat(ws, interval):
global seq
while True:
await asyncio.sleep(interval / 1000) # sleep for the interval provided by HELLO
payload = {
"op": 1,
"d": seq
}
await ws.send(json.dumps(payload))
print("Heartbeat sent")
async def standby_bot(token, status, activity):
global seq
gateway_url = 'wss://gateway.discord.gg/?v=10&encoding=json'
while True:
try:
async with websockets.connect(gateway_url) as ws:
# receive HELLO payload to get the heaartbeat interval
response = await ws.recv()
response = json.loads(response)
if response["op"] == 10: # HELLO payload
heartbeat_interval = response["d"]["heartbeat_interval"]
asyncio.create_task(send_heartbeat(ws, heartbeat_interval))
payload = {
"op": 2,
"d": {
"token": token,
"properties": {
"os": "linux",
"browser": "disco",
"device": "disco"
},
"intents": 3276541
}
}
await ws.send(json.dumps(payload))
while True:
response = await ws.recv()
response = json.loads(response)
seq = response.get("s", seq)
if response["op"] == 9: # INVALID_SESSION
print("Invalid session, reconnecting.")
break
# (Your event handling code goes here)
except websockets.exceptions.ConnectionClosed:
print("Connection closed, reconnecting.")
# breakoff before connect
await asyncio.sleep(5)
if __name__ == '__main__':
token = "here"
status = 0
activity = "testing"
asyncio.get_event_loop().run_until_complete(standby_bot(token, status, activity))
@topaz crest
alright
nothing happens
blank console
i see heartbeats being sent
but nothing else
are you on python 3.7+?
also do you have a new bot token cz i saw you accidentally showed it here earlier
import json
import asyncio
import websockets
seq = None
async def send_heartbeat(ws, interval):
global seq
while True:
await asyncio.sleep(interval / 1000)
payload = {
"op": 1,
"d": seq
}
print(f"Sending heartbeat: {payload}")
await ws.send(json.dumps(payload))
print("Heartbeat sent")
async def standby_bot(token, status, activity):
global seq
gateway_url = 'wss://gateway.discord.gg/?v=10&encoding=json'
print(f"Attempting to connect to {gateway_url}")
while True:
try:
async with websockets.connect(gateway_url) as ws:
print("Connected to the gateway")
response = await ws.recv()
print(f"Received response: {response}")
response = json.loads(response)
if response["op"] == 10:
heartbeat_interval = response["d"]["heartbeat_interval"]
print(f"Received HELLO payload, heartbeat interval: {heartbeat_interval}")
asyncio.create_task(send_heartbeat(ws, heartbeat_interval))
payload = {
"op": 2,
"d": {
"token": token,
"properties": {
"os": "linux",
"browser": "disco",
"device": "disco"
},
"intents": 3276541
}
}
print(f"Sending IDENTIFY payload: {payload}")
await ws.send(json.dumps(payload))
while True:
response = await ws.recv()
print(f"Received event: {response}")
response = json.loads(response)
seq = response.get("s", seq)
if response["op"] == 9:
print("Invalid session, reconnecting.")
break
except websockets.exceptions.ConnectionClosed as e:
print(f"Connection closed with exception: {e}")
await asyncio.sleep(5)
except Exception as e:
print(f"An unexpected exception occurred: {e}")
if __name__ == '__main__':
token = "your_token_here"
status = 0
activity = "testing"
asyncio.run(standby_bot(token, status, activity))
here's a version with some prints so you can see whats happening
if ur on 3.7+ try asyncio.run() instead of get_event_loop().run_until_complete()
@topaz crest if that dont work lmk and i can try something else :)
alr
i think that worked
it spammed my console with server info about servers the bot is in
ay nice
lmk if u need any more help
alright ty
how do i actually add css to my plugin
is html "coding" enough for this channel
maybe idk
i dont own the server
compile times 
helo how can i
a. reduce this weird spacing
b. add some padding here without adding padding to everything solved by adding padding-left and padding-right to body
my css
body {
background-color: #7d8491;
font-family: Figtree;
}
.container {
display: flex;
align-items: center;
justify-content: center;
}
img {
border-radius: 10px;
}
.text {
font-size: 20px;
}
.extraspace {
padding-bottom: 100px;
}
each section (image and text on a row) is in its own container div
ill help if u want sure
align the image to the right and the text to the left for the top row, then use padding to add the gap you want
ah i see thanks
i broke it harder
i'll fix tomorrow
i changed my mind and wanted it to just be
text > image
text > image
etc
img {
border-radius: 10px;
right: 0px;
position: absolute;
}
.text {
font-size: 20px;
position: absolute;
left: 0px;
}
i prolly understood wrong but this is what i did
they are cooking
i didnt even know 3.12 was real
i figured i was an edgecase for using 3.11 as it is
WAIT 3.12 HAS PER-INTERPRETER GIL

true concurrent execution of python threads
at long last
LMFAO yea
ducko jumpscare
what is up with that hostname?
preview deployment from a pull request
owo
quick question: what would be a way to programmatically grab plugin settings and then apply the values to patches or are settings the wrong way to go about that?
different purposes
two options:
$self.settings.store.someSettingafter putting return of definePluginSettings() on your plugin instance
patches: [{
find: "",
replacement: {
match: /.../,
replace: "$self.someSetting"
}
},
get someSetting() {
return "thing"
}
Aren't both web bundlers? What are the purposes of these two? ๐ค
Hmm, guess I'm missing something
const options = generateOptions(soundmap);
export const settings = definePluginSettings(options);
function generatePatches(soundmap: Record<string, any>) {
var patches: Array<{ find: string, replacement: { match: RegExp, replace: string; }; }> = [];
for (const key in soundmap) {
console.log(`${key}: ${soundmap[key]} `);
const soundValue = self.settings.store.soundmap[key];
console.log(soundValue);
if (soundValue) {
patches.push({
find: `${soundmap[key]}:function(e,t,n){\"use strict\";e.exports=n.p+`,
replacement: {
match: /n\.p\+"\w+\.mp3"/,
replace: `\"${soundValue}\"`
}
});
}
}
return patches;
}
rspack is a webpack replacement, esbuild has very different api
using rspack only really makes sense if you want to make use of webpack plugins
wtf is that
why would u do it like that
that's a really bad way of doing that - and i think there is already a sound changer plugin pr
going by the name im gonna assume that rspack is a rust implementation of webpack
it is i guess
yes
neubrutalism looks so cool
It's the 15 mins way I initially did it and tried to expand it, but the pr works great. Thanks!
sounds scareh ยฐฯยฐ
just use vite 
why
guh
why do you think discord started using rspack instead of webpack
bros are rust simps fr
look at these rustlovers
the rusters
do they rust?

If they are a metal then ya
Is it ok to use UserUtils.getUser multiple times every time I render a custom modal or should I store the user objects instead of IDs to avoid calling getUser every time?
or I could getUser the IDs once at plugin load then use those until restart
just useState useEffect
rn i uh im doing something very similar to this https://github.com/Vendicated/Vencord/blob/86e94343cca10b950f2dc8d18d496d6db9f3b728/src/components/PluginSettings/PluginModal.tsx#L93C1-L104C12
**PluginModal.tsx: **Line 93
React.useEffect(() => {
i guess its fine
discord uses swc and not rspack iirc
swc is speedy web compiler
partial webpack replacement that was more mature at the time of migration that rspack
@ScriptedAlchemy @_adryd @discord @rspack_dev On average our Webpack build times in CI were around 7-9 minutes and Rspack takes about 45 seconds to 1 minute. So total reduction in just build time is actually closer to 90% but there is some constant time overhead we're hitting that is unrelated to the actual building part ๐
๐ 3
nice, okay
well, i only had to fix the classes with the class fixer thingy for my theme
and vencord was fixed overnight before i got to experience it broken
like, css stuff anyway
how could i add some text right here im making a timestamp plugin for peoples local times and woudl like to see the current time on their profile
i figured i would need to do something like this tsx { find: ".useCanSeeRemixBadge)", replacement: { match: /(?<=onContextMenu:\i,children:).*?\}/, replace: "$self.renderUsername(arguments[0])}" } },
straight from the "ShowMeYourName" plugin
but im an amateur when it comes to js/ts

maybe you can yoink from SortFriendRequests
Anyone know why my gltf models aren't showing up when I serve from dist and serve it, but works perfectly fine when I'm running from bun run dev? I'm using three js and vue 3 btw
Dist vs dev
are the gltf files in dist?
i may try my first plugin idea again
What was it?
message notes port
it was fairly simple i just stopped because my brain couldn't get around manipulating discord's message component
i ahould aleep
That's sounds nice
that looks awesome btw
hello look to my profile
no
dev loper
yeah is just a badge
to do that create a server
and go to google and type discord badge creator about me
click on the first link
and do the icon you want the text and the color
and import as badge.zip
and you will see 6 รฉmoji
if is 7 it will not work
and add the emojis on the server
and go to your settings
and go to profile
and go to about me
and click on รฉmoji
POV you are 12 and saw a no tts video on YouTube
WARING: Only work if you have Nitro
Lol
This kid thinks we don't know shit
He just watched a notts vid and now he is a master at discord lol
lol
hi
No
why is the e an "รฉ"
ฤ
ร
what
You spelled devloper wrong, genius
This is a โซ message โซ
dรฉvlopรฉr
Again just a thing from a notts vid lol
You are just making a joke of yourself
Is it using unicode chars?
me when old discord formatting tricks:
It feels like unicode fuckery
It is
Ya u are
Thanks
Np 
Noooo
saying I'm smarter than I look implies I look dumb lmfao
No you look smart but you are smarter that how u look
yes RLE
right to left embedding
indicates the change in direction of text layout
sometimes
nope
thanks
so i guess your dev script is serving files from dist and the folder in which your gltf files are in
whereas you are only serving from dist
dev shouldn't be serving anything from dist though
Well I could try putting it in public/assets I guess
it's static
ok that worked
well that was a dumb problem
anyone got some dnd bypass pluging, so you still get desktop notifications
its called online mode
they want notifs
on dnd
i hav a plugin to bypass it for specific ppl
yes but no
send <3
this plugin is ancient but i never pr'd bc katlyn wanted to port cutecord
maybe i should try that
yeah
hey fellas, im a total noob when it comes to even the simplest of code but im trying to make a .bat file that will find and launch discord on any pc, i have it working for mine but i can't really test it outside of mine and sandboxie isn't really working as intended for it
if anyone would be willing to test it would only require closing discord and running it. it should be compatible with both vanilla and vencord discord since it's the same file name
shouldnt have to close discord in tray or anything but if anyone knows better do share
also if anyone has been having issues with their vencord discord shortcuts getting deleted everytime theres an update this may help, that's what it's designed to do, should also work as a startup program but havent tested that yet either, though that's not so important to me in terms of functionality
I LOVE CACHING I LOVE CACHING
# holy shit thats alot of caching
- name: Cache AppAndroid
if: matrix.os == 'ubuntu-latest'
uses: actions/cache@v3
with:
path: appAndroid/build
key: ${{ runner.os }}-appAndroid-${{ hashFiles('appAndroid/**') }}
- name: Cache AppDesktop
uses: actions/cache@v3
with:
path: appDesktop/build
key: ${{ runner.os }}-appDesktop-${{ hashFiles('appDesktop/**') }}
- name: Cache genesisApp
uses: actions/cache@v3
with:
path: genesis/app/build
key: ${{ runner.os }}-genesis-app-${{ hashFiles('genesis/app/**') }}
- name: Cache genesisCommon
uses: actions/cache@v3
with:
path: genesis/common/build
key: ${{ runner.os }}-genesis-common-${{ hashFiles('genesis/common/**') }}
- name: Cache genesisDiscordApi
uses: actions/cache@v3
with:
path: genesis/discord/api/build
key: ${{ runner.os }}-genesis-discord-api-${{ hashFiles('genesis/discord/api/**') }}
- name: Cache genesisDiscordClient
uses: actions/cache@v3
with:
path: genesis/discord/client/build
key: ${{ runner.os }}-genesis-discord-client-${{ hashFiles('genesis/discord/client/**') }}
- name: Cache genesisApi
uses: actions/cache@v3
with:
path: genesis/genesisApi/build
key: ${{ runner.os }}-genesis-genesisApi-${{ hashFiles('genesis/genesisApi/**') }}```
now it wont spend 5m building genesisApi (a 76 line file) for ios every time
cache fans when their build mysteriously stops working on ci but not locally
@echo off
SETLOCAL EnableDelayedExpansion
:: Define the common paths where Discord might be installed.
SET "discord_paths=C:\Users\%username%\AppData\Local\Discord\Update.exe --processStart Discord.exe
C:\Program Files\Discord\Discord.exe
C:\Program Files (x86)\Discord\Discord.exe"
:: Attempt to start Discord from the known paths.
FOR %%D IN (%discord_paths%) DO (
IF EXIST "%%D" (
START "" "%%D"
GOTO End
)
)
:: If Discord wasn't found in the common locations, perform a system-wide search.
echo Discord not found in common paths. Performing a system-wide search, please wait...
:: Use where command to search in Program Files directories. Avoiding system directories for speed.
FOR /R "C:\Program Files" %%F IN (Discord.exe) DO (
SET discord_path=%%F
GOTO LaunchDiscord
)
FOR /R "C:\Program Files (x86)" %%F IN (Discord.exe) DO (
SET discord_path=%%F
GOTO LaunchDiscord
)
FOR /R "C:\Users\%username%\AppData" %%F IN (Discord.exe) DO (
SET discord_path=%%F
GOTO LaunchDiscord
)
:LaunchDiscord
IF DEFINED discord_path (
START "" "!discord_path!"
GOTO End
)
echo Discord executable not found on the system.
GOTO End
:End
ENDLOCAL
why did u send bro chatgpt code
Nah see I tried chatgpt and it exported the message it was unable to find the file every time
Though I will admit I had it regenerate the prompt so many times it did end up having some generally good points
You can't really ask it to generate code persay but you can ask it how to solve a problem so you can look up how to do the thing
Where you usually just wouldn't even know what to google
Or I dunno maybe it's just way better at c# or something evil like that than batch
(I don't know if c# ie actually that bad or not I've never touched it I just know it's a common joke that it's bad or something)
Yeah sometimes itโs easier to write it in pseudo code and have it convert it
i just ask it to rephrase docs lol
import { ApplicationCommandInputType, ApplicationCommandOptionType, Argument, CommandContext, sendBotMessage } from "@api/Commands";
import definePlugin from "@utils/types";
import { UploadHandler } from "@webpack/common";
import { findByPropsLazy } from "@webpack";
const UploadStore = findByPropsLazy("getUploads");
const DRAFT_TYPE = 0;
const UploadHandler = findByPropsLazy("showUploadFileSizeExceededError", "promptToUpload") as {
promptToUpload: (files: File[], channel: Channel, draftType: number) => void;
};
async function downloadVideo(url: string): Promise<Uint8Array> {
try {
const response = await fetch(url);
const arrayBuffer = await response.arrayBuffer();
const uint8Array = new Uint8Array(arrayBuffer);
return uint8Array;
} catch (error) {
console.error("Error downloading video:", error);
throw error;
}
}
async function convertAndPostYoutubeVideo(url: string, channelId: bigint, cmdCtx: CommandContext) {
try {
// Debuggin with bot message
await sendBotMessage(channelId, { content: "Downloading video. This may take a moment..." });
const payload = {
url,
vCodec: "h264",
vQuality: "720",
aFormat: "best",
};
const response = await fetch("https://co.wuk.sh/api/json", {
headers: {
"Accept": "application/json",
"Content-Type": "application/json",
},
method: "POST",
body: JSON.stringify(payload),
});
const result = await response.json();
// Debug download link with bot message to make sure this shit is working
await sendBotMessage(channelId, { content: `Download link: ${result.url}` });
// Upload the video - this shit is not working
let videoArray = await downloadVideo(result.url);
let videoFile = new File([videoArray], "youtube_video.mp4", { type: "video/mp4" });
UploadHandler.promptToUpload([videoFile], cmdCtx.channel, DRAFT_TYPE);
// Debug with bot message - I am getting this message but no upload
await sendBotMessage(channelId, { content: "Video downloaded and ready for viewing!" });
} catch (error) {
// Log the error with bot message
await sendBotMessage(channelId, { content: `Error converting or posting the video: ${error}` });
}
}
async function executeYoutubeConverterCommand(opts: Argument[], cmdCtx: CommandContext) {
const youtubeURL = opts.find(opt => opt.name === 'url')?.value as string;
if (!youtubeURL) {
await sendBotMessage(cmdCtx.channel.id, { content: "Please provide a valid YouTube URL." });
return;
}
try {
await convertAndPostYoutubeVideo(youtubeURL, BigInt(cmdCtx.channel.id), cmdCtx);
} catch (error) {
await sendBotMessage(cmdCtx.channel.id, { content: `Error converting or posting the video: ${error}` });
}
}
export default definePlugin({
name: "converter",
description: "Handles YouTube video conversion and posting",
authors: [
{
id: 214127950109343745n, // Replace with the actual author ID
name: "Chokitu",
},
],
patches: [],
commands: [
{
inputType: ApplicationCommandInputType.BUILT_IN,
name: "youtubeconverter",
description: "Converts and posts a YouTube video",
options: [
{
name: "url",
description: "URL of the YouTube video",
type: ApplicationCommandOptionType.STRING,
},
],
execute: executeYoutubeConverterCommand,
},
]
});
okay, so I am trying to make a plugin that will grab a video url as parameter and will upload it as a discord video. I wrote most of the code by myself, but by the time I didn't know what to do anymore, I got the petpet code, threw on chat gpt and told chat gpt to try to mimic the upload method, probabily thats why it didn't work, but if anyone has points on why this shit is not working I would love some suggestions:
I am also giving up on doing the utube url check, cuz apparently this api also works for instagram reels, twitter and other stuff
it was chat gpt idea to use uint8array btw, since buffer and blob werent working either
how do I make it so the urls are more split apart?
gap: 1rem
or whatever amount you want
youre welcome
@quaint cipher
import { Database } from "bun:sqlite";
const db = new Database(":memory:");
db.run("PRAGMA journal_mode = WAL;");
db.run(`CREATE TABLE guilds (id STRING PRIMARY KEY, data STRING);`);
db.run(`INSERT INTO guilds VALUES ('1', '{"id": "1", "name": "test"}')`);
db.run(`INSERT INTO guilds VALUES ('10', '{"id": "10", "name": "bleh"}')`);
db.run(`INSERT INTO guilds VALUES ('2', '{"id": "2", "name": "meow"}')`);
console.log(db.query("SELECT * FROM guilds").all());
console.log(db.query("SELECT * FROM guilds ORDER BY id DESC LIMIT 2").all());
console.log(db.query("SELECT * FROM guilds WHERE id = '1'").get());
oh idk
lol
IS THAT A BUN
DISCORD CLIENT
also why the fuck are you using sqlite just to store json
shiggy?
what
the man says "shiggy" i swear
lol it's shige
that was a test, it is destructured now
nah not a discord client, something else about datamining
if i ever make a discord client it'll be in rust ๐
many such cases
maybe whis cost so many strings of your profile using all features of 3y3.
hm... i want whis...
whos know how to import custom plugins using custm CSS?
bc i hate BD
|| decorations ||
|| effects ||
O_O
what happened
what have he done
you forgot to return
OMG
I swear to god that return wasnt in the arrow function in the tutorial
thank you
posts.map((post) => { return <a href={post.slug}>{post.data.title}</a> }) or posts.map((post) => <a href={post.slug}>{post.data.title}</a>)
yeah I made it into the () variant now
you only need it if u make a block {}


dummy forgor
right in rust u don't need it do u
just omit semicolon and it returns
should have omitted the semicolon and maybe it would have worked


blogs heading?
i assume this
I assume so as well
oh
footer
h3 span[class*="username_d30d99"]:before {
visibility: visible;
position: relative;
margin-right: -1805px;
background: linear-gradient(to right, #4e5dd6, #e224c5);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
}
why doesnt this change my name color anymore?
classnames change
they havent
nuh uh
how should you format ternaries over several lines, and should I even be using a ternary for this
the ternary is redundant
reduce right will return x if its empty
but youd ```
x == y
? a()
: b()
thanks
it's slightly faster to do this comparison than to perform reduceright on an empty array, which is why I done it
its slightly faster to not use js
true but gamified coding fun
NOT LIKE THIS
reduce but the other way
reduceMiddle
reduces lina
the only good way to format ternaries is
condition
? x
: y
anything else is criminal
or inline if very short
NOOOOOOOOOOOOO
cond1 ? x :
cond2 ? y :
cond3 ? z :
w
im right
@dull magnet shut up u did this too
esp w ts types
agree except tab indent
tabs horror
tab isnt whitespace?
ah mb
dum void
hey void run this find and replace
ill reduceRight you to ashes rini
it doesnt matter, its eslint enforced anyways
tab bad bc notepad displays it wrong /s
tab fans when no consistent line length limit
i also have this 
objects can have key order??
ya
i mean
iirc its not defined but most engines will give them to you in some sort of fixed order
oh ew
its insertion order usually
that's usually the formatter doing it
it formats ts types so weird
mald
yea sometimes,,,
see what
id rather not thank you
tab fans wben i stab them

why is ur ide so ugly
disable whitespace indicators
looks bad
Theyโre right thoughโฆ
I donโt really see the point of them?
ok and?
my ide is the pretties
opinions on pudding light aquarium
puke
Can barely see the green and grey text, if the text colours were changed I could see it being okay
Also smells like outlook
jesus christ dark high contrast is painful to look at
Ehm 5/10
is there a good way to get the amount of characters that have been entered into the msg text box?
What editor is that?
corrupt installation 
intellij / android studio
doki theme wallpaper overwrites vscode files
yikes,,
it normally does after a restart but i just repatched it before the ss
it's funny that they allow this on their official store
Thereโs a watermark?
Sorry, next time I'll post it without the chat alteration
Which watermark tho
never seen a watermark
for real
maybe DraftStore can help?
const SelectedChannelStore = Vencord.Webpack.findStore("SelectedChannelStore");
const DraftStore = Vencord.Webpack.findStore("DraftStore");
const DraftType = Vencord.Webpack.findByProps("DraftType").DraftType;
const currentChannelId = SelectedChannelStore.getCurrentlySelectedChannelId();
const currentChannelDraft = DraftStore.getDraft(currentChannelId, DraftType.ChannelMessage);
const length = currentChannelDraft.length
DraftType values
ApplicationLauncherCommand: 3
ChannelMessage: 0
FirstThreadMessage: 2
Poll: 4
ThreadSettings: 1
why did I do this
we DO NOT need another electron app
lmfao
Ok ty
aight how do i make it so that data->categories is sorted by id
Can you not just do ORDER BY id?
i have no clue about sql, i'm just adding random keywords hoping it works 
ah lol
Iโd just try SELECT * FROM meow ORDER BY id
Iโm pretty lost at sql aswell though so uhh
nah i dont want to sort the rows by id, rather the id of categories prop in data
getting somewhere
Is that plugin public
i got it! kinda
now i need to figure out how to plug that into my insert or replace statement
woo!
WITH modified AS (
SELECT id, json_insert(
coalesce(
data,
$data
),
'$.categories[#]',
json($category)
) as data
FROM meow
WHERE id = $id
)
INSERT OR REPLACE INTO meow
SELECT id, json_set(data, '$.categories', json(categories)) as data
FROM modified, (SELECT json_group_array(json(value)) as categories FROM (
SELECT value
FROM modified, json_each(data->'categories')
ORDER BY json(value->>'id')
))
this is definitely the most complex sql i'll ever write
it works!!
okay, so ive narrowed down the issue. and imma try a solution, if it doesnt work, ill follow up :p
okay, as far as i can tell, my solution works.
it (obviously) ISNT a good idea to check if a member has a role in a guild, before checking if that user is a member of said guild.
They actually have this https://primer.style
hi uh is there an easier way to get this or is this ok
Vencord.Webpack.find(e=>e.default?.prototype?.hasOwnProperty?.("getAudioContext")).default.prototype.supports
i want to get this module
that code works but not sure if its ok to use
nvm only works on vesktop and not discord for some reason
got this that works both in discord and vesktop, is it ok?
let id = Vencord.Webpack.findModuleId("getAudioContext");
Vencord.Webpack.wreq(id).default.prototype.supports
nevermind. doesnt seem like im doing this right
build with --watch flag
epic update to keyword notify coming soon
it will highlight messages
with the keyword
ima try
camila
woah
woah
please dont use other ui frameworks in vencord plugins (assuming thats what this is)
i think they're making an electron wrapper around github
assuming by #๐งฉ-plugin-development message
it's not
no worries
I'm just messing around with github's UI
The app actually looks really good so far
if a=b then what is c
an arbitrary value in memory
thx
writing horrible rust
Looks pretty good to me :D
it's actually not 
is there a way to make a css only light/dark mode switch?
yes
with :has()

hello vee
did you fix your sleep schedule
also themks
I asked chatgpt with your hint cuz I have no idea where to start
please dont kill me vee
hmmI want to have 3 mutual exclusive buttons tho thats probably only possible in js

Itโs not
Radio buttons
Pure html
:3
now I can make cool buttons for light/dark/system
Is it SSR?
uh I use astro in dev mode rn and astro has a cool feature that executes js during comptime so it tries to request github api every content update / page reload druing dev
wait why would rate limit affect u
just use https://github.com/KiraCoding.png
cuz I dont give it an auth token
Theyโre grabbing the pic with user info api
lol


The way you are doing it is pretty cool though
Just have to change the username and it could be someone elseโs portfolio page lmao
it back yippee
Navbar not centered T-T
blah bla bla blah blup bleh blah ... meow mrrp miau meow
Thank you for reading! โฅ

u should maybe still use js 
:has has bad browser support
Literally latest version of Firefox
Afaik
I store the state in localstorage
forced to use js reeee
Not sure if thatโs ideal though
Make it replace all links on the site
To a light mode version of that page

No JS
lmao
But paranoid anti JS people will be happy
Or you just make a light mode
Everyone has dark reader anyway right?
I try to make it 100% js free
except for view transitions I guess cuz it doesnt remove features if its not there

i mean you can still do theme toggle with pure css, but use js to persist it
then if users don't allow js it just won't persist
but Firefox would still be a problem no?
Unless theyโve recently fixed has
gosh view transitions make page transitons so smooth
To mess with programmers
Itโs a css reset
Because it has terrible defaults
more than just that
border box?
the only reset there is the margin
ic, why would you need a flex col the body though
writing jsx that translates to normal html
no js is dumb
so I can fill the <main> idk
so I dont have overflow on the home page
will probably break until I go other 100 but it works for now
I mean yes
is using <a> like this cursed?
not enough styles
im prototyping
Iโd consider that fine
svelte my beloved
(Ik it's astro, but they look extremely simmilar)
this was stupidly simple to make
github sure know how to use react
yes
horrible
why would u make the entire desc a link
whats the better way to make a clickable card that takes me to the blogpost
hmm omki
what is it?
colorways but on github
no that's good
i do the same
it messes up user-select :c
huh how so
cuz it now drags the url
ur horiblw
vee lets be horrible together
Aww :3
not pure css, but minimal js https://github.com/arHSM/arhsm.github.io/blob/main/src/components/ThemeToggle.astro

async function ping(defer: () => Promise<unknown>, send: (content: InteractionContent) => Promise<unknown>) {
const start = Date.now()
await defer()
const end = Date.now()
await send({
content: `Pong! \`${end - start}ms\``,
components: [{
type: ComponentTypes.ACTION_ROW,
components: [createPingBtn({})],
}],
})
}
const createPingBtn = defineButton({
name: "ping",
label: "Ping again",
style: ButtonStyles.PRIMARY,
async handler(interaction) {
await ping(() => interaction.deferUpdate(), content => interaction.editOriginal(content))
},
})
defineCommand({
name: "ping",
description: "Check if the bot is alive",
async handler(interaction) {
await ping(() => interaction.defer(MessageFlags.EPHEMERAL), content => interaction.createFollowup(content))
},
})
@austere mauve rate this api
i like how js devs replace named params with just taking an object as the argument
How do I hide a command from showing?
my code is working as I want, but it's showing the /command
nvm, found out
its just better 
async function fetchDonorPfps(
githubToken: string,
after: string | null = null
) {
const query = `
{
user(login: "Vendicated") {
sponsors(first: 100, after: ${JSON.stringify(after)}) {
pageInfo {
hasNextPage
endCursor
}
nodes {
... on User {
avatarUrl
}
}
}
}
}
`;
const res = await fetch("https://api.github.com/graphql", {
method: "POST",
headers: {
Authorization: `bearer ${githubToken}`,
"User-Agent":
"vencord.dev (https://github.com/Vencord/vencord.dev)",
},
body: JSON.stringify({ query }),
});
if (!res.ok)
throw new Error(
`Failed to fetch sponsors: ${res.status}\n${await res
.text()
.catch(() => "Unknown Error")}`
);
const { data, errors } = (await res.json()) as SponsorData;
if (errors)
throw new Error(
"Failed to fetch sponsors:\n" + JSON.stringify(errors, null, 4)
);
const {
pageInfo: { hasNextPage, endCursor },
nodes,
} = data.user.sponsors;
const avatarUrls = nodes.map(n => n.avatarUrl);
if (hasNextPage)
avatarUrls.push(...(await fetchDonorPfps(githubToken, endCursor)));
return avatarUrls;
}
horror
this is fiiine
what the fu
can u not turn it into a blob a saner way
fetch is the most straight forward way
otherwise i need to like trim prefix, atob, etc
then make response myself
if i fetch() i can literally just directly return its response
sure
FEAR
how do i parse an image with canvaskit
i dont think cloudflare workers support the Image class
does canvaskit even work on workers
uh huh
it seems to work
okay im getting ECONNRESET lmao @trail ginkgo
so ig i cant just fetch all 200 urls at once
rate my interaction api
.
canvaskit so normal love
i mean its just browser canvas api xd
its probably just unreliable
AYOOO
W
wait huge but
why does it look so bad tho
the scaling interpolation lol
how do i make it not terrible
now make clickable pngs
would using a power of 2 yield better result
LOL
LOL
there doesnt seem to be a straight forward like
.drawImageFilter = "bilinear"
but
this is crazy
doesnt look better with power of 2
basically create a new canvas
draw image at half original res
then get data url and draw it again at next half
until ur at target res
NO















