#We're making a wrapper over the Discord API using Java!!
1 messages · Page 3 of 1
not worth it
in rare senarios the only time 8 and 11 will be used in discord development is when linking like 1.8 servers or 1.12.2 servers that aren't even paper
you are the reason why people still use old java versions
because you still support
instead of enforcing latest
we're not even using java 17+ features?
not that i've seen
it's compiled and developed in 21 right now but we're not using any weird syntax
records
records are java 16 features
17+
what about virtual threads and stuff like that? wont we use that?
nope, no use for them
exactly we will use that
why not?
java http and vert.x use their own threads, we just maintain 1 platform thread for event dispatching
arent they using virtual threads?
who's they?
pretty sure no
well
they make their own virtual theeads
iirc
We talked about switching away from vert.x
it's only used for the websocket
Exactly
anyways all that is not a reason to have some branch with outdated version
It’s kinda bloated just for a ws
yeah but whatever library we switch to will handle mutli threading within itself
anything on maven supports LTS
Isn’t LTS 17?
yes
So why should we support below LTS
we shouldn';t - i thought 11 was LTS by mistake
yeah but if they change the internals to use virtual threads then we would benefit from that on higher versions no?
it is?
it's not anymore
we're developing with latest
but there's no java 21 features used rn
just by chance, it compiles in java 17
and we're almost done so there's no need to enforce 21 if we're not using 21 internally anyway
Are you debating supporting 8 still?
lts is 21
no
We don’t use any 21 specific stuff do we
An ok then idc
nope, we didn't have a need for it
you sure?
let me check ,sec
we can use
string templates
virtual threads
pattern matching
string templates are preview though
they work tho
but yeah record patterns and pattern matching etc
Oh that looks cool
record patterns can be pretty useful for this project though
take a look at the codebase and lemmie know if you find any potential areas to use it
our records are just data containers for the discord responses
we don't do any logic on them
i don't care if you use java 21 features if there's a real need for it - there's no point in doing it if it's gonna be for a single method
because we'd break 17 support for 5-lines of code, that isn't worth it
there is also no point in supporting older versions instead of enforcing latest version
there is because people use java 17
people that use java 17 use java 21 lmao
biggest problem are people stuck on java 8, but anyone that knows of java 17 also knows of java 21 and how to upgrade if not already using it
i need another expert to chime into this conversation
on whether it's a bad idea to support java 17 and just to enforce java 21 (even though we're not even using java 21 features
)
maybe @sharp ferry
(even though we're not even using java 21 features
)
I wouldnt be surprised if any library like vert.x etc use virtual threads internally which got several benefits
you should never use virtual threads for threads that are long running
that's not what they exist for
not everything needs long running threads though
but we have no requirement or need to multi thread
should we multi thread json parsing? for what benefit?
it makes no sense to multi thread an application that does not benefit from mutli threading
virtual threads isn't an argument beause the multi threading we are doing is handled by the libraries we are using, our application only needs 1 thread
but using virtual threads will not improve performance
they're just lighter to spawn but we're not spawning any, neither are our dependencies
ik
uhm, it's not just that you know
no
JVM and byte code changes from version to version
17 is LTS i checked
and so is 11
you can't say 11 is no longer lts but 17 is
oh wow the website i looked at said it wasn't
lmao
but oracle says it is
😦
my google sucks 😄
The Java language has undergone several changes since JDK 1.0 as well as numerous additions of classes and packages to the standard library. Since J2SE 1.4, the evolution of the Java language has been governed by the Java Community Process (JCP), which uses Java Specification Requests (JSRs) to propose and specify additions and changes to the Ja...
at the least, our code compiles in java 17 at the current moment, so there's no advantage for anybody for us to compile in 21 and release that
As a rule of thumbs, regular versions last until the next version, and LTS last until next LTS
so since 21 is a LTS
Supported versions are 21 and 22
it's 4 release versions
3 since 17
see this
yeah looking now
maybe it won't matter but also there is something called byte code changes and JVM changes
no you don't understand
an end user can compile in any version that is java 17+
if they want to use 21 they can
but they can't use 17 if we compile in 21
but we don't use 21 anyway just out of pure luck - so why compile in 21 anyway ?
So, old project won't probably pick your libs anyway, only new projects would
and since new projects should only use latest or latest TLS...
if you don't use any feature of 21, then yes, you can use an older version
I am saying enforce latest or latest lts, idc if people are stuck on java 17 ngl
this is what i'm trying to say
if we don't use 21 there's no need to force an upgrade for endusers
once we use 21 we can then say "hey peeps, you need java 21 because we use xyz features"
such as virtual threads
I know but whats against enforcing it, then people arent stuck on java 17 and you help everyone
it's just giving freedom of choice to the best of our ability
because how can we be competitive? if JDA supports java 11 for example and your system is using java 11, then you'll use JDA
imagine using java 11
because you just wanna create a discord bot and you'll use whatever framework that runs on your system
yeah at the least we support 17 😄

