#archive-library-discussion

25217 messages · Page 3 of 26

simple veldt
#

Right so I'll make a pr

wild flax
#

yes this is a bug

simple veldt
#

*list

ornate topaz
#

What list

vernal atlas
#
  • @param {string} [options.type='text'] The type of the new channel, either text, voice, or category
#

that list

#

maybe create a typedef for ChannelType

waxen swan
#

Is there anywhere we can talk about upcoming features or thoughts? :3

ornate topaz
#

Whether a new api feature gets added to d.js depends purely if it gets released and documented by discord.

#

If that's what you're asking about

waxen swan
#

It was that I was wondering about screen sharing abilities now that they're available on servers. Just a thought 🙂

#

Unless it is and im blind 🤔

ornate topaz
#

Bots do not have access to streaming

waxen swan
#

Only voice streaming yeah :/

ornate topaz
#

And again. We don't decide if they can or not. Discord does.

waxen swan
#

Yep

#

Anyway thanks for your time I will go as I'm not wanted here

vivid field
#

why does the .id property not exist on Base directly?

vernal atlas
#

my guess is it was originally for documentation purposes

simple veldt
#

@ornate topaz add news here:

  • @param {string} [options.type='text'] The type of the new channel, either text, news, voice, or category
real jetty
#

Why is message.mentions.members nullable (i assume that's what the ? is albeit im pretty stupid at this sort of thing) when message.mentions.users isn't? they're very similar and I would think that in a message where no one is mentioned both wouldn't exist, correct?

raven juniper
#

I believe the logic is that users can be mentioned in DMs but members cannot be, as there is no guild thus no GuildMembers

real jetty
#

ah, ty

simple veldt
#

setExplicitContent filter doesn't accept numbers

#

using ts

#

should this be fixed or it doesn't matter as we can use string levels

vernal atlas
#

yes the typings should be updated for that, the method does accept numbers

wild flax
#

Using TS, not using numbers here is actually preferred, simply from a type-safe standpoint.

#

But I guess we can loosen the type.

vernal atlas
#

strictly speaking couldnt the typings be altered to support only the numbers that match a verification level?

snow crypt
#

you could use a numeric enum for convenience with that

oak quail
#

ah its because d.js drops it if the member is uncached

#

and members arent cached without sending messages if presence is disabled

timber plover
#

Would the discord.js maintainers be open to a PR that added optional best-effort pre-emptive enforcement of the global rate limit? That is, add an option to the Client (constructor and/or setter as appropriate) to limit to sending 50 (or a configurable other number) of requests per second?
I say best-effort since obviously the global rate limit is based on timing on Discord's end, so without them providing additional headers, we can't be 100% sure we won't hit the limit, but restricting to 50 outbound requests per second should at least reduce the rate you hit it without really adding any latency above what Discord itself enforces.

#

For context, I have a bot using d.js that does enough things in enough servers that it hits the global limit several times per day, and during our peak usage times, we've gotten hit with the temporary block for 10k invalid requests in 10min. Rather than wrapping every single call to d.js on our end, it seems like it would be a lot easier to add global rate limiting inside d.js. I'd probably also add invalid request tracking at the same time, and have a warning event emitted at some configurable threshold (default 9.5k) so users could have an easy way of noticing the limit coming and avoiding the hour-ish long block it triggers

lofty birch
#

there is a ratelimit event that you can use

tacit crypt
#

I mean... if you're hitting that limit/s with good reasons, it'd be time to contact support to have your limit raised anyways

#

Also, reminder that the 10k invalid request ban does NOT apply to just 429's, but also 403/401, something you can handle on your end 👍

timber plover
#

The ratelimit event now is raised when the responses come back. If there are 10 responses "in-flight" when you hit the rate limit, that means you get 10 429s.
As for contacting support to have our limit raised, our bot is in several hundred guilds, and the docs say to ask about an increase if you are in 200k+ guilds. IMO we are hitting the limit for good reason when we hit it, but I'm guessing Discord doesn't care about my opinion for a "small" bot.

#

And yes, I'm well aware of what the 10k invalid request limit includes - I already instrumented my copy of discord.js to log all the invalid requests, their types, and whatever cause info is available 🙂

tacit crypt
#

That's wrong. The ratelimit event we emit means we're currently handling a ratelimit (aka pausing X amount of time before continuing, something we do for any request that 429's). We also handle the global limit when hit by basically blocking all outgoing requests for however long Discord tells us to

timber plover
#

right - I want to block when necessary, before discord tells us to. Since the existing headers provided by discord don't provide any info on the global limit until you hit it, they aren't relevant here

#

and as for the ratelimit event - you emit it when you are handling a rate limit. But if I send 60 requests, all 60 might go out before discord responds to any of them, which means the global rate limit will kick in on discord's end when it receives the first 50, and the last 60 are over the limit. Same thing for a non-global limit - if 10 requests go out to an endpoint with a limit of 5, then you're going to get 5 successes and 5 429s coming back

tacit crypt
#

That is not true

#

Requests on the same ROUTES are sequentially sent

#

So only after the current one finishes do we go to the next one

#

This is the default (and only option in v12) and the "sequential" in v11 (also default, the other being burst, however you shouldn't use it)

timber plover
#

ok fair point, I have been staring at the global part so deeply I forgot how the per-route thing is handled

#

although technically that assumes that the mapping to routes that you have is identical to the buckets that discord uses for the actual rate limit determination on the backend, since

"Per-route" rate limits may be shared across multiple, similar-use routes

tacit crypt
#

We do that, except not with their relatively-but-not-that-recently added bucket hashes. We currently group by the 3 major parameters discord has (guild, channel and webhook ID to be exact)

timber plover
#

sure, I've looked at the source code 🙂

tacit crypt
#

Also, the only cases of there POSSIBLY being 429s is with Discord and their reaction buckets IIRC, there's an issue on their api docs repo

timber plover
#

but regardless - the global limit is what I really care about here (well, also the fact that there is an undocumented 2/10 minutes channel rename sublimit on the channel edit route, but that's a whole other can of worms)

tacit crypt
#

Back on track tho, I understand what you want, however...I dunno if that should be added (esp since giving a lot of control over rest to users...is one easy way to get api banned)

#

the fact that there is an undocumented 2/10 minutes channel rename sublimit on the channel edit route
It was announced in the ddevs server but sadly cannot be represented in the headers

#

Which also causes issues as it stands; you can still edit overwrites even tho you're ratelimited on name changes but as it stands, we don't have that edge case

timber plover
#

yep, I discovered that once I was pointed through several other servers to ddevs 🤦

#

but not before I put a ticket in complaining about it being entirely undocumented

#

which I hold is fair since ddevs is at best quasi official

tacit crypt
#

HA, you'd be surprised how much can be undocumented if we don't do it ASmeguFace

timber plover
#

oh I'm sure 🙂

tacit crypt
#

DDevs IS official, DAPI is the unofficially official or w/e (I think it's the official unofficial one)

timber plover
#

since giving a lot of control over rest to users...is one easy way to get api banned
@tacit crypt not really sure what you mean by this. I don't want to give control to my bot end users, I want to give control to users of d.js

lofty beacon
#

if blocking the request for invalid ones before it is sent is some how possible, that'd be very useful (if i undersotood corect)

timber plover
#

so I don't know who you are concerend about being banned

tacit crypt
#

You're an end user of our library, like me, and many here. The more control we give you over the rest dials (like we do with the restTimeoutOffset) the higher the chances someone will turn them wrong and well, suffer the consequences. or someone turns them wayy down and then complain that d.js is sO sLoW

timber plover
#

so don't make the threshold of 50/second tunable, just let it be off (default, as now) or on (best effort to not global rate limit)

tacit crypt
#

What about those whose global limit is higher/lower

timber plover
#

right - that's part of why my instinct was to make that configurable

#

but if you want to limit turnable knobs...

tacit crypt
#

well, ok you can keep it off

#

Fair point

#

Regardless, I don't see why not but shrug
You should still probably try to contact support for a limit raise (guild limit aside, doesn't hurt to ask) but make sure your use case is actually not considered API abuse and the such

timber plover
#

could also set the min global rate limit to 50 - I was under the impression that was the limit for everyone who hadn't gotten it explicitly raised, so if you try to set lower than that, you're probably making a mistake

tacit crypt
#

However I do have to ask..what are you doing that causes you to actually hit 10k 429's in 10 minutes

timber plover
#

that's a great question, and I don't have a super clear answer now tbh - the bot I work on is for Pokemon Go, and there is a weekly event that sees a pretty substantial uptick in active players and hence in active bot users. The past three weeks, we've gotten blocked sometime around the end of the east coast activity window for the event.
After last week, I added instrumentation to track all the HTTP responses, but all I know now is what happens during lower usage times. So far today, we've had 164 429s from the global rate limit, 94 429s from the channel rename limit (also working on that separately, but that's easy to do from my end), and a handful of other things. My assumption is that those just scale up dramatically during that weekly event window and cause us to hit the 10k in 10 minutes, but I won't know for sure until wednesay evening (or, ideally, never if I can make the necessary changes to not hit the limits before then)

lofty beacon
#

Suggestion: Make the discord.js client cache only things you want it to cache. Discord.JS bots can take up loads of memory mostly because of the cache.

timber plover
#

Update: on what we were doing to hit 10k 429s in 10 minutes for @tacit crypt:
We made some API calls in our unhandledRejection handler and in response to rateLimit events. Turns out this is a terrible terrible terrible idea. If we hit 50/s global rate limit and then attempted to handle an error, we called the API to attempt to resolve what the name of the channel that the error came from was. Obviously this in turn gets a 429, and the descent into madness begins. So no, we didn't get 10k 429s in 10 minutes, we got 12k 429s in about 40 seconds. Big yikes for us

So while I still want to submit a MR for preemptively handling the global rate limit (especially since I did about 95% of it before discovering what was going on), it is somewhat less important/urgent for my bot 😂

autumn talon
#

Why does the typings are in index.d.ts and not directly into the declarations files ?

ornate topaz
#

what exactly are you asking about

#

index.d.ts is a declaration file.
also, library is written in javascript, not in typescript

oak quail
#

should probably be mentioned in the release notes that v12.3.0 updates the domain

ornate topaz
#

what is the difference for the end user though

oak quail
#

older versions may stop working soon

ornate topaz
#

fair

autumn talon
#

Yes, but why do not writing the library in ts ?

ornate topaz
#

for the same reason it is not in java or c#

#

because it is javascript library

autumn talon
#

typescript is typed js

ornate topaz
#

which supports being used in typescript projects via the typings file

autumn talon
#

Ok

raven juniper
#

A future version of the library may be written in ts

ornate topaz
#

also, you cannot just rename all files from .js to .ts and call it a day. typescript code is never ran, it's transpiled to javascript before it runs.

real jetty
#

user.bot was changed so it is now always true or false and can't be null in 12.3.0, right?

vivid field
#

yes, null was removed as a possible value in 12.3.1 but the docs didn't get updated accordingly

real jetty
#

i would try and change that but im bad at PRs

#

dont even know which repo docs are on omegalul

vivid field
real jetty
#

ah thanks

oak quail
#

.system hasnt been updated (although i mentioned in the issue that it should be)

#

the code for .system should have been updated but it wasnt

real jetty
#

yeah i dont see why it wouldnt?

#

i have a feeling that opening an entirely new pr just to remove a single question mark is a bit over the top so im assuming youre just going to commit to the existing one

#

but its already been merged 🤔 anyway ill prob leave this up to you and vaporox you guys are good at these tings

empty viper
#

Also in the Guild class documentation, some of the descriptions of fields speak about de the removed PUBLIC flag

oak quail
#

@empty viper where? i dont see any

#

im pretty sure i updated all of them

empty viper
#

I supposed that it has been fixed in the meantime, the one that I had noticed have not the mistake anymore

oak quail
#

i mean, nothing has changed since you sent that bloblul

empty viper
#

I found the errors like 20 minutes after the release of the 12.3.0 and now it's all fixed 🤔

oak quail
#

maybe it loaded the wrong docs version? because it was changed in 12.3.0

empty viper
#

Yeah it's possible

haughty venture
#

Does someone know how do I test the library?

ornate topaz
#

what do you mean by "test"

haughty venture
#

run the code on test/. all around there's mention to require auth.js, on those files, but there's nothing like this

wild flax
#

Just look what it imports from that file and you can reconstruct it.

#

Its not really much used, those files are just to debug certain things, not to completely test everything

haughty venture
#

sure, thank you!

indigo oar
#

I guess there should be easier ways to get information from a User like If he has nitro

#

without OAuth2

unique axle
#

I guess there should be easier ways to get information from a User like If he has nitro
There is not, there shouldn't be. We can only implement what the discord API offers
flags https://discord.com/developers/docs/resources/user#user-object-user-flags do not include that information. premium type https://discord.com/developers/docs/resources/user#user-object-premium-types is only accessible through an authorized user request - oauth2

summary above, discussion around the topic swepped for less clutter sweep

real jetty
#

or default to false potentially?

frank turret
#

To your second point of defaulting to false, if it’s coerced to a Boolean and is null, wouldn’t it already be turned to false (cause null is falsey)?

real jetty
#

it doesnt check if it's falsy, it just checks if it exists in the data, correct?

#

otherwise nothing is set and it remains undefined

copper laurel
#

Yeah

#

Is that an issue?

real jetty
#

i don't know, you tell me?

#

I just think null would make more sense

copper laurel
#

I mean, I dont believe that it is

real jetty
#

and be more consistent with other properties

copper laurel
#

But it is consistent with the others

#

Nearly everything in _patch has an if in data check

real jetty
#

huh - i always thought by default it turned to null

#

my bad if thats not the case

oak quail
#

discord sends bot and system the same way: either undefined or true

#

discord.js now makes bot true or false

#

but system hasnt been updates, so its inconsistent

real jetty
oak quail
#

we're defaulting bot to false, so we should also default system to false, for consistency

real jetty
#

yeah that makes sense - i'll probably pr it when i can

vernal atlas
#

i didnt set system to null in my PR because i assumed it would've been a breaking change

#

although now that i think about it the docs say it should be null

#

typings say undefined docs say ?boolean which is boolean | null

snow crypt
#

this seems to be happening on every pr sent

vernal atlas
#

yeah i noticed that the other day, i suppose someone can make a PR to ignore it or make a getter that is this.client.options.http.api

lofty beacon
#

Suggestion:

When calling the fetch method, you can pass in an argument as false and It won't cache whatevrer you fetch yet it will return it.

raven juniper
#

that's already a feature on some, if not all, of the fetch methods

#

?docs client.users.fetch

rich iglooBOT
raven juniper
#

although on other managers (roles, channels, etc) i don't think it's there, but they're usually assumed to be cached anyway

lofty beacon
#

thanks! I might work on a PR fo it tomorrow.

ornate topaz
#

on what exactly

lofty beacon
#

no caching of other collections for the fetch method

ornate topaz
#

but why? library assumes that it's always there (and it's actually always there until you forcefully remove it)

#

due to that there is no reason to specifically fetch role or a channel

lofty beacon
#

oh ok. nvm

plucky jay
#

In the typings, should StringResolvable be string | number | boolean | bigint | symbol | any[] (primitives except undefined and null + any[]) instead of any? If content is an object in TextBasedChannel#send, Message#reply etc., it gets used as the options and won't be sent: https://github.com/discordjs/discord.js/blob/master/src/structures/APIMessage.js#L342-L345

Currently, there are no editor suggestions for MessageOptions in TextBasedChannel#send, Message#reply etc. because anything can be used as content. It also means that typos such as channel.send({embed: {tilte: 'Title'}}) do not get reported because it's still a StringResolvable.

I know this would be a breaking change, which is why I'm discussing it here.

copper laurel
#

Typings arent breaking changes, assuming thats all you plan to change

vernal atlas
#

i think it would make more sense to change what the first parameter for TextChannel.send is in the typings rather than the actual StringResolvable type

plucky jay
#

Yeah true because StringResolvable is also used in Util.resolveString

vernal atlas
#

yeah

#

anything with a typeof of object (aside from an array) is treated as MessageOptions | MessageAdditions

#

if no options are provided through the second argument*

real jetty
#

it appears that available can be undefined from what ive seen

oak quail
#

i mean

#

honestly there are probably some mistakes in discord's docs for whether properties are optional or not

real jetty
#

theres no harm in making it constantly boolean value

#

even if there is no mistake it doesnt effect anyone

#

but if it is optional it defaults to false

#

i too would not be surprised if there were mistakes in discord's documentation

vernal atlas
#

those properties seem to be sent even if they are false

vernal atlas
#

the docs (typings too probably) would also need updating for Emoji#animated and Emoji#id

#

animated isnt documented as possibly being undefined, and id is marked as ?string which implies null, but its infact undefined

#

should Activity.syncID be documented, its the track ID for a spotify status, except syncID doesnt really give that away so maybe under a different name?

snow crypt
#

This appears on every PR

vernal atlas
snow crypt
#

oh i see

#

thing is

#

when i run npm test it doesn't even pop up

#

but that might be because of errors because of prettier/prettier

#

which i have no idea why they don't show on GH

vernal atlas
#

oh wait did i just

#

k i facepalmed there, api is meant to be a string

#

but is there still an issue there? doesnt seem like its meant to iterate over the string

real jetty
#

Hey sugden can you read my comment to your PR review when you can, thanks PES_Heart

vernal atlas
#

sure

#

regarding that pr review comment ^ are the jsdocs incorrect for properties such as Guild#approximateMemberCount? as its documented as ?type rather than type|undefined, because ?type indicates type|null as per https://jsdoc.app/tags-type.html

real jetty
#

if thats the case then a lot of things are wrong in djs

#

such as <Guild>.widgetChannelID

#

and Guild#widgetEnabled
you get the picture, this is the case with a lot of properties

copper laurel
#

?type should indicate that something is nullable. We shouldn't have any documented properties be potentially undefined imo

real jetty
#

i agree that if something isn't sent by api it should be nulled but that's breaking
at this point the best solution is probably just to go with ?type even for undefined properties

#

unless we change literally every single one to type|undefined

vernal atlas
#

?type should indicate that something is nullable. We shouldn't have any documented properties be potentially undefined imo

yeah thats what i think would be the best approach, except it would be a breaking change to fix that accross the board

copper laurel
#

v13

vernal atlas
#

well for v13 / djs-next obviously yea, but as for v12 at the moment

real jetty
#

for now i reckon just making the JSDoc consistently wrong rather than occasionally right and inconsistent is better

#

because this is the case for pretty much every property which can be undefined

vernal atlas
#

i think the jsdoc is a bit of a mess

real jetty
#

the approach that i take in the pr is the best we can do for now afaik

vernal atlas
#

types are correct for the most part i think but its just the little parts like this

copper laurel
#

Yeah but I think that like

#

?type will do, it indicates that it might not be there

real jetty
#

yeah exactly

#

having 2 properties typed correctly and 100 not is just more confusing

#

i resolved the conversation since its pretty clear we can't make the changes you suggested sugden, at least not for now

vernal atlas
#

yeah for now it cant be done, maybe if this is an issue it can be implemented with another PR

paper furnace
#

can you explain me the choice which lead to te poorly designed partials feature?

#

why we can't have simply an event like raw previously dedicated to partial instead of dealing with them for each declared listener ? this is completely insane

#

while writing this part of the doc, nobody thinked: oh, finally it's maybe a bad design?

WARNING

Partial structures are enabled globally. You can not make them work for only a certain event or cache and you very likely need to adapt other parts of your code that are accessing data from the relevant caches. All caches holding the respective structure type might return partials as well!
radiant glacier
#

you can still use the raw event

#

in v12

paper furnace
#

nope, my IDE tell me this event don't exists anymore (using typescript)

#

maybe this event is missing into the typedef

#

the in fact partial would be incredibly more usefull if we can bind then to a custom event instead of using them globally like that

radiant glacier
#

well it does @paper furnace

paper furnace
#

mhhh really weird

lofty birch
#

it's not shown in the typings as you are encouraged not to use it

#

same as v11, wasn't shown there either

#

and partials are very helpful, it's as simple as adding if(<x>.partial) await <x>.fetch(); wherever a partial may occur

vernal atlas
#

raw is undocumented, because it emits the raw websocket data

slate nacelle
cold basin
#

would it be handy to add a guild property to DMchannels

#

which is actually the user

slate nacelle
#

There is recipient, isn't there?

cold basin
#

and dont keep asking

real jetty
#

its easier to tell them guild is null in dms

#

because it actually makes sense

cold basin
#

¯_(ツ)_/¯

ornate topaz
#

no, because guild would no longer mean guild

cold basin
#

thats true

ornate topaz
#

so you actually could not do message.guild.roles or anything similiar

real jetty
#

that just makes things even more confusing

cold basin
#

yeah ok fair enough

oak quail
#

honestly, imo its ok (but a bad idea) to not document the raw event, but its really dumb to not put it in typings

unique axle
oak quail
#

imo the typings should cover the entire library

real jetty
#

yes but thats not a public aspect of the library

haughty tide
#

Why don't you create a separate typings file and point somewhere that this file exists for those who want to use the whole power of the library?

ornate topaz
#

"whole power"? you mean "unrealiable power that can change at any point without any warnings, as its undocumented"?

copper laurel
tacit crypt
#

I mean, we can type the raw event as "unknown" so it's up to you to either type it or use a typings library for it shrug

raw is this middle-ground between undocumented and documented, it's a slightly more uh.. raw than what Souji linked, and what you should most likely use (cause raw includes things like the sequence and op and stuff, which for most is really NOT needed, however YMMV)

fallen arrow
#

i have a question about TextChannel#startTyping, from what i understand it was built so the promise resolves once the bot finishes typing, however it seems a little counter-intuitive considering all other api methods resolve as soon as the request returns a response. Doesnt this prevent the user from properly awaiting it for example at the beginning of a command?

#

for example, you cannot do the following because startTyping will never resolve ```js
await message.channel.startTyping();
await message.channel.send("test");

unique axle
#

correct, the promise will resolve once the typing has ended.
correct, awaiting it like this will wait for the typing to end before continuing, consequently never continuing

snow crypt
#

can we add an option to not wait for stopping to type?

fallen arrow
#

currently the only alternative is not awaiting, which introduces a possible race condition

tacit crypt
#

IIrc you can pass a count too

snow crypt
#

?docs textchannel.starttyping

rich iglooBOT
unique axle
#

i don't really see the use case tbh, and passing a count does not change the behaviour of the returned promise

tacit crypt
#

well, passing 1 WILL make it return

snow crypt
#

but also end typing

unique axle
#

if you pass 1 the exact same happens, it stars the typing indicator and the promise resolves when the adequate count (1) of stopTyping has been called

snow crypt
#

well, what about the option idea?

fallen arrow
#

the use case is being able to ensure the typing indicator has started before proceeding with the command, otherwise there is a possible race condition where the command's response will be received by the api before the typing indicator, which makes the bot send the response first and start typing afterwards

tacit crypt
#

unless someone PRs a sendTyping (which is just await this.client.api.channels(this.id).typing.post())... Nothing stops you from using the raw API

fallen arrow
#

sure, there is always a workaround

vernal atlas
#

wouldn't be too difficult to perhaps create a function that listens to the typingStart event

#

for yourself - not in the library

#

but perhaps a wait boolean parameter for the sendTyping function could work?

#

which would of course determine if the promise should wait until.the typing has finished

#

does the count parameter even... work? i don't see it being decremented anywhere in the startTyping function and testing a startTyping(1) doesnt seem to resolve

#

ok yeah im either stupid or the count parameter doesnt even do what its supposed to

real jetty
#

Maybe adding an actual error for when you try to ban a guildmember while not providing an object as options would be nice 🤔, for now it gives an Internal Server Error which gives the user no information

oak quail
#

might be a change due to the new update, as djs updated to the new preferred discord behavior which is iirc sending a json object instead of query params

copper laurel
#

Yeah, the change mentioned above resulted in the API returning an error when invalid data is passed instead of... whatever it did before, possibly resolving a ban but not passing the reason
The error would be the same as the TypeError for Message#delete
I agree the response isn't meaningful to what they did wrong, but having said that, if they bother to read the docs and use the ban method correctly it won't be encountered

vernal atlas
#

should Client#generateInvite have options for other query parameters for the invite other than permissions? eg preselcting a guild, redirect URI etc

unique axle
#

i'm not too sure what you mean there with the count parameter not working?
.startTyping(1) -> .stopTyping()
.startTyping(2) -> .stopTyping() x2
.startTyping(3) -> .stopTyping() x3
and so on. i tested that up to 5 the other day, could not see any misbehaviour in the counts

discord.js heavily diverges from how typing works api wise, we keep the typing indicator alive as long as not all typing "instances" are resolved (the count is decremented through stopTyping to the point where none are left) and sending a message does not resolve the call, but has to be done manually.

and as was pointed out above you can't await the start call as is right now, since it resolves only after the typing is fully resolves (has stopped)

unique axle
#

should Client#generateInvite have options for other query parameters for the invite other than permissions? eg preselcting a guild, redirect URI etc
https://discord.com/developers/docs/topics/oauth2#bot-authorization-flow sure, the redirect is really just useful for the non-invite generation, unless i'm missing something?
You'll also notice the absence of response_type and redirect_uri. Bot authorization does not require these parameters because there is no need to retrieve the user's access token.
Since all are optional probably best with PermissionResolvable|object and deprecating the first.

vernal atlas
#

sweet

#

so do you have to actually call stopTyping?

#

i was under the impression the route was called count times, and resolved on the final call

snow crypt
#

what are the marked ones for?

wild flax
#

Those are all legacy and we’ll prolly not use them anymore except for v12 @snow crypt

snow crypt
#

so is the current repo gonna move to a legacy repo when next goes live?

#

next being the typescript one

wild flax
#

no

#

next will be merged into the current repo

#

but the tags/labels won't be the same most likely

velvet tide
#

so i realized the docs and typings dont have syncID for the Activity class. I decided I will make a PR because it'll be useful. What exactly should I put for syncID's jsdoc comment?
Can anyone provide input on this? i did some further digging and found this PR related to it https://github.com/discordjs/discord.js/pull/2314 with the commit message spotify stuff. So should I put the comment as The ID of the Spotify track?

#

should Activity.syncID be documented, its the track ID for a spotify status, except syncID doesnt really give that away so maybe under a different name?
@vernal atlas my apologies for pinging you, but i'm in the same boat as you are and hoping to get a conversation out of this as well

velvet tide
#

so it seems the reason its not documented is because Discord API docs doesn't even document Activity#sync_id because that's their intention? ( https://github.com/discord/discord-api-docs/issues/1239#issuecomment-563425694 ) but I'm also reading this issue comment ( https://github.com/discord/discord-api-docs/issues/545#issuecomment-370604860 ) that sort of backs the previous one, but it's been 2.5 years since that comment has been made and I believe the Spotify integration has matured since then? Someone even questioned the relevancy of the property here ( https://github.com/discord/discord-api-docs/pull/436#issuecomment-349790557 )

So overall, does this go up one level higher to the Discord team to consider adding this? For now, I ended up extending the Activity interface myself and defining that missing property. I'm in limbo on it in general for submitting an issue to discord.js, but potentially the Discord API docs repo instead? Thoughts?

unique axle
#

undocumented fields might change name or functionality at any point without further notice. due to that discord.js just implements (and accepts PRs for) upstream (discord-api-docs) documented fields. If you get them to document it it's relatively surely going to be added.

* we can't promise semantic versioning if we introduce a change that might result in breaking functionality, discord mostly doesn't break documented fields

velvet tide
#

I see. I think I'll go upstream with this. Thanks for the input @unique axle

glad sparrow
#

what will Collector use if there is no time (in collector options)

unique axle
#

this is not a support channel, whatever other ending criteria you give it, if none - none

vernal atlas
dapper leaf
#

are there any plans of porting discord js to deno in the future many people have made their own attempts but they lose support in a month or 2

unique axle
#

no current plans, has not been discussed - might become easier after the planned typescript rewrite or be considered during it

dapper leaf
#

ok

copper laurel
#

@vernal atlas not sure what you're pointing out here honestly - what are you suggesting it should extend?

vernal atlas
#

you can extend the classes Presence and TextChannel via Structures.extend, however ClientPresnce and NewsChannel extend those classes (respectively), but they don't extend the custom-made extended class

#

a bit like how ClientUser extends User

copper laurel
#

Ahh gotcha. So you're suggesting they should extend the extended Structure, if that's even possible

vernal atlas
#

the ClientUser export is a getter so it can properly get the User class from Structures.get

#

yea

vernal atlas
#

well

#

all channel classes extend Channel

lofty beacon
#

I had a look through the events on the client and there isn't one for when messages are swept, so could that be added?

This would also work when calling client.sweepMessages() along with the automated interval system.

real jetty
#

the debug event emits whenever messages are swept. it's quite crude, but you could filter through debug messages (i.e. not the WS ones) then emit your own event based on that

vernal atlas
#

you could also extend the client class and override the sweepMessages function to emit an event 👀

lofty beacon
#

oh yea lol

#

also, there isn't such thing as a message.quote, might be cool.
ex:
if a message had the content of hi and you called the quote method with hello as the content it would resovle this:

> hi
@user hello
ornate topaz
#

what would be a use case for that

unique axle
#

As discord themselves are planning to remove that feature in favor of proper reply (which may or may not get proper bot API support at some point) I don't personally see much value in this

lapis talon
#

Yeah that new quoting thingy is pretty epic

vernal atlas
#

the API seems to have stopped sending embed_enabled causing Guild#embedEnabled to always be undefined, rather than a boolean as it should be, should this be left as-is or perhaps changed to use the widget_enabled value?

wild flax
#

Considering we can’t just up v13 for this, yes

#

The latter

vernal atlas
#

O wait- embed_enabled/widget_enabled doesnt/never come with the initial GUILD_CREATE packet

#

but it perhaps should be cached with the fetchWidget/fetchEmbed method, ill pr that

oak quail
#

has that changed, or was it always like that?

vernal atlas
#

thats what puzzled me at first because i could've sworn it was sent with the initial packet

oak quail
#

i'd make an issue on discord-api-docs

vernal atlas
tacit crypt
#

Guilds do not store this metadata, so it isn't returned in guild creates

GUILD_UPDATE contains them

#

logic 200

vernal atlas
#

would it make sense to make fetchEmbed just return this.fetchWidget() to avoid duplicated code?

tacit crypt
#

Ye, and mark as deprecated

vernal atlas
#

ye, already deprecated, the same for setEmbed too?

#

they both hit a different endpoint, guilds/:id/embed and guilds/:id/widget, but yield the same result, which is why im asking first xd

oak quail
#

/embed is removed in api v8

#

which is why the djs embed stuff was deprecated

vernal atlas
snow crypt
vernal atlas
#

im tryna implement the changes from https://github.com/discord/discord-api-docs/pull/1886/files into a PR - but the short of it is should i make a new class for IntegrationAppliation or just use the ClientApplication class

making a new class would essentially just be the same as ClientApplication, but without botPublic,botRequireCodeGrant, cover, owner, and rpcOrigins

#

perhaps an Application interface/base class?

#

i think that would actually be a good idea

snow crypt
#

@vernal atlas why not have includeApplications just true by default

#

like, not even an option

#

just always true

vernal atlas
#

well, i thought it best to add the option & default it to what discord defaults it to

#

oof just made me realise i forgot the typings

snow crypt
#

@vernal atlas well they could have done the same thing with webhook ?wait

#

but i really wonder, why not

#

it's not like it will be breaking

#

or cause anything unpredictable

#

i say just have it always true so you always have the application

vernal atlas
#

perhaps default to true, but still have the option if you need it

snow crypt
#

why would i explicitly NOT need it?

#

yeah i might not really have a use for it

#

but in what case is it gonna be "it must not be sent"?

vernal atlas
#

well, it would be easier for a user to filter out bot & webhook integrations

snow crypt
#

can you explain?

vernal atlas
#

well, if for whatever reason you didn't want to list bot & webhook integrations (eg in a command), simply passing false would be easier than (await guild.fetchApplications()).filter(int => int.application === null)

snow crypt
#

ohhh wait my bad

vernal atlas
#

did you think include_applications did something else?

snow crypt
#

yeah

oak quail
#

oldeyes PR #4762 was merged before the docs pr was merged

thorny copper
#

Why did you make separate methods for avatars (avatarURL and displayAvatarURL)? Why not merging the second one with the first one by making a parameter "callback", which could be an image (URL, buffer or anything else) or "default", which effectively returns default avatar URL?

warped crater
#

avatarURL yields the avatar given by Discord as is, null in case the user has none set
defaultAvatarURL gives back an asset from Discord's API with... a default avatar; calculated as they do it in the client
displayAvatarURL is simply a utility that either gets the user's set avatar, or their corresponding default (theoretically, what you should have on screen)

#

this design choice makes sense to me, and either way, it can not be changed as this would be breaking

thorny copper
#

(Yes I know this would break existing code, but why not a change for DJS v13)

wild flax
#

I don't see a huge benefit in merging them

#

Nor a huge downside in leaving them as is

warped crater
#

^ the way it currently is actually allows you to tell if the user has no avatar set

thorny copper
snow crypt
#

Util.resolveColor returns NaN instead of throwing.

unique axle
#

summary:
https://github.com/discordjs/discord.js/commit/0d4eab8d241e770cbea065688ccf85aa93fe07d1#diff-fb4312d30636f670d026660847d06636R368 https://github.com/discordjs/discord.js/commit/b1473b1e4cdecc782ead80c06ff447d94479e5e4#diff-dd560c495a00593ea828a458e5e13b18R115-R118

  • has this behaviour since Jan. 2017 Dec. 2016
  • potentially breaks build pipelines for people using it that way
  • inconsistency is bad (it should probably throw)
  • still erring towards semver:major which makes this v13 earliest

thanks space for digging shibaHeart

slate nacelle
halcyon field
#

Add something like .bannable but for ".dmable" (checks if the user can be dm'd)

copper laurel
#

Discord has previously said no to this request anyway. They prefer to have the API call to send the message reject than have developers making two API calls for every DM - check + send.

deft holly
#

Think this has been asked several times here but with no response 😕 what's the reason https://github.com/discordjs/discord.js/pull/2910 hasn't been merged? Does it count as a breaking change in some way (please excuse my ignorance on this topic :P)

vernal atlas
#

its got a semver: minor label on it, and there dont seem to be any breaking changes, so no its not a breaking change

crimson harbor
#

Sorry for a dumb question, but I'm not sure how to use util.deprecate on a class method.

#

Nvm, I figured out that you use Class.prototype

copper laurel
#
GuildMember.prototype.hasPermissions = util.deprecate(GuildMember.prototype.hasPermissions,
  'GuildMember#hasPermissions is deprecated - use GuildMember#hasPermission, it now takes an array');```
#

Theres an example from v11

patent halo
#

How does discord.js handles rate limit internally? PepoHmm

left moat
#

check the code

patent halo
#

i dont get it, somewhat

patent halo
#

Ahh, like a queue

cursive shuttle
cursive shuttle
#

Similarly, Discord always emits GUILD_BAN_ADD with a full user object, meaning guildBanAdd will never emit a PartialUser even though it's marked as such in the typings

#

Again for GUILD_BAN_REMOVE

#

newUser in userUpdate shouldn't be partial either as userUpdate always includes a full user structure

fallen arrow
#

currently there is no way to define guildsPerShard when using internal sharding set to "auto". Can i PR a client option for it?

#

well i guess one could always manually call Util.fetchRecommendedShards and feed its result to the client, so nvm

vivid field
slate nacelle
#

I'd say that's a bad autocomplete of my editor and should have been this.

vernal atlas
#

PR'd it

#

would it make sense for ChannelManager and GuildChannelManager to have overloads for the resolve function with a type parameter, so you could use
guild.channels.resolve<TextChannel>(...) or similarly, client.channels.resolve<DMChannel>(...) for the client

copper laurel
#

How would that handle the ID not being a text channel ID though

vernal atlas
#

well, this would be similar to just casting it yourself, except its just a little cleaner for typescript

snow crypt
#

might as well just <TextChannel>client.channels.resolve(id)

vernal atlas
#

ig

drifting knot
#

so collection.filter doesnt do great with typescript

#
import { A, B, isTypeA } from '../classes';

const collection = new Collection<A | B>();

// ...

const aCollection = collection.filter(item => isTypeA(item));

// aCollection is still typed as Collection<A | B>
// It should be typed as Collection<A>
#

can we use type guards or assertions or some other TS feature to make the return type match whatever the filter predicate is doing?

#

i'm asking because i don't like having type assertions for things like filtering a bunch of channels to just be voice channels

deft holly
#

it's worthwhile to note that Array#map has the same behavior. I doubt there's a way to fix the typings for this in a sane way since

  1. you'd probably need TypeScript to infer the return type of a function (the predicate) when called with a specific set of arguments which isn't really possible currently
  2. Array#map would have been updated with proper typings if this were possible easily

the only alternative then is something like collection.filter<string[]>(predicate: ...) which would then result in a string[] but I don't think this a big improvement over just typecasting

drifting knot
#

thats a good point

#

i kinda like the idea of passing a type param to Collection#filter

#

but i can just do const a = whatever as unknown as Thing

deft holly
#

found a github issue about this. Does seem like it's not possible without explicitly typing the value though which is unfortunate - https://github.com/microsoft/TypeScript/issues/16069

update 2:
seems like supporting type guards can actually be supported through the following overload:
filter<S extends T>(callbackfn: (value: T, index: number, array: T[]) => value is S, thisArg?: any): S[];
(this is for Array but the concept can be applied to Collection as well)

basically, this would allow -
const foo = collection.filter((x): x is undefined => x === undefined);
foo is then typed as undefined[].

long basalt
#

I got something that feels like a bug, but cant tell, I also dont know if this is the reason its happening, im not a expert on the request handler. so the bug is, when multple items are in queue and a 400-500 error, it wont continue in the queue, just reject. in result, some stuff will just hang indefinitely until a request gets added to queue and it continues to handle requests until it runs into that error, im not fully sure this is why it happens, its just what I think is whats causing it, im also not sure if this is a bug or not

tacit crypt
#

Known, reported and will be fixed 👍

long basalt
#

is there a pullrequest or not yet?

#

anyway, I think im going to evade the issue by awaiting before adding another request to queue

random shell
#

is there anything special I need to do when importing the webpack version (I'm using 12.3.1) via a <script> tag?

#

it seems to always result in errors, so I feel like i am missing something

vivid field
#

about to implement the newschannel following feature, would targetChannel.follow(newsChannel) or newsChannel.follow(targetChannel) fit better into the structure of the library?

vernal atlas
#

i would go for NewsChannel#follow

crimson harbor
#

I think that NewsChannel#addFollower would be a better name.

ornate topaz
#

Imo that points slightly more towards a user than a channel

deft holly
#

typings: any plans to use named tuple elements (ts 4.0 feature) for the ClientEvents interface? benefit of this is that client.on('message', ...) - intellisense no longer shows args_0, args_1, etc. as the names for the parameters but rather the labels

For what I mean by this, see the following two screenshots. If you can't see the difference, it's args_0 vs name.

This may be a breaking change for TS users not on 4.0 though

oak quail
#

API/GW v8 changes:

  1. permissions is now back to the original field, as a string.
  2. game fields are now removed, replaced with the first element in activities. For widget endpoint, game field on users is renamed to activity, since there's still a singular field.
  3. Channel Permission Overwrites have their type field serialized as a number (e.g. 0) instead of a string (e.g. role)
  4. embed_enabled and embed_channel_id fields are removed, replaced with corresponding widget_ fields.
  5. Form error responses now have a format that is better aligned with "regular errors".
  6. Rate limit headers are sending seconds instead of milliseconds now. As such, the X-RateLimit-Precision header is no longer respected.
  7. Bots no longer get CHANNEL_CREATE for DMs on v8.
  8. Many routes have been deprecated. (Consult: https://github.com/discord/discord/pull/29722/files)
  9. Bans delete-message-days is no longer available. Use delete_message_days instead.
  10. Removed roles, premium_since, and nick from Presence Update gateway event.
vernal atlas
#

that link is a 404 page ASC_PepeThinking

unique axle
#

of course. that's not discord API docs, that's discord/discord it's not public.
that information is a direct copy from the DM of mason with one of their engineers

vernal atlas
#

yeah figured the repo wasnt public, just wanted to point that out incase it was meant to be a different link

copper laurel
#

@deft holly technically speaking we don't consider the typings to be breaking changes since its a JS lib, however one that major is probably worth holding off on. discordjs-next is a TS rewrite though so we can definitely make use of it there

vernal atlas
#

well- maybe that property isnt the best example but im sure theres others
edited to a better example

tacit crypt
#

Eh. I just document the types, how they come is not something i should spend time documenting... Plus I link the direct object url so people can read when using it

vernal atlas
#

oki

tacit crypt
#

Besides.... Think about it this way: properties can come and go at random from different places... And may even be changed randomly, requiring a patch release for it

oak quail
#

well

#

owner and permissions are based on the specific context of "get current user guilds"

#

because its "is this user the owner" or "what perms does this user have"

real jetty
#

Is it not possible to add the "GuildMember" who triggered an event on events such as channel create/update/delete as a parameter?

unique axle
#

we can only implement features around data discord provides, this is not provided by discord

#

"who did something" will always work through audit logs only

real jetty
#

Can it not be pulled by the lib through audit?

#

so the user doesn't have to do it for each event?

unique axle
#

the library does not auto-fetch data.
additionally audit logs are not guaranteed to have arrived when the websocket event does
(there's also a bunch of other caveats, which i won't get into here)

#

so: no, we can not do that

mint iron
#

What the utility for each folder inside packages in discord.js-next?

#

For example where should goes structures like Message, Guild...

tacit crypt
#

Those are probably gonna go in packages/discord.js

#

each folder is a submodule

#

for instance rest will host everything rest related

drifting knot
#

since new djs will target new node, can snowflakes use bigints please

#

idk if this is a "node doesnt support it" issue or a "we have been using strings for 999999 years" issue

raven juniper
#

Discord does provide them as strings on the API, so I suppose one question would be if we'd want to convert it, iirc we don't change any other API types

vernal atlas
#

i think there was a discussion about this, i remember it being said that it seemed silly to just convert back and forth between strings and bigints all the time

drifting knot
#

doesnt erlpack use proper int64s

#

also its like 2 operations

#

if its all written in TS it shouldnt be an issue

#

just call id.toString()

#

it will never fail

drifting knot
#

my user id takes up 36 bytes of memory as a string, a bigint would take up 24 bytes

#

for a large bot you could easily be saving 1-2 mb ram lmao

tacit crypt
drifting knot
#

how

#

surely this is because erlpack is still written as if bigints dont exist in electron or wherever they're running their code

copper laurel
#

Just because they exist doesn't make them a particularly good type to use

vagrant holly
#

Wait wait wait

#

ShardingManager and Shard cache eval calls?

#

Dang that's why sharding is so fucked

vagrant holly
frank turret
#

I know role#equals just compares properties from both roles, but is it really needed/within the scope of the library to provide a method like that? Even in the methods description it advises a person to just compare the ids for most use cases. I understand it would be a breaking change, but would it be worth opening an issue/making a PR regarding removing it?

oak quail
#

its for internal checks

frank turret
#

Fair enough, my next topic is out of the list of v8 changes (for discord-api-types)(https://github.com/discordjs/discord-api-types/issues/12#issuecomment-692972229), I made a sub list of which changes are actually related to the issue itself. Could someone look it over and inform me if I'm mistaken about anything?

APPLY:
>permissions is now back to the original field, as a string.
>Channel Permission Overwrites have their type field serialized as a number (e.g. 0) instead of a string (e.g. role)
>Removed roles, premium_since, and nick from Presence Update gateway event.
>embed_enabled and embed_channel_id fields are removed, replaced with corresponding widget_ fields.
DONT APPLY:
>game fields are now removed, replaced with the first element in activities. For widget endpoint, game field on users is renamed to activity, since there's still a singular field.
>Many routes have been deprecated.
>Bots no longer get CHANNEL_CREATE for DMs on v8.
>Bans delete-message-days is no longer available. Use delete_message_days instead.
>Rate limit headers are sending seconds instead of milliseconds now. As such, the X-RateLimit-Precision header is no longer respected.
>Form error responses now have a format that is better aligned with "regular errors".
deft holly
#

About the stores -> managers change (yes, I know I’m several months late on this):
Have shortcut methods like XYManager#filter() (which calls XYManager#cache#filter() internally) been considered? From my (admittedly poor) understanding of the issues at hand (https://github.com/discordjs/discord.js/issues/3485):

Poor Inheritance
Since the design doesn’t really change from right now, I don’t see why this would be an issue.

The design is not extensible
As XYManager#filter(), XYManager#find() and so on simply call their respective cache methods internally I don’t see why this would be less extensible than the current approach either.

Naming conflicts
An example of a naming conflict before was MessageStore#delete vs MessageStore#remove (which deletes the message and which removes from the cache?). This would be solved by simply not creating an alias for MessageStore#delete -> MessageStore#cache#delete, i.e MessageStore#delete would make an API call and MessageStore#cache#delete would be used to remove the message from the cache.
I personally believe that the proposed change (shortcut methods) do not remove any of the benefits of managers without any significant drawbacks. About whether this change is needed – from the many, many users who complained about having to add .cache everywhere in their code, I believe that the majority of the user base would appreciate this change. In addition, as these are simply shortcut methods, no existing code has to be modified.

Looking forward to any thoughts about this, perhaps I’m missing something really obvious which prevents this from being a possibility in which case I apologize.

oak quail
#

@frank turret im pretty sure this will have to be changed too

game fields are now removed, replaced with the first element in activities. For widget endpoint, game field on users is renamed to activity, since there's still a singular field.

copper laurel
#

I both agree and disagree with what you're saying here @deft holly

#

The intention was to achieve a separation of API and cache - for that reason I'm not sure I totally agree that providing methods that call the cache from the Manager is necessarily the right approach.
However Managers themselves really don't act as a good API Manager yet - making API calls still relies on having the cached instances. For example, if you want to pin a Message, you have to get the Message object from cache, and call Message#pin.
A method like MessageManager#delete which lets you delete uncached messages by ID is a much better representation of how it should work imo (and Message#delete actually calls MessageManager#delete now internally, because the Manager is responsible for API calls)

This is something I'm working on literally right now now, providing much more extensive API coverage on the Managers so that they can fulfil their purpose, and better reflect that separation of "I'm making an API call" vs "I'm operating on the cached items" such as you would be with #filter.

deft holly
#

The intention was to achieve a separation of API and cache - for that reason I'm not sure I totally agree that providing methods that call the cache from the Manager is necessarily the right approach.
I agree that in an ideal world we would want to have this but the reality is that most Discord.js users do not really care about a separation of API and cache - no one (to my knowledge) brought this up when v12 was still using stores until the beforementioned issue was raised. It is a (admittedly mild) inconvenience to type .cache every time you want to access the cache, and I think having shortcut methods would mitigate that somewhat. I can absolutely understand not adding it though, as I personally don't find .cache to be too much of an issue :P It's just that I'm reasonably sure a lot of people would appreciate not writing it everywhere. It's just that I believe that Discord.js would provide a better experience for users of the library if not chaining .cache everywhere were an option (without causing more issues).

wild flax
#

While user experience is an important topic, I simply do not care what the "majority" does, when the majority follows youtube tutorials or does not know JS at a level enough to even write a complete bot by themselves

left moat
#

Also I would hope that a clientOption field is eventually introduced to change the cacheType of managers in v13 or in the next big v12 update

#

afaik this isnt a breaking change bc nobodies code will break because of it

unique axle
#

Making chaches be exchangeable is definitely on the roadmap, however more expected towards -next.
V13 will focus on adapting the existing js codebase (v12) to the new API versions.

vagrant holly
#

Gonna ask here cause I feel y'all might know better than the help channels, is there a good way to completely block a channel and its messages from ever being cached in the library (got a channel where each message has a solid 80MB+ of reactions data on it, so I'd rather just not deal with that channel ever)?

left moat
#

well you could just remove the bots perms to see anything in that channel @vagrant holly

vagrant holly
#

Not a channel that I have any control over at all, so curious if the lib has any decent internal way to block out a channel from caching at all

unique axle
#

please do not use this channel as an upgrade of help channels

#

no, you can not
you can sweep messages on an interval or modify source

vagrant holly
#

Is the raw processing of a new message exposed, or would the best bet be to just listen for a new message normally and then purge it from cache at that point?

#

If not, would it be worth looking at a way to add a custom callback/filter to a raw message arriving in the lib, or would that PR never get anywhere if created?

tacit crypt
#

Granular cache controls would be nice...but I don't think it'll be a priority for v12/v13? (don't quote me on that)
However, nothing stops you right now from creating a sweeper of sorts

undone ravine
#

messageCacheMaxSize is a thing also

vagrant holly
#

I have super strict sweeping set up for messages themselves with what the library provides in options, this seems to be coming from a small subset of messages that don't match the main sweeping criteria

vagrant holly
#

Is it possible to request an issue be assigned to me on GH?

vernal atlas
#

working on a PR to handle channel type changes (text => news, news => text), what would be the best way to handle this? just remove the channel from the cache and re-add it?

#

oh wait- its already handled

tender field
#

is there a plan to have better stacktraces in djs-next? I know it would require a lot of changes and i don't expect it to be on v13, but will it be taken into account for -next?

raven juniper
#

at some point yes, there will by async stack traces and will include the line of the code

#
DiscordAPIError[50006]: Cannot send an empty message
    at RequestHandler.makeRequest (/home/archid/workspace/alestra/node_modules/@klasa/rest/src/lib/RequestHandler.ts:192:11)
    at processTicksAndRejections (internal/process/task_queues.js:93:5)
    at RequestHandler.push (/home/archid/workspace/alestra/node_modules/@klasa/rest/src/lib/RequestHandler.ts:101:11)
    at async Promise.all (index 0)
    at Map.add (/home/archid/workspace/alestra/node_modules/@klasa/core/src/lib/caching/stores/MessageStore.ts:65:23)
    at default_1.eval (/home/archid/workspace/alestra/node_modules/klasa/src/commands/Admin/eval.ts:66:14)
    at default_1.run (/home/archid/workspace/alestra/node_modules/klasa/src/commands/Admin/eval.ts:24:43)
    at CommandHandler.runCommand (/home/archid/workspace/alestra/node_modules/klasa/src/monitors/commandHandler.ts:58:23)
    at CommandHandler._run (/home/archid/workspace/alestra/node_modules/klasa/src/lib/structures/Monitor.ts:110:4) {
  code: 50006,
  status: 400,
  method: 'post',
  url: 'https://discord.com/api/v7/channels/642137151626018818/messages'
}``` this is an example, you can see where it points to the command file where the occur originates from
tender field
#

incredible! did you write this from scratch or is this already available somewhere ? 👀 (like a branch or smthg)

raven juniper
#

it's not available yet, i'm not technically proficient enough to tell you where it comes from

#

i'm just a copy-paste monkey. i just know it's planned to be in an upcoming version of d.js, whether that's 13 or next, i don't know

tender field
#

ok thanks 😄 still really nice to see we might have better stacktraces at some point 🙂

left moat
#

djs-next/13 will most likely take design ques from klasa/core such as the ws/rest design

oak quail
#

well -next will be v14

#

but vlad said that v12.5/v13 might use the updated rest stuff

tacit crypt
#

Keyword might

unique axle
#

well -next will be v14
-next will be the next major at the point it's completed.

We might need to release another major before -next if discord decides to introduce breaking changes and release other versions of the API, which we might need to reflect to support new features

oak quail
#

@frank turret @tacit crypt for api-types, should we maybe keep most things only in v8 and just import&export them in v6 unless they're different

#

so not everything is duplicated

#

because theyre gonna keep updating v6

tacit crypt
#

Ehh.. dunno honestly
Personally I'd prefer duplication and once discord marks a version as basically dead, we delete it from the module

#

It'll be annoying sure.. but idk, depends what others suggest too

vivid field
#

shouldn't Client#emojis and Guild#emojis be separate managers? for one, the types are different (i.e. guild vs no guild) and also there's methods like create() accessing this.guild, wouldn't that throw an internal error when trying to do client.emojis.create()?

unique axle
#

DiscordAPIError: 405: Method Not Allowed does throw, correct

vivid field
#

so shouldn't the library handle that instead of sending an invalid request? just throwing an error when calling it from a client would probably be enough imo, but idk if that's seen as patch or major

unique axle
#

following the discussions here https://github.com/discordjs/discord.js/pull/4816#pullrequestreview-487356231 it'd be major (i'd also agree with that, it changes the "return type" of a function in the case of failure, which is then no longer a DiscordAPIError.

though as i mentioned earlier v13 will be needed to comply with new api versions and bring new features before the full rewrite anyways, so this might be the right time to propose a change here.
Maybe even on a larger scale, trying to spot and change similar occurences like this (though that could also easily blow out of scale)

solemn oyster
#

incredible! did you write this from scratch or is this already available somewhere ? 👀 (like a branch or smthg)
@tender field we'll likely do that for 12.5 (or 12.4 if Crawl doesn't release it before), the trick is that the new REST uses an async lock implementation, versus using stateful deferred promises

#

As such, the queue is done in a natural manner, and by design (unless V8 is bugged, which is not), it cannot deadlock, it cannot halt, errors bubble up naturally, the entire request can be retried entirely (adds support for retried AbortErrors!), and by design, it has proper async stack traces, which is done thanks to the fact that it does await this.queue.wait() before proceeding, it doesn't use middle steps nor makes an object representing the state, it just awaits for all the previous requests and then it jumps directly to the fetch()

#

A try/catch/finally tells the queue to resolve the first promise (wait obtains the last promise, it any, pushes a new deferred promise, and awaits the previous), it may be a little hard to understand, but it's really simple

#

But yeah, before I can use this, I need @tacit crypt to either give me async-queue's code, or upload it so Crawl can publish it, although it might be weird having @discordjs/core as depencency in 12.x

#

Since... that package is for 13.x

#

I still plan on using this ASAP, I have been trying to make d.js have useful stack traces for years, I think my first PR adding them (although it used V8-specific APIs, and broke error messages in some cases yet unknown to me) dated back to 2018, but Lewdcario and a few more people were having issues, so we had to revert it.

My point with telling you all of this is, it's not a new issue, we've been looking for a solution that works for everyone without needing to use non-standard things, and we have now found one :)

real jetty
#

how can VoiceChannels have a Channel Topic? Thonk

frank turret
#

it inherits from GuildChannel, which I guess has that. Shouldn't that be something more like on a TextChannel/NewsChannel?

real jetty
#

Yeah, according to discord api docs, only Text, News can have topics GWbruhThonkNoHands

frank turret
#

In addition to that, the setTopic method exists on GuildChannel but not the topic property (at least on the docs), leading me to believe this is a mistake?

copper laurel
#

I've raised before that the placement of properties on GuildChannel doesnt really make much sense

frank turret
#

worth opening a pr for?

copper laurel
#

Like Souji hinted at earlier, now is probably the time to make semver major changes

#

Its actually pretty extensive though

#

createInvite for example

frank turret
#

Well, at least for now I'll open a draft pr for removing it and putting it on textchannel

#

and since newschannel extends textchannel, i only have to do it on textchannel

copper laurel
#

Yeah make it a collab PR or issue or something

oak quail
#

speaking of semver major changes, maybe remove disableMentions (replace with allowedMentions) in v13?

frank turret
#

Should i apply the setTopic change to TextChannel or TextBasedChannel, since either way it will end up reaching NewsChannel

oak quail
#

@frank turret TextChannel, because DMChannel shouldnt get it

frank turret
#

Updated in the pr, do I have to do any wonkyness for the docs?

oak quail
#
  • Sets a new topic for the Text Channel.
  • @param {string} topic The new topic for the Text channel
  • @param {string} [reason] Reason for changing the Text channel's topic
#

this is unnecessary

#

just say channel

frank turret
#

Alright, will change

oak quail
#

while ur at it i'd change the description for .topic too

#

its inconsistent with the rest and is wrong for news channel

frank turret
#

wb the example, should i also make that channel.setTopic? that seems somewhat misleading

oak quail
#

well everything else is channel.

#

because it assumes that you have a variable named channel

#

also u gotta fix up the spacing and stuff so eslint stops complaining

tender field
#

@solemn oyster thanks for these explanations! I think i understood 😅
Looking forward to these change, then 😄

solemn oyster
#

@wild flax one question, are we allowed to use @discordjs/core in v12.x?

#

Or should I yeet AsyncQueue and port it to JS?

tacit crypt
#

I..don't see why we wouldn't be allowed to?

solemn oyster
#

Voilá!

#

@tender field in case you want to try it out 😄

tender field
#

This is really nice! Thanks 😄

solemn oyster
old kelp
solemn oyster
#

Yeah, it should, although, wouldn't that be rawPosition?

old kelp
#

I guess, but wouldn't that create a bit of inconsistency since GuildChannelManager#create and the endpoint both take the position as the param? the user could always just specify it themselves as well.

real jetty
#

Hey
What do you think about Message#awaitMessages return a Message object if Collection contains only 1 Message Object ?

old kelp
#

imo that's the expected behavior, it would be a breaking change if to do so. there are plenty methods that also do that, if you go at changing that yet - it becomes inconsistent with the rest.
see MessageManager#fetch, with the limit of 1, or GuildMemberManager#fetch with the query option, for instance.

unique axle
#

i heavily disagree with this, this makes the API and typings inconsistent and hellish to use. We can only do that with Collection#first because of the distinction no args/ amount

adapting this based on a number that's passed as optional parameter does not seem an improvement in usage

ornate topaz
#

that would change from always getting a Collection, with first() method to obtain a Message, to a Collection or a Message, making you need to constantly check how many elements your awaitMessages was supposed to collect.

oak quail
#

maybe followTo would be a better name then addFollower?

unique axle
#

is there anything speaking against just... #follow ?

oak quail
#

I thought it might be confusing as to which channel is following which

snow crypt
#

lets say you have channel1 - announcement channel; channel2 - text channel
channel1.follow(channel2) could now refer to either:

  • channel1 should be followed by channel2
  • channel1 should follow channel2
    it depends whether you write it as follow(follower) or follow(toFollow) which I find very confusing
warped crater
#

I... absolutely disagree here.

#

To me channel1.follow(channel2) makes zero sense

#

you have to follow, at the 3rd person, singular, it obviously refers to the channel you're passing in?

snow crypt
#

not really
yet i can't really phrase it in a clear way

#
  • you can call #follow on a channel, and now it is followed
  • you can call #follow on a channel, and you've just instructed it to follow another channel
ornate topaz
#

channel1.follow()
message.pin()

warped crater
#

not to mention how the news channel shouldn't have a follow method either way, imo

ornate topaz
#

to me it's clear - follow is method used on channel1

warped crater
#

which makes it even more clear

snow crypt
#

um
what would you use in that context instead of message.pin()

ornate topaz
#

channel.addpin(message)?

#

if you're asking about that

snow crypt
#

god language is weird

warped crater
#

okay

#

I just saw the status of the PR

snow crypt
#

i can't really explain it but not naming it follow makes sense

ornate topaz
#

imo, just like in the app, you follow an announcement channel, selecting into which channel it posts

snow crypt
#

so you want NewsChannel#follow ?

ornate topaz
#

so channel1.follow(channel2) would make sense, assuming c1 is news channel

#

yes, that would make it consistent with app, as well as logically with rest of the lib

warped crater
#

mmm

#

I feel like TextChannel#follow should also exist

#

to sit in fashion with other helpers

#

such as Member#ban literally pointing to Guild#members#ban

#

as for the naming of NewsChannel#addFollower im starting to see the issue lol

snow crypt
#

but naming them both follow just makes it confusing again which is what we tried to avoid in the first place

warped crater
#

probs fine keeping NewsChannel's as is, then

snow crypt
#

now we have news.follow(follower) and text.follow(news) and without static typings in there you just fuck readability

#

you could accidentally throw by trying to follow a text channel because you got the order wrong

#

you might want it to exist on both but naming them both the same, especially with inheritance, is just wrong

ornate topaz
#

followIn() for news?

snow crypt
#

i still agree with addFollower

ornate topaz
#

imo that sounds odd and everytime i look at that i think of users

snow crypt
#

same for folllowIn

ornate topaz
#

well, technically, news.addFollower() doesn't really say much on its own. something like "add follower, yeah cool". could argue that news.followIn() asks for a channel to be passed

tender field
#

I think followIn() is way clearer than chan.follow(chan) ^^

copper laurel
#

This is why documentation exists and has a description

tender field
#

that's true, but it doesn't mean that methods should be named anyhow

#

like when you write the code you have the documentation, but when you read someone's code you shouldn't need the doc

copper laurel
#

I mean... thats why they should comment their code

#

This is now offtopic though

tender field
#

well imo they should comment their code only if their fault that the code is not readable. If the library has confusing methods, it not their fault

oak quail
#

so, no to NewsChannel#followTo?

tender field
#

i find it clear too 🤷🏻‍♂️ but i think the conversation moved to #archive-offtopic 🤔 they proposed a manager

ornate topaz
#

nothing was really proposed

solemn oyster
#

@snow crypt as in, adding @private to AsyncQueue class's description?

snow crypt
#

yes

solemn oyster
#

Added 👍

#

Good call 😄

#

Added the comment, thanks! @snow crypt

snow crypt
#

with love 🎉

solemn oyster
#

Also @vagrant holly, do you have any progress on the message edit limit?

vagrant holly
#

Also @vagrant holly, do you have any progress on the message edit limit?
@solemn oyster I have some stuff locally that I'm testing out in prod, will probably make it into a PR in the next week or so 👍

vagrant holly
#

Just noticed this mem creep

#

From a heap dump of the shard, this array stands out as fuckin huge compared to any other shard

#

Any thoughts on figuring out what's causing this, not familiar enough with heap dump or lib internals

left moat
#

OR

#

kinda different idea but for follow mayb add it to guildchannelmanager?

#

guild#channels#follow(c1, c2)

raven juniper
#

That opens up more opportunities for a screw up, if they put the wrong channel in the news channel spot

#

Although it is more use of the manager, which I know was a discussion lately... Could see it, I suppose

left moat
#

also it makes it less bork when u have followTo on newschannel and follow on regular textchannel which will confuse people imo

#

and u can unfollow aswell

#

but imo unfollowing should be on channel but that may be a bit inconsistent

vernal atlas
analog oyster
warped crater
#

uh.. yes?

#

because its not part of the public api and shouldnt ever be?

#

its an internal property for handling your http requests

#

and should never be touched externally

analog oyster
#

what if I want to use it

copper laurel
#

Too bad, its private

warped crater
#

feel free to use it, but because its private anyone is free to change it to api2 just for the lols in any release and break your code

#

or for any other reason

#

you shouldn't make http calls that way

copper laurel
#

TypeScript wont let you use it though

solemn oyster
#

Just do Reflect.get(this.client, 'api') to bypass TypeScript's system, @analog oyster

#

Alternatively you can do (this.client as unknown as { api: any })

tender field
#

Hey what's the difference between TextChannel#overwritePermissions and TextChannel#createOverwrites ? They both replace the existants overwrites, and it's just that the later takes a userOrRole and overwrites, where the former takes an array of objects with userOrRole and overwrites

vivid field
#

overwritePermissions clears all permissionoverwrites and applies the ones provided
createOverwrite clears only the permissionoverwrites of that user/role and applies the ones provided
updateOverwrite clears nothing and updates the permissionoverwrites for that user/role

vagrant holly
#

This mem creep/leak continues to grow. Any tips of getting to the root of it? Feels internal somewhere

copper laurel
#

Respectfully something "feeling" internal isnt a lot to go by haha, would probably be best to discuss outside this channel until we have something more conclusive to look into the library for

vagrant holly
tender field
#

@vivid field ohh ok fair enough, but maybe the doc should explain that better ^^

vagrant holly
#

bad shard

#

good shard

oak quail
unique axle
#

issue link please, i want to track that

gaunt flare
#

me too because I just tried to start using djs in a browser. djs claims to support browser but i'm not actually sure it does anymore? I'm running into CORS issues which lead me to https://github.com/discordjs/discord.js/issues/4710 (which you also just commented on recently)

vernal atlas
vernal atlas
#

also, should an error be thrown for GuildChannel#edit if a parentID was passed, but couldn't be resolved? as GuildChannelManager#resolveID returns null in that case - which will have the un-intended effect of removing the category from the channel

oak quail
#

@gaunt flare djs supports it but Discord seems to have blocked it

gaunt flare
#

🤔 hmm that's unfortunate...

oak quail
#

as a temp workaround you can try {http: {api: 'https://discordapp.com/api'}} in your clientoptions

#

that may break in the future tho

oak quail
#

oh, it merged as addFollower, f

drifting knot
#

when djs next gets released can it be under the package discord

#

2 emails to npm and they will give it to you

#

no publishes in 8 years

#

here is the email

to: msteigerwalt@gmail.com
cc: support@npmjs.com

Hi,

I'm writing to see if our organization Discord.js could use the "discord" package you published 8 years ago.

Thanks,
Discord.js Representative
#

the package will be yours within 4 weeks

oak quail
#

but why

#

also it might sound too official

ornate topaz
#

discord*.js*, discord*.py*, discord*.rb*
those aren't there for show

drifting knot
#

npm explicitly requests you dont name package with .js

ornate topaz
#

but discord.js is not discord

drifting knot
#

keep the github as discord.js

#

make the package discord

ornate topaz
#

but why

#

what's the point

drifting knot
#

its cool

#

and follows npm convention

ornate topaz
#

what convention

drifting knot
#

Don’t put “js” or “node” in the name. It’s assumed that it’s js, since you’re writing a package.json file, and you can specify the engine using the “engines” field. (See below.)

ornate topaz
#

where is that

drifting knot
#

many other packages do this

#

ex. google is an unofficial lib for using google search

#

google is also heavily active on npm, but they use their scopes of @.google-cloud, @firebase, etc.

ornate topaz
#

also, it's a tip

#

not a rule

#

it's a tip because google.js sounds worse than google

#

but discord.js is not discord

drifting knot
#

i didnt say rule i said convention

ornate topaz
#

it's a tip

#

and it's explained why it's a tip in the second sentence

#

also, even if, this will cause literally nothing more than confusion

#

using discord to code bots for discord.

drifting knot
#

logical

ornate topaz
#

anyway, that went offtopic.

drifting knot
#

people already import it as

const Discord = require('discord');
ornate topaz
#

what

drifting knot
#

module.exports

#

when people import the whole module

#

but you use the cringe discord.js

ornate topaz
#

cool, they can also name it lkidfhgkjdfghbkjhdfgekjlihvdfkjbh, should we rename package to that?

drifting knot
#

yes

#

simply begin annexing package names

ornate topaz
#

ok, case closed

drifting knot
#

i am going to take the discord package name and publish malware to steal bot tokens

ornate topaz
wild flax
#

We can double publish packages, that should be no issue

tacit crypt
#

For all intents and purposes, it would be better if Discord themselves claimed that name, not us

solemn oyster
#

Should AbortError retries be tied to its own option, or share with the 5xx one?

snow crypt
#

when would you deploy the new changes to npm?

solemn oyster
#

tfw noticed a type bug while trying to fix 3471... I re-arranged the handler to be... easier to read - handle 2xx and 3xx, then handle 4xx, inside it, 429, then handle 5xx

#

Also, this comment was written 2 years ago, it's not really true, at least, not for today's spec:js // NodeFetch error expected for all "operational" errors, such as 500 status code

#

Both of those codes resolve with 500 and 501 respectively:js require('node-fetch')(`http://httpstat.us/500`).then(r => r.status);``````js require('node-fetch')(`http://httpstat.us/501`).then(r => r.status);

real jetty
#

Heya, I was messing around with guildMemberSpeaking on a new project that I forgot to install the voice dependencies for. On the latest version, when I try to play a stream that I've received from a user (so, voice audio), it fails silently if I dont have the dependencies installed. This seems to be different from previous versions, like 12.2.0, where it would throw an error if I was missing deps.

#

Not sure if this is intended and whether or not I should open an issue for this

real jetty
#

Actually, scratch that, that may have been a fluke while listening on guildMemberSpeaking. The event doesn't seem to be firing at all, and I'm not the only one with this issue

solemn oyster
#

@tacit crypt read above please

tacit crypt
solemn oyster
#

wdym

tacit crypt
#

Uh

#

remove the comment if its inaccurate

#

and i guess keep the rest of the code as is?

solemn oyster
#

I moved code around because the flow was hard to understand

tacit crypt
#

thats fine

solemn oyster
#

Because it was handling this way:

2xx/3xx
429
5xx
4xx

#

I made it be:

2xx/3xx
4xx

  • 429
  • !429
    5xx
tacit crypt
#

coool

solemn oyster
#

I guess by removing the comment, you meant Isa's comment (git blame points to her). I replaced it withjs // Retry the specified number of times for request abortions

tacit crypt
#

ya

real jetty
#

Actually, scratch that, that may have been a fluke while listening on guildMemberSpeaking. The event doesn't seem to be firing at all, and I'm not the only one with this issue
@real jetty I seem to have found the solution to this problem
https://github.com/discord/discord-api-docs/issues/808#issuecomment-457962359
Now you cannot receive anything unless you first send several packages through the UDP connection.
This issue describes it.
Would it be possible to add this to the library so we don't have to worry about sending empty packets first before listening to user streams?

ornate topaz
#

@real jetty tmk library already does that, but you still have to send some data before receiving it.
There's also a fact that voice receiving is not documented, and is changed from time to time

real jetty
#

Yeah, as I figured from the issue. I just spoke with someone from #archive-djs-v12-voice-deprecated and they said the solution to listening on guildMemberSpeaking was to send an audio file at volume 0, but then what's the difference between that and creating a readable stream from /dev/null LUL

ornate topaz
#

That audio files are not os dependant shrugCat

real jetty
#

lol guess so

lofty birch
#

When will #4835 be published? I see it's been merged

copper laurel
#

Whenever 12.4 is released, we don't do scheduled release cycles

solemn oyster
#

@lofty birch at very minimum, 4852 needs to be merged before releasing, because I introduced a bug in that PR

#

I didn't notice the bug because it's only noticeable when you do an instanceof check, which I didn't during testing

snow crypt
#

well

#

both merged now

#

any release soon?

unique axle
#

as per usual we do not give an ETA on releases

tacit crypt
#

@unique axle how is a major change? In relation to the edit limit

You're still holding edits, and for 99% of people it isn't even a problem we'd now hard limit to 100

Even then, we could just... Default to -1, thus minor

unique axle
#

it changes the public facing behaviour of the library, how would it not be major?

#

currently there is simply no limit on it, any form of imposed limit by default is thus changing and major

#

-1 being "no limit" would make it minor, sure

tacit crypt
#

it changes the public facing behaviour of the library, how would it not be major?
@unique axle it doesn't change anything public facing. The edits array is the same, and its contents. What it changes is a "limit" (that for all intents and purposes is not breaking at all)

#

An internal limit at that

unique axle
#

pardon? before you could access 51+ edits, now you can't, how would that not be breaking?

tacit crypt
#

who says you can't

#

message.edits[51] is not different. the only diff is how big that array WILL grow (and come on man you can't find me a person who DEPENDS on that many edits [also i won't comment how personally i dislike the idea of the array but alas])

unique axle
#

huh? if you limit an array to a max length of 50 where before there was no max, that's a change in behaviour
or am i completely misunderstanding this pr

tacit crypt
#

which, fyi, for all the user knew, it could've been limited at 10 or 100 or Infinity.. shrug

#

Look, idk, I don't agree with setting the limit to 100 being a major change. If it is, thats stupid semver wise, and at that point for every thing we now let you control its cache we.. release a new major??

#

(assuming we don't have 1 big PR with it, but split it into pieces)

#

and fyi

unique axle
#

how is that stupid? what? i really don't get it
you set a default limitation where there was none before
adding the ability to let the user manage this is minor, if it behaves the exact way it did before the change by default
as soon as the default behavior changes in any way that's semver major

tacit crypt
#

MAJOR version when you make incompatible API changes,
MINOR version when you add functionality in a backwards compatible manner, and
PATCH version when you make backwards compatible bug fixes.

#

its not incompatible at all

unique axle
#

introducing a limit where none was is def. incompatible

tacit crypt
#

...you what?

#

Adding a configurable limit is in no way incompatible api change in my eyes

unique axle
#

but the default behaviour changes

#

if you have to apply a configuration to get the same behaviour you got before without any that's breaking

tacit crypt
#

No, cause its backwards compatible

unique axle
#

only if the default is no limit

tacit crypt
#

you added functionality (cache size limit), that defaults to 100 ("major") BUT you can set to (-1) => MINOR

unique axle
#

if you default it to no limit it's minor, yes
if you default it to 100/50/x it's major

tacit crypt
#

HOW

#

Souji. You CAN SET IT TO THE BEFORE LIMIT

unique axle
#

you have to apply a setting in a minor release?

#

you have to add code to set it to that

#

you have to make a change to your code base after updating to get the exact same behaviour

tacit crypt
#

you have to add between 1 and 3 lines of code MAX. Even then it's still backwards compat imo

unique axle
#

the whole idea behind semver is you can update the dependency without anything breaking without you having to apply any change, whatsoever

#

as soon as you have to now apply a setting to get the same behaviour as in the earlier version you made a breaking change that requires someone to maintain their code base

tacit crypt
#

I don't see it like that

unique axle
#

that is legit what semver is for

tacit crypt
#

I'm referring to the "requires a setting => major"

#

Not the versioning itself

#

If I delete the prop altogether, thats DEFINITELY major (INCOMPATIBLE API change, no more edits prop)
If I artificially LIMIT the prop to have a length of 50, it still has the prop, its still there shrug

lofty birch
#

An update where you have to change anything to get the same behaviour is breaking

unique axle
#

you still changed how a public facing part of the library works

#

you have to make a change to keep what you had working before, even if it's just a single letter, that's not minor anymore

tacit crypt
#

Yeah no, I disagree, but thats my opinion. The language itself is vague as is (and no, adding an option to limit a cache is not breaking)

What next, we release v13 or w/e, then I make a PR to limit another cache and we jump to v14? that's absurd

#

And from a G search

It sounds like they just mean "mostly backward compatible".

The definition of "backward compatible" pretty much is "not breaking stuff". But if there are some small changes to rarely used things, that only affect a very small portion of users, it may still be accurate to describe a new version as backward compatible overall.

unique axle
#

then we'll have to agree to disagree here, the point of semver is so you can specify a range in your dependencies and experience no change in behaviour whatsoever.
after all you guys (maintainers) will have to decide that, i'm clearly not making the decisions in that regard as merely a contributor and triage

tacit crypt
#

Technically this PR with a def limit of 100 would be mostly backwards compatible shrug

#

I'm not trying to say you are 100% wrong and I'm right, or w/e. I'm just stating my opinion that this PR, imo, is not major but minor. It's not in my hands when it'll be merged/released with what ver number. But personally, I would've merged it as minor

#

Technically with this one we're both right

vagrant holly
#

^ Setting it to 100 makes it a major change per semver, I concur

#

Setting it to -1 means the behaviour matches master by default, thus minor. PR now has that 🙂

solemn oyster
#

@tacit crypt JFYI, we can change limit from -1 to 50 (or 100) in v13, if not entirely remove _edits

#

We didn't need _edits when we made KC, and it worked just fine, I don't see what its purpose is, or why it was added in the first place

unique axle
#

that was the initial point i was trying to make, seeing that v13 is not going to take very long having the feature be implemented without changes in behaviour now and changing the default/behaviour with v13 seems to be a preferable solution to me

solemn oyster
#

Yeah, in v12, any change we make must make everything that has been documented, behave like so

tacit crypt
#

We never documented edits having an infinite length 0_EyesMoving

solemn oyster
#

It does document "the oldest", anyways

tacit crypt
#

Considering how message updates work tho..

#

That's wronf

#

And inaccurate of..messages fetched

weak kraken
#

Have you heard if they plan on implementing anything like an event emitter/stream for audit logs? or upgrading the guildMemberRemove one to indicate kicked users states?

copper laurel
#

Nothing like has come from Discord, no

weak kraken
#

kinda shocked, would seem like the audit log would be a natural place to track all manner of events

#

albeit redundant

ornate topaz
#

discord doesn't send anything for when audit logs are created

weak kraken
#

i know, i was asking if its planned

ornate topaz
#

it just reflects changes sent to clients in other events

#

(which already would make audit logs events redundant)

weak kraken
#

just feels weird to have to use audit logs to discover if a user was kicked, for example

ornate topaz
#

while true, there isn't much we can do about that

snow crypt
#

@vagrant holly can't you just remove the -1 for infinity? Infinity exists and works in that case so -1 too seems weird

vagrant holly
#

We seem to use -1 in a lot of other settings for no limit, so I reflected that with this PR too @snow crypt

snow crypt
#

i see now, my bad

vagrant holly
#

Should I skip hooks to revert the change, or should we just leave it?

vernal atlas
#

perhaps you could sneak in a prettier-ignore comment or something?

unique axle
#

what even is the actual issue here? eslint conflicting with prettier or something?

#

because i'd much rather fix the underlying issue than monkey-patch it for each PR

vagrant holly
#

yeah, eslint & prettier seem to be fighting

lofty beacon
#

What are peoples thoughts on User.mutualServers? Just gets the guilds the bot and the user are mutual to.

unique axle
#

that information is available

lofty beacon
#

I know that, but adding a shortcut on the User class. Do you think that'd be a good idea?

unique axle
#

if you know that the information is not available and requires an oauth2 request, how would a shortcut on User be of any use?

lofty beacon
#

Can't you just map the guilds and check if the user is present in it?

unique axle
#

that information is inaccurate due to just affecting cached member instances

lofty beacon
#

You could fetch them, set the cache option to false and see 🤷

unique axle
#

no. we don't need a utility function that iterates over n servers, fetches members on all of them and bloats cache into oblivion

lofty beacon
#

alright

#

thanks

unique axle
#
  • the official way to retrieve that data (shared servers) is an oauth2 request
    we're not going to support some way to prevent api limitations and make N requests for the user in the background, hidden behind a single seemingly harmless function call
lofty beacon
#

makes sense

cerulean siren
#

Is there a planned version with Deno Support?

raven juniper
#

No

cerulean siren
#

Ok, thanks for your answer

tender field
#

it is a bit weird that AuditLog is not a manager, isn't it ?
Like we have to fetch it to get the actions enums... And i feel like some cache capacity could be added 🤔 Is it planned for v13? Is there good reason to justify the way it is now?

unique axle
#

managers manage (hence the name) a cache, neither audit logs nor bans (where this also applies) are received through websocket events (and caches/cached structures) and consequently also don't require managers

tender field
#

oh ok

#

but why do we have to fetch it to get the enums ? This also feels weird to me

unique axle
#

pardon?

tender field
#

(what i call the enums are GuildAuditLog#Actions)

#

oh no i'm dumb

#

i can juste call AuditLogActions

#

then it makes sense the way it is

copper laurel
#

So, currently drafting the PR for inline replies
The Discord API property for the message a crosspost references is message_reference, which we implemented as Message#reference
The API property for the message an inline reply references is referenced_message

So I need a naming convention for this property - Message#replyReference?

opaque vessel
#

That sounds okay! It feels like in the next major version, .reference should change to .crosspostReference to keep the a clear distinction between that and .replyReference? 😅

copper laurel
#

That definitely makes sense - Souji has a PR to replace Message#reply with functionality that would act as a helper for inline replies, and might also include other breaking changes like renaming properties like that

oak quail
#

@opaque vessel @copper laurel message_reference is also used for replies, as well as pin messages and follow add messages

#

message_reference is guaranteed on replies while referenced_message may not be present

copper laurel
#

Right, that's what some comments suggested but it wasn't clear

#

So referenced_message is only on replies, but message_reference is all of them?

#

Why does the API bother sending both, because a reply needs author data etc for the reference?

oak quail
#

So referenced_message is only on replies, but message_reference is all of them?
yeah

#

and it sends both because message_reference just has the IDs which can always be provided; referenced_message has the full message object which is for client rendering (they don't want all clients fetching the message) but in some cases that won't be returned

copper laurel
#

So then if its for clients, is there any reason for Discord.js to implement referenced_message as I have as a Message property? Or just cache it using that data, and rely on the properties from message_reference if it needs to be grabbed from cache and/or fetched later?

tacit crypt
#

I mean we can still do it, Discord gives us the data, we might as well hand it over as a Message object (so then we also don't need to fetch the reply)

lofty birch
#

Would message cache sweeping behaviour not affect this? If it was set to delete all messages older than 10 minutes, for example, and a message younger than that includes a reference to a message that has been removed from cache, how would that work?

ornate topaz
#

would probably be removed again in next sweep

#

which would be to be expected, honestly

slate nacelle
#

The PR in its current state seems to be referencing the object directly, so it would no longer be in the cache, but still accessible, through the referencing message, after sweeping.

lofty birch
#

Is that necessarily good behaviour though? By being accessible through the referencing message, it's still cached, and will only properly be swept once the latter message has been also. Perhaps making it a partial message object once swept would be better?

copper laurel
#

Sweeping a Collection doesnt modify any objects that arent being swept though

slate nacelle
#

It's also possible to make it a getter, like User#lastMessage and friends. Messing with the object after sweeping is imo a no-no.

copper laurel
#

That would actually become quite a complex operation, checking every Message still in the cache

#

Yeah, I did suggest it could be a getter based on the Message#reference property, and we just cache it when it received, not store as a reference

#

Then sweeping would work as normal

lofty birch
#

I'm just thinking of the memory usage more than anything. A getter would fix that

#

How would it behave if we then wanted to fetch that other message though?

slate nacelle
#

Similarly, by having a field with the id, which you can use to fetch.

copper laurel
#

As normal

#

MessageManager.fetch(message.reference.messageID)

lofty birch
#

That's a lot better behaviour than the sweeping not working. I'd be totally happy to use that

vernal atlas
#

im starting a PR to update to the v8 API, should i bundle it all in one or create multiple PRs

#

im thinking multiple PRs might be better but want to know if it ultimately matters

oak quail
#

@vernal atlas you should clearly label that this pr switches to API v8

vernal atlas
#

aight will do

oak quail
#

or tbh just do all v8 stuff in 1 pr like fyko said

#

did any maintainers say anything

vernal atlas
#

got no pings about it

copper laurel
#

Note that I already added message type 19 in my inline replies PR, so that's v8-ready

oak quail
#

or a string

#

in RESTPostAPIGuildRoleJSONBody its permissions?: number | string | null;

vernal atlas
#

might have been an oversight

oak quail
#

should i just remove it so its the original value

#

because afaik only the id is different

vernal atlas
#

ye i guess so

oak quail
#

also i'll change

export type APIGuildCreateOverwrite = Pick<APIOverwrite, 'type'> & {
    id: number | string;
    allow: number | string;
    deny: number | string;
};
```to
```ts
export interface APIGuildCreateOverwrite extends RESTPutAPIChannelPermissionsJSONBody {
    id: number | string;
}
vernal atlas
#

oh wait i think i know why i added them

#

i think it was to do with

#

permissions being deprecated and x_new being a thing

oak quail
#

heres RESTPutAPIChannelPermissionsJSONBody in v6:

export interface RESTPutAPIChannelPermissionsJSONBody {
    allow: number | string;
    deny: number | string;
    type: OverwriteType;
}
vernal atlas
#

i think that'll be good actually tho since RESTPutAPIChannelPermisionsJSONBody (god, thats a mouthful) doesn't have _new

oak quail
#

yeah

vernal atlas
#

👍

vernal atlas
#

i think i've covered everything, i went through the diff from the api docs commit, i imagined it'd be bigger but i guess not

#

this PR is mainly just the basics btw, i haven't really got too much into handling uncached data from missing intents, but i think that this was planned for the next major update in discord.js-next

oak quail
#

@vernal atlas did you test if messages in DMs work

#

Bots no longer receive Channel Create Gateway Event for DMs
this might break it

#

also did u update ratelimit stuff

The Retry-After header is now based in seconds instead of milliseconds (e.g. 123 means 123 seconds)

The X-RateLimit-Precision header is no longer respected. X-RateLimit-Reset and X-RateLimit-Reset-After are always returned at millisecond precision (e.g. 123.456 instead of 124)

vernal atlas
#

hm, i didnt test that, but at a guess you would need the CHANNEL partial type enabled

oak quail
#

then should enable it by default i suppose

#

or just not make it an option

vernal atlas
#

also have not updated the ratelimits, wasnt that done in another PR or am i mistaken

oak quail
#

i dont think it was

vernal atlas
#

oh yea that was just the async queue

#

ill update the ratelimits tomorrow

oak quail
#

did u account for this

Channel Permission Overwrite types are now numbers (0 and 1) instead of strings ("role" and "member"). However due to a current technical constraint, they are string-serialized numbers in audit log options.

vernal atlas
#

oh

#

i dont think i did

#

should be an easy enough fix

oak quail
#

that probably wouldn't have been documented if i didn't mention it bloblul

vernal atlas
#

that wasnt on the api docs v8 diff hmm

oak quail
#

it was

vernal atlas
#

oh i couldnt find it

#

maybe im just blind, happens

lofty beacon
#

hey
when fetching members, it allows you to pass in an object when fetching
shouldn't it be like this for fetching roles, channels maybe?
i might make a pr of it just was wondering if well people thought it was a good idea

lofty birch
#

You can't fetch only a particular channel or role. The API just doesn't support it

lofty beacon
#

oh does it not?

#

sorry then

lofty birch
#

The reason you can fetch members with a query is because there could be hundreds of thousands of members

lofty beacon
#

yea

lofty birch
#

And returning all of them would be a huge waste of resources

#

Unlike channels (500) and roles (250)

lofty beacon
#

yea makes sense, thanks.

sullen mortar
#

Any solutions to insane memory usage?

#

I have two shards ~1.8k guilds, shards are allocated 1gb of memory and restarts daily due to memory usage

#

message cache set to 50

#

My bot holds no state

unique axle
#

you can manually sweep caches on an interval
apart from that currently not much, addressing custom caches is on the roadmap for the planned typescript rewrite, it requires us fundamentally rethinking the inner core structures so it's really nothing we can feasibly do under the current library.

if your bot can completely work without state you are probably better off using a more low level approach to websocket events and a rest API (for now at least)

left moat
#

make sure ur using the correct intents

sullen mortar
#

my intents are GUILDS, GUILDS_MESSAGES and GUILD_MESSAGE_REACTIONS

#

@unique axle great info, thanks! I'm pleased to see the project making steps to address these memory issues

#

I know you can sweep messages cache on interval, but other caches too?

unique axle
#

sure, caches are at the core Collection(s) which are extended from the base JS Map structure, you can #clear #sweep them as documented, providing a predicate function to selectively clear for the latter

sullen mortar
#

yeah - gotcha

#

thanks

oak quail
#

i don't see X-RateLimit-Precision in the code; does djs use second precision? is ms precision even supported in apiv7?

unique axle
#

@tacit crypt (i think that's your thing) this
where thing := area of proficiency

tacit crypt
#

I don't think it was ever PR'd to d.js (or it was in that rest PR of mine that is dustier than dust)
And iirc api v8 doesn't support it sooooo

oak quail
#

yeah was just wondering if ratelimiting would break if i updated something to v8

#

but v8 sends decimals now, so maybe that could break it? idk

#

it looks like it shouldnt break

#

cc @vernal atlas might not have to update ratelimit stuff

vernal atlas
#

ah

copper laurel
#

Going back to the referenced_message data, which is a complete Message object to support the message_reference properties of a reply, what do people think:

  • maintain a complete replyReference property on Message
  • cache the message, but make replyReference a getter rather than maintaining a direct reference
#

Also to note, that getter needs to know if the properties exist because its a reply and not if its a crosspost or pin notification

warped crater
#

And iirc api v8 doesn't support it sooooo
source?

copper laurel
#

Which leans more to the first option being easier, as the second would need to define something like isReply

#

The X-RateLimit-Precision header is no longer respected. X-RateLimit-Reset and X-RateLimit-Reset-After are always returned at millisecond precision (e.g. 123.456 instead of 124)

warped crater
#

ahhhhhh I see, that's much better then

#

I guess they did it in a backwards-compatible fashion before as a feature on top

#

but now it's just always ms

#

good good

real jetty
#

Hm, I'm experiencing a strange bug, when the bot removes its own reaction from a message it sent, it seems to be ratelimited, as in the rateLimit event is fired. This this intentional?

#

Or, wait actually this might be a combination of things, one moment let me see if I can reproduce it

#

Never mind, it's just my bot doing many things in quick succession; what I was doing that would trigger the rateLimit event was I was adding a reaction to a message sent by the bot and then immediately removing the reaction.

#

I guess Discord didn't like that.

surreal geode
#

Message reaction ratelimits are 1 per time period so you will always hit a ratelimit when reacting/removing reaction

copper laurel
#

Going back to the referenced_message data, which is a complete Message object to support the message_reference properties of a reply, what do people think:

  • maintain a complete replyReference property on Message
  • cache the message, but make replyReference a getter rather than maintaining a direct reference
    Additional thought - would the getter need to just be for replies? Couldn't it try to get the referenced message no matter if its a reply or a crosspost?
lofty birch
#

What if it was crossposted from a different shard (with traditional manager) though?

copper laurel
#

Its just a getter, so if it cant get, its null

#

Anyone using sharding generally should expect to have to do fetching of things like that

#

eg

get referencedMessage() {
    return this.reference.messageID && this.client.channels.cache.has(this.reference.channelID)
      ? this.client.channels.resolve(this.reference.channelID).messages.resolve(this.reference.messageID)
      : null;
  }
#

That should have a check for this.reference too but yeah

lofty birch
#

That's my point. A reference is different to a crosspost due to which servers they can come from

copper laurel
#

Well no, message_reference provides message/channel/guild ID for crossposts, pins, and replies

#

For a reply, we also get a complete referenced_message object which allows us to cache that referenced message also

#

So when it comes to the getter, should it be generic and try to get any sort of reference from cache, which would mostly be replies, or should we restrict it to only replies
And if the latter, we'd need to set a flag like Message#isReply to enforce that restriction

vagrant holly
#

👋 Gonna play around with this some more, but can anyone think of any immediate issues to sweeping cached channels? Should the lib cleanly handle a message arriving in an uncached channel etc.?

ornate topaz
#

to my knowledge it doesn't emit messages for uncached channels, but i neither kept track of it nor checked on my own

analog oyster
#

node v14 will become LTS soon, are you guys planning on supporting it

#

oh ok

vernal atlas
#

@raven juniper regarding #4890, doesn't seem out of scope to remove it from the tests too

raven juniper
#

i changed the method to fit in the test/random.js file, i'm just saying the whole line seems unwielding