I am just against people using old versions if you can literally use latest/latest LTS
yeah i get that - i would always say use java 21 but this situation is different, we want to be usable by as many people as possible out of the box
but if we have a real need for 21 (for example we actually use virtual threads) then so be it, we have a java 21 dependency
from 1.17.1 it's recommended to use 21
on paper docs
on 1.20.5 21 is required
I thought paper recommended 17?
no that's the required
Ah strange
for 1.17.1+ required is 17
for 1.20.5 it's 21
Minecraft is different
Each version of minecraft require a different version of java
and the reason people use some version over others is either because of mods, or because of performences
Whenever I dev’d for mc sfuff I mostly did 8 and 17
use 17+ or you get the belt
i can agree to that at the least lol
but i gotta admit the framework we've built is kinda sexy 
im gonna study and in my free time I'll continue writing my Minecraft inventories library
unrelated here but I'm upgrading it to 3.0.0 hehe
@light loom
ever thought about this just being called GuildMetadata?
uhh I shat my pants
possibly
yup that's what they give us lol
is there a command API?
yes
there technically is just not tested and it's too "raw" for end users
that's why we have a spike! 🙂
feel free to pick up the spike ticket @steep spruce 
or drop your suggestions, would be good to do it on github though so it's all documented
is there possibly a way you could literally just scan the commands via annotations, check the method args and then just cache the command and execute when needed
JDA for example has String[] for command args but it's bad and needs external libraries to make it somewhat good
(I'll add this to GH when I have time dw)
yeah I was thinking we can mark a method with a SlashCommand object return type for example
that it uses that
yeah! exactly
e.g. java @SlashCommand public SlashCommand ping() { return new SlashCommand("ping").addOption(String, "something"); }
hm.. I was thinking more like:
@SlashCommand(name = "ping", desc = "Pings user or yourself!", ...)
public class PingCommand {
@DefaultExecution
public void ping(Member user, @Optional(def = "self") Member target) {
// ...
}
@SlashSubcommand(name = "something", ...)
public void pingSomething(Member member, ...) {
// ...
}
}
just add the check for it here
if you want.. idk how to link it to discord but maybe if it hasn't been implemented I can create the annotation parser for it
I'd basically make the annotation parser in here, put commands in cache
you guys can just link those slash commands to discord
I've done it for minecraft
but that code was low-key trash lol I've improved
and if needed, I could literally make the registration parallelized and I don't think discord's rate limit would complain (we might need to fact check that tho lol)
since yk, it's a lot of reflection xd
sure, you can make a parser just don't do the reflection
If you want I can give you a walk through the codebase tomorrow? @steep spruce
It might be worth getting my PR merged in first too, since I completely made :annotations an independent module i.e. if a user doesn't add it to their build then they can't use annotation processing but instead have to manually register the listeners
like acf?
yeah I made one for Minecraft
i think it should be easy enough to understand everything
after looking at your code it's like 87% requests and records xd
also like.. the parser kinda does require reflection
i mean don't implement it yourself or do that part of the work just yet :p
you might find it easier to add/reference the existing stuff
my PR has only 1 thing left to do which is finish this damn GuildRequest class
but gosh it's do demotivating after have done all the rest and now being on the final but that is just a big one
ill no-life today and just get it done
because this final PR unblocks all the testing, additional features etc
let me do it now, fuck it - eta 2 hours
you could also just make the args String[] if you want extensibility
Orr you can make a really good built in library like my idea
wym?
for example
commands can either be something like this:
public class PingCommand implements GuildCommand {
@Override
public void execute(Member member, String[] args) { ... }
}
which enables extensibility to create your own command libraries
or better, since we are imagining an already fast implementation and really good in general:
@SlashCommand(...)
public class PingCommand {
@SlashCommandExecution
public void onPingCommand(Member member, ...) { ... }
}
which allows for easy commands, and also this approach can greatly reduce the amount of reflection (unless the API for internals is really good)
since yk, you can already do it in the loop that registers listeners
instead of redoing that reflection
we can do that second approach easily
and have the power of the first version
so adding a SlashCommand listener is no effort there (neither is validation/sending events to it)
we can already dynamically invoke the method and pass the correct arguments to it since
the only thing we really need to nail is making it nice, pretty and easy for the end user
the method name can be anything the end user wants
e.g. java @SlashCommand public T helloWorldHandler(...) { ... }
the beauty we've added is
all parameters are optional
if you don't need the Member parameter, no need to add it
and realistically, we don't need the class level annotation either, just annotate any method you want with @SlashCommand and it's good to go
so u could do something like
String[] don’t make sense tho since it’s slash commands
With named args and types
do you have an efficient approach? removing the need may actually be good, and might even encourage kotlin development like:
@SlashCommand(...)
fun onPingCommand() {
// ...
}
instead of:
@SlashCommand(...)
class PingCommand {
@SlashCommand
fun onPingCommand() {
// ...
}
}
yeh that's true
Could even add a kotlin module
With support for suspend
mhm
There is a way to use kotlin reflections from java too
hm?
I mean, the second approach here can also lead to noticably faster startups in simpler algorithms (if something else can do it really fast then no objections needed), or the more classes the more time it takes to start, even if they aren't even commands
Nvm, I thought there was a way but idk
Yeah, I like the idea of that tree-style annotations
my finals start at may 8, and on may 14 I have loads and loads of free time
i don't wanna introduce kotlin 
reason being, it's adding another tech stack, especially one i'm not familiar with and once we start adding multiple languages, it gets harder to maintain because not everyone will understand it
wazei must introduce kotlin
yeah the approach we have at the moment is pretty good, locally, i've been spinning stuff up in like 2 seconds tops
i don't see any performance issues with adding more annotations
@SlashCommand(...)
fun onPingCommand() {
// ...
}
so this example would be correct
reflection isn't pretty (often confusing to understand) but gosh the end result is insanely sexy
also yk, if you use MethodHandles instead of Method#invoke you can optimize it using public lookups
As a separate module ofc
A couple of us know kotlin here
I’ve done kotlin for 900 (ish) hours
Taz knows kotlin too
I've seen it execute nearly as fast as direct invocation
it's only kotlin lol
and it would be an extension not a rewrite
public lookups aka
it can use optimized lookups for a public method
with MethodHandles you can also use an optimized method that doesn't check for argument types (is good when you already have the arguments parsed and you know the types, from personal experience tho do not mix with an Object[], instead use a Generic[] but Generic can be anything extending an Object, so same thing but works with a parsed array)
the setup should look like this:
MethodHandles.publicLookup().unreflect(someMethod).invokeExact(Object, ...);
yes i've cried 4 times doing kotlin
that should be enough experience
happy for you to explore it - all for doing things more efficently
I made a Minecraft command library for Minecraft that uses annotations basically the same way as here but with different annotation names
so I have experience in this kinda, more like experience in parsing String[]
but this should be fairly simple and the same
we most likely don't need to do a String[] - we can easily derrive that from the data we receive and the parameters set
yep
for example on the event listeners an optional parameter is Guild and we dynamically construct that using some of the data we receive from the request + cached data
just make sure within :core there is a non-annotation version of whatever you do
so for the event listeners we have registerEventListener or something available in the Discord class
which is for any manual stuff when people opt out of annotations
@orchid portal #86 just GuildRequest needs finishing in :api
basically, only 15 methods left
those methods need builders as parameters
you can see the other ones as examples, it's all commented with TODO so you can see it easy
ty 
method name is pretty much the same name as the discord request e.g.
// TODO:
public AsyncResponse<Guild> modifyGuild() {
return responseParser.callAndParse(Guild.class, null);
}
links to
ModifyGuildRequest
for the name of the builder just use the same name but instead of Request call it Builder
required params in the constructor, optionals all get a builder method
@light loom what to do with optional?
ohh make a builder
ugly
too draining
also y are these not in separate packages
We discussed
Putting them in com.javadiscord.api.builders
Since they are user facing
Yeah we were discussing something else and it turned into that
i think htg is too busy someone else should pick up docs
i think he's been too busy
we should start documenting as we write unit tests as that will give the tester an idea of what's going on and can then provide valuable docs
Wasn’t the docs thst he was assigned to not the javadoc but the like other docs
he was doing java docs
Also @sand peak what’s going on with the unit test PR, are you writing more tests or is that ready for review?
he's working on it in vc 😄
Oh, got that confused with https://github.com/javadiscord/java-discord-api/issues/47
Lmao
Oh my bad I forgot about it was really busy irl
no worries!
I will be travelling this week I have a funeral to attend.
Unless you can wait a week
oh sorry to hear
Upto you
i needed it yesterday
just kidding :p - sorry take as long as you need, hope everything is okay
@orchid portal just rebased on main - there's the new webhook stuff to do as well :S
ExecuteSlackCompatibleWebhookRequest , ExecuteGithubCompatibleWebhookRequest these look interesting af @restive void 😮
didn't realize it was supported out of the box by discord
Ye ye
that is just the #github-activity-log
dev is going to write tutorials?
or just the setup for docs website?
alright bet
so I get to do the reflection then
btw the args can't be parsed into something like Member member, String item, Integer number but instead it's gonna be like T extends User memberOrUserDependingOnInterfaceImplementation, Arguments args
but I can make it in a way where it is 100% independent of a class, just a method/function if you want
Idk who is who on discord
just setup 🙂
why can't they be?
I mean, I can tell you more info and study this
they for sure can be 🙂
if I find a way to allow this then I'll tell you
but basically with annotations it's really easy to just parse into args
yeah
but also
if we can do that, it basically defeats 80% of purpose of annotations
20% to just provide the name, description, etc etc
and also there should be an annotation for each arg if you want custom and overriden data for that arg
public void onPingCommand(Member member, @SlashOption(name = "target", desc = "Who should we ping?", ...) User pinged, ...) { ... }
this is kinda a rabbit hole
so that even a usecase to support?
yes
you need to be able to do this somehow someway
but not dynamically find a random user
@SlashOption is kinda the best way for it
I would expect the method to be like:
@SlashCommand
public void changeNick(User user, Optional<String> nick) {
nick.ifPresent(s -> user.nick(s));`
}```
in the real code you would give a reference to the Guild class
public void changeNick(User user, Optional<String> nick, Guild guild) {
then guild.member().update(user) or something
that's the neat part, the command invoker just provides the mention
wdym dynamically find a user
like go through all users and find that user or smt?
yeah we don't want that
Ya it is interesting
what? no
no way lol
the user would already provide a mention like
/nick @steep spruce Hello World
I'm assuming we are parsing an array of strings
Discord converts a mention like @steep spruce to @steep spruce
we can just get the ID easily and convert it to a discord user/member
I don't even know anything about discord API except for using a discord wrapper and I can semi-imagine this
ah you mean mentioned users?
ah okay, if that's the case then sure, but we'd want it a a List<User> mentionedUsers kinda thing
i had no idea what you were talking about
but it seemed wrong without that context lol
my man really thought I was gonna do a heavy O(n) operation to find 1 user lol
wdym
users would already be able provide that
but most people would want just 1 user for most cases
we can also just add custom argument providers
be careful you don't fall into the trap of having too many parameters and overcomplicated the implementation
reason being, this is for end users, it needs to be as easy as possible
and with the annotation specifically, we're assuming the user will either
- Figure it out on their own
- Read the doc
- Use the hard coded variant
have you ever seen my code? XD
it is very straight forward
public void onPingCommand(Member member, @SlashOption(name = "target", desc = "Who should we ping?", ...) User pinged, ...) { ... }
this?
that was an idea
it's similar to Spring/Jackson and whatever else uses annotation method parameters sure
I'm okay with this but there's a few things you'll lose too, there's no compile-time validation for example (we already sacrificed that with dynamic method invoking)
I mean, for slash options, adding autocompletions, making it optional, adding metadata, etc
it's the best and simplest way and is optional so you don't have to add it, but will this ruin consistency and should it be mandatory?
mm okay, it'll make more sense once the implementation starts
if I can see what you end up making then i should be able to get a better idea
everything happens at startup so it wouldn't take a lot more time
the end user might not do it all at startup for example
somebody makes a bot that allows people to create their own slash commands
a user might upload the code and inject it like we are during runtime
also, what validation for what
hm
public void onPingCommand(Member member, @SlashOption(name = "target", desc = "Who should we ping?", ...) User pinged, ...) { ... }
so see this
@SlashOption(name = "target", desc = "Who should we ping?", ...) User pinged
could be a useless parameter if the bootstrapping of the command didn't even specify this
i.e. the annotation is inconsistent with the @SlashCommand method parameter
so when we invoke it - we're actually invoking it against null and should be throwing an exception "unexpected parameter <name>"
and at runtime, you're running this in some headless linux server and might not even see the logs
the command will just not be working
for those who have no top-level exception handling, will crash their bots
that is more so in the case of injecting during runtime after we've done our initial bootstrapping
though in CI/CD, somebody commits the wrong code, stuff compiles, it gets deployed but their bot remained offline because we threw at runtime not compile time
that's something we have lost already with the :annotations module
the only way that could be solved is with an annotation processor
but we shouldn't introduce too many areas that problem can occur in
yes
exactly!
which is a TODO that i want to add
this issue is also a huge problem with interpreted languages
yeah dynamic languages suck
because they are especially vulnerable
stuff like groovy has backward inheritence too
e.g. in groovy you get the normal child inherits from parent
but you can also
dynamically
dynamically
parent inherits from child
the concept seems cool but once you get an issue, gg can't debug
because that makes autocompletion awesome
and work better
(this is sarcasm if you haven't noticed but I felt somewhere in my heart you haven't noticed)
annotation processing might be a little bit difficult, I haven't looked into it so not sure the javax.annotation.processing api has everything we need out of the box
it's our best shot at fixing this problem
it can deffo be done ofc
this also proves that annotations are the best way to handle commands
yess
the entire annotation system we got going on is so nice and clean and perfect lol
lel
after FlameWare my old annotation library which I abandoned I haven't worked much with annotation reflection
annotation reflection is super easy to me anyways
that code is dog shit tho
it's a fun topic anyway 🙂
can I put your name on this? https://github.com/javadiscord/java-discord-api/issues/28
if your okay with my limited time availability until may 14, sure
well I can still get on everyday but for a max total of like 3h/d
yeah no rush, we have loads of other stuff in the TODO
max
17 issues at the moment + a few more that need to be added
and loads of lengthy tasks that need to be done
you can put my name
e.g. docs, unit testing etc
can you comment on the issue?
what do I comment lol
that you'll pick it up or whatever - i just need your interaction in the issue so you'll show up in the list when i assign it
for some reason, i can't just type your username in
i described the process here anyway
alright there
I guess I need to learn discord API lol
after reading the code it does mostly look like network calls
yeah the code is primarily a wrapper over the discord api
when we receive events we just send it to the users handler method
the way the users create the handlers and call the "wrapper methods" is what we define as the framework
I never worked with direct discord API ever
butt I do have great experience in doing stuff like.. reflection and commands
- the additional benefits we give such as caching and rate limit control
the API is straight forward, the docs explain how stuff works https://discord.com/developers/docs/resources/application
i feel like I might have to create a separate cache for commands idk tho
why?
the cache we have is just a Map<Long, List<Integer, Class>> (long is guild_id)
the List<Object> is just all the objects we've cached, channels, users, etc
ohh ok
you can throw anything into the List and look it up via an id or something
e.g. cache.get(1, Channel.class)
will give u the channel object that has ID 1
if we use low-memory cached values of parsed args it can significantly reduce the reflection needed for every command (because if the parsing is like 90% done we just need to cache it and then 90% of the reflection is done, all that's needed is to specialize it for the command)
okay
also what if I add the ability to add custom annotations to commands
like a set of predefined actions for a command that can be done via 1 annotation
if you can't re-use the caching code we have, create your own 🙂
try make it as generic as possible so maybe it can be re-used in :cache
@SlashCommand
@GuildOnly
public void onPingCommand(...) {}
I think I can reuse the caching code y'all have
in the annotation processor,
if the command invoker is just a User it could throw to tell to upgrade to a Member instead of a User when @GuildOnly is there for example
what do u think?
ideally we want User instead of Member
public @GuildOnly void onPingCommand(User user) {}
Member would be a member of a server
what does GuildOnly mean? can only be invoked inside a server and not DMs?
yep
you can invoke slash commands in DMS yk lol
User has more information attached to it
yeah just saw
maybe we can do @Source ?
Member is an extender of User tho
let me check
public record Member(
@JsonProperty("guild_id") long guildId,
@JsonProperty("user") User user,
@JsonProperty("roles") List<String> roles,
@JsonProperty("joined_at") String joinDate) {}
it just has stuff like Member#hasRole, Member#hasPermission, Member#add... etc etc
yep
so it's just the roles that are extra
and permissions
and adding then
connecting them to vcs
doesn't look it?
kicking them
banning them
that's done by user_id
muting
user_id inside member and user is the same
I think User makes more sense, maybe we can merge them somehow?
I think I can
we just add ```java
@JsonProperty("roles") List<String> roles,
@JsonProperty("joined_at") String joinDat
so none of this member.user() nonsense
but what if someone uses it in DMS?
List<Role will just be empty
what if someone does User#addRole in DMS? you want it to take a screenshot?
we internally cache and update objects
but you can't do User#addRole inside DM because there's no guild assosicated to it
so in your code
if @DMsOnly (for example)
they can't use the guild object
i think
dunno experiment 🙂
how would you validate that
i'm only theorising i'm not sure, it's 11pm my mind is going dead lol
alright I can create commands and then tell you everything
good luck, looking forward to seeing what you make!
it's 1am I should rly sleep
cya
night
btw ik I really should be sleeping but just saying you didn't really answer the main question
like if there was a set of defined annotations for commands that could be used, and people could even make their own, if that's a good idea xD
also tab completer providers
we should get a basic annotation based lib working before we think of like goodies to have
also I'll try to build the best API I can
Yup
I suggested making a ksp, or wharver the java equivalent of that is for event listener annotations
@steep spruce would you be willing to make a GitHub issue or comment on the slash command issue with the proposed way a user would use the api and write a short summary there so it’s all in one place
Whens that oauth2 API issue on gh gonna be moved into the ready to pick up section?
Want me to assign you to it?
(I don't think any of the models for this are implemented)
Maybe but idk. It caught my eye but I've barely worked with oauth before but it might be an interesting challenge 🤔
@restive void lmk if u wanna be assigned then, there is also guilds template which are just more of the normal stuff
widget image is not complete?
ohh just need to make the enum
@plain ledge in which packge we were making the enums?
i forgor
models I believe
yes its models
u merged this with the old spotless
The action was passing
yes coz it uses the branch's spotless config
ah well it's fine
ohh wait u changed the spotless config to the old oen
thats y everything felt off
@light loom intentional?
ah yeah it is - I reverted it
the reason I did this was because I got fed up of seeing the following:
public void something(int a, int b, int c) {}
public void something(int a,
int b,
int c) {}
public void something(int a,
int b, int c) {}
all 3 formats passing spotless
(example)
there was just some stuff that wasn't being changed when i wanted it to be so we have to redo the original spotless implementation that you did to do everything and be strict
ohh ok makes sense
@orchid portal just checked the PR - looks good man! thanks! 
Since I raised the PR - I cannot approve it but you can
Are you interested in some more child labour? there's the webhook api that needs a builder :3
i'll only be able to do it tomorrow now
no problem
i'm being slaved at work rn - i'm actually stuck and can't fix something lol
#1051826284008853505
lol
nobody will answer it 😭
prove it
it's a specific issue with TypeScript, AWS Synthetics, Lambda and Credentials
well ofc if you never ask
boi i'm the tj aws expert
if i can't do it - the average jo can't either 
well there are experts here though
i dont doubt that
I'm gonna try my best to figure it out, I don't have the luxury of being able to wait around - my JOB DEPENDS ON IT
(not literally)
But I'm a senior
I spoke to one of the other seniors
I told them if i can't get it working i'm gonna rip all the typescript and write it all in Java
damn
i can convince the tech lead ezpz
whatever gets this done quicker
(i fixed it :3)
KSP?
@light loom is channel requests still not finished?
did u fucking generate this all with ai
Kotlin symbol processor, it replaced kasp
Jesus Christ
Arrays.stream(clazz.getConstructors()).filter(c -> c.getParameters() == 0).findAny()
What is that method for
getting the 0 arg constructor
from a class
only if reading was an option
I mean when do we use it
I’m on my phone
its done
no just the models at the start
yeah fine
dont change it, i just have the urge to write ever foreach loop in a stream
its out of control now
i'm not gonna change it myself
the code is perfectly readable
you save nothing by condensing code like the example you provided
if anything, it makes it harder to refactor in the future if we did it
but there are some areas that can deffo do with the improvements
such as the areas with heavy indentations
Isn't stream more efficient?
yes
no
a "simple" for-loop is faster if we're talking about performance
nope
a stream needs to warm up before being useful
does some extra stuff
making it slower than a for loop
and all the initialisation too, we already have a [] but by using a stream, under the hood it needs to wrap it first
I could make a good implementation of a stream that is basically the same performance as a normal for loop
the reason people like streams more is because it's more declarative and encourages immutability
and using lambdas with streams is awesome
but my problem here is Familiarity
people use it because it's overall just better for readability
you'll lose that with a complex stream vs a single for-loop doing a single if-statement
for small collections/arrays I'd encourage it
the problem I have with Taz's example is that the complexity is introduced by the Optional returned
not so much the stream itself
why don't we use an expressible library?
so that we could return Result<Value, Exception> for example, or use better optionals
no
Arrays.stream(clazz.getConstructors())
.filter(c -> c.getParameters() == 0)
.findAny()
.orElse(throw new RuntimeException(..));
would be best stream approach
yeah that's what i meant
but another problem is..
spotless isn't gonna do that pretty formatting
you'll get shit like this:
you guys use formatters???
Arrays.stream(clazz.getConstructors())
.filter(c
->
c.getParameters() == 0)
.findAny()
.orElse(
throw new RuntimeException(..));```

just use your brain to format better
yeah it's the best way to keep the entire codebase consistent and unopinionated
what if someone uses formatter "shittier" on accident
we have it defined in gradle so they can't use a different formatter
gradle:spotlessApply
gradle build will fail if you don't run that
alright
and since our pre-commit does gradle build it won't let you merge if that fails
for (Constructor<?> c : clazz.getConstructors()) {
if (c.getParameters() == 0) return c;
}
throw new RuntimeException(..)
you sure this isn't better? a stream only looks good and is worth it tbh if you make nice code somewhat like this:
// notice how we use a lot of those cool looking lambdas using `::`
requests.stream()
.filter(Request::isAsync)
.map(Request::execute) // some result
.forEach((result) -> ...);
my opinion
Yeah I'm sure, for a simple function it does not need that, we just want to return a value or throw an error to the user
@light loom is this not AsyncResponse?
yeah for a callback function
lets do that now
its just an example lol
it wasn't meant to use any code I know
oh wait
I forgot to really check the reply
💀
@light loom how would i know what response to parse it into?
thats what i was saying to include it int request
check docs 😦
@light loom do we at least have all the models?
I think theres some models missing
<Void>
yeah i just copied how vert.x handles this situation for their async stuff
Models are missing but ig for response we have all the models
try adding the missing models
we gon add everything in this pr
Yeah we can
It wouldn't be the first mega PR 
We'll just all review it together, the changes aren't tested anyway
I only manually tested like 2 of them
But we're not going live without unit and integration tests
I think that's the last bit of human labour 
@light loom did u checked the reviews on the pr?
I will look properly later
Taz is the PR ready?
No
public class CreateMessageBuilder {
private final long channelId;
private Optional<String> content;
private Optional<Integer> nonce;
@light loom wrong naming or is this intentional?
this is a multipart request
and we're finding it out now 
The name is based on the ChannelMessageRequest
Shouldn't it be ChannelMessageRequestBuilder?
I've just been replacing Request with Builder
Bc this is user facing and the long name is kinda bad for them
They will never see the Request variant as it's part of the internals
bruh i thought u meant add builder at the end
Aah don't worry about it
We can sort out the inconsistencies later when we write tests
We'll have to touch majority of the files anyway so any bugs, inconsistency, todos, have to get fixed then
hello, can i contribute as well?
of course, check out https://github.com/orgs/javadiscord/projects/1/views/2?pane=issue&itemId=58197125
i commented on #81
this looks so easy to follow, you guys have done a very good job!
help me please i cannot create a branch: remote: Permission to javadiscord/java-discord-api.git denied to notyourhabibti
you need to fork the repository
hang on, i'll add you as a maintainer instead
try now
dont u have a job already? y is this a new github account
i don't use github
pushed changes! ❤️
what do i have to do for https://github.com/javadiscord/java-discord-api/issues/14?
basically, when logging we should have an ID attached to the log messages so we can see which log messages appear for what
e.g.
event received -> we log with an ID
any methods that get called that does a log
should have this ID attached to it
so we can see all the logs that appeared in relation to a specific event
custom appender ig
this is multi threaded though if you get an event and then another event at the same time the flow id will be changed and it will not link back up??
look into "mapped diagnostic context" (MDC) on google for log4j and run some experiments
you can set a few properties such as the guildId, userId etc to appear in the logs
start simple though with just a random number (or auto incrementing int)
i will do something else 
gitlab then?
hi @orchid portal
i added to your branch some of the TODO comments and missing objects, i think that was the best place to do it?
oh I did it in my branch
microsoft
it's common to see that
also @molten tusk did you just do the TODOs?
to my branch
sure
imposter is wrong and it does not match the docs
{
"id": "",
"type": 0,
"content": "",
"channel_id": "",
"author": {
"id": "",
"username": "",
"avatar": "",
"discriminator": "",
"public_flags": 0,
"flags": 0,
"bot": false,
"system": false,
"banner": "",
"accent_color": 0,
"global_name": ""
},
"pinned": false,
"mention_everyone": false,
"tts": false,
"timestamp": "2024-05-05T18:33:48Z",
"edited_timestamp": "2024-05-05T18:33:48Z",
"flags": 0,
"position": 0
}
but the docs say author is user
the openapi spec is returning author when it should be user?
yes
keep a note of it but see if you find any other occurrences of the spec not matching the docs
i think i am doing something wrong, the object does not match the request
does not match the docs
that looks like a user
I'm gonna try make a team on discord, this should also give you the "developer" badge on your profile
Discord lets u make teams for ur bots?
you dont create bots on the discord dev portal
u create applications
and then create bots under it, u can also do like presence and shit
and u can create applications under "teams" I believe
Oh i see
@molten tusk u'll have to revert all those changes coz its already been done in the other pr
sry for ur time waste wazei should've told u that
it seems there is important progress
@light loom do u wanna roll back to my config and we can edit it over time?
u can install eclipse and also edit it
Yeah I will do let me get setup first to be able to play with it
Add me @light loom
Sure
@light loom my school ends the end of may so I’ll be able to work on the project again since summer starts. Rn I’m busy with some other stuff and don’t have time on top of school
No problem nopox, focus on your own stuff and work on this project whenever you have time to kill 
1 enum
im very sure we havent
yeah we deffo haven't 
we've been blindly writing these APIs based on the docs
@orchid portal should I work on it?
it's not - we just have unit tests left
sure
which enum is it?
component
no not component
i actually used Integer instead of making an enum
and after pushing i realized it should be an enum
also the build is failing rn
@light loom ok its the components in EditMessageRequest
cool ill fix
also check for components in other places
@light loom also fix builders names while ur at it
sure
within the end of half of may I should start
I'm really busy on school rn
@molten tusk sorry can you remove your gpg keys? (edit: i removed it)
they're still on my system
so i keep commiting against your name - nvm it wasn't - it just didn't update on edit
i want to work on sm fun stuff as well
whats that
so we have annotatons right
e.g. @MessageCreate
we want a new one called @Source so that an @EventListener only gets called when it's from that defined source
e.g. private message or guild or both
anyways I have done the changes @orchid portal
https://github.com/orgs/javadiscord/projects/1/views/2?pane=issue&itemId=61157040 this is the ticket I am talking about
but it's not refined, you're welcome to refine and work on it 👀
or if you want a real challenge...
there's also this one: https://github.com/orgs/javadiscord/projects/1/views/2?pane=issue&itemId=59639792 (Enforcing Nonce)
can we also choose a name for our framework !?
yes please
javadiscord
java discord library
java discord interface
imadethisinjava
idk man
trust me OpenJDA 💀
it would be cool if JDA wasn't open source
JDA PRO
lmaooo
should we take the first letter of every contributor
and make a word out of it
e.g.
taz
wazei
nopox
anax
squid
``` = wants framework
w = wazei
a = anax
n = nopox
t taz
s = squid```
people wont get it
also unfair for other contributors
what other contributors
future
i'll do it using all the v1 contributors
u better commit a fix to the readme or something
thing is, people might think its a spin off on JDA and except the same coding style?
disbot?
ofc I would avoid anything jda related lmao
let's post it here
tim suggested AccordAPI
I dont get it though lmao
Doesnt sound java related
All the good names lowkey taken ngl
Javacord, Discord4J
I posted a possible name idea on the discussion
Idk why it thought it was Spanish 
this one sounds weird tho
sounds like discoboard or smth
like a actual bot or bot finding website
Yeah thought so
Lol somebody make a drag and drop editor
"drag an event listener", "create event", "send request"
Should be easy actually 👀
like scratch?
That'd be kinda cool
https://github.com/google/blockly like smth based on this
Encord
Should we name it after a vegetable
The cauliflower framework 
We really such at names - not even a short list 
Cork
Discork
this cork
That sounds good
Uranium
because this framework will blow up
in no time
Ah the terrorist framework
Fr
Nono it's popularity will blow up
so like
uranium gang
like rust has rustacians
uranium has uraniumians
or uranium gang
It's the visuals 
I deleted
before I say anything
I know you saw it
I just want to say I'm 14
damn
@tawdry pewter Where tf did you come from
Hi though 
Snooping on top secret conversations!!
Hozeyn, any name ideas??
hi my friend
but its very easy to guess what it was
What was it then taz
ur anus ig?
Of course you'd think about my anus 🥰
lemme hop on vencord and get the screenshots
if you don't mind
WHAT
Should we name ourselves vencord
def not
choose something which is not existent in discord space already
Original
do you like wario?
"it's a me! mari-"
"bro that's not the script, you are not og Mario, you are wario"
The Discord Wario API or DWAPI
TikTok ew
Wait this could be it
Djinncord
D for discord, j for java
But Djinn is also an existing really cool word
what's the meaning?
In French, the word "djinn" refers to a type of supernatural being or spirit in Islamic mythology and theology. Djinn are often depicted as powerful entities that can be either benevolent or malevolent, and are believed to inhabit the unseen world alongside humans and angels. The concept of djinn has been present in Arabian folklore for centuries, with stories about these beings appearing in various works of literature and art. In French-speaking cultures, the word "djinn" is commonly used to refer to these mythical creatures or spirits.
Jinn
Wait no
Djinn seems to also work
Here all the english words starting with Dj : [dj, djagatay, djagoong, djakarta, djalmaite, djasakid, djave, djebel, djebels, djehad, djelab, djelfa, djellab, djellaba, djellabah, djellabas, djerib, djersa, djibbah, djibouti, djin, djinn, djinni, djinny, djinns, djins, djuka]
so
Dijkstra'a Discord Framework 
Djinn is the best here
these words have meaning?
Could work indeed
all look arabic
Falafel framework
what
Falafel is a popular Middle Eastern dish made from ground chickpeas or fava beans mixed with herbs and spices. The mixture is formed into small balls or patties and then deep-fried until crispy on the outside and tender on the inside. Falafel is commonly served in pita bread with vegetables such as lettuce, tomatoes, and cucumbers, along with sauces like tahini or tzatziki.
Falafel is a versatile dish that can be enjoyed on its own as a snack or appetizer, or as part of a larger meal. It is often served with a side of hummus, tabbouleh, or pickled vegetables. Falafel is a popular street food in many countries and can be found at food stalls, markets, and restaurants around the world.
In addition to being delicious, falafel is also a nutritious option for vegetarians and vegans, as it is high in protein and fiber. It is also gluten-free, making it suitable for those with gluten sensitivities or allergies.
Overall, falafel is a flavorful and satisfying dish that has become beloved by people of all cultures for its tasty combination of ingredients and versatility in serving options.
Dunno i just said something random 
If you've never had falafel ala, you should try it
In a wrap
It's actually lovely
okay, I'll answer this because I'm a Muslim
"jinn" is basically a term for a stronger variant of a ghost
You can’t use JDA without using the web socket
which, most jinns are enemies since Satan controls jinn
only few are good
We have quiet a few
To name some:
The food

