#We're making a wrapper over the Discord API using Java!!
1 messages Β· Page 4 of 1
Error handling
yes, I'm middle eastern silly
I know falafel and tasted it
Yeah error handling
u from lebanon?
I just prefer shawarma or koshari
Oh guess what we're also gonna have tests, JDA has 0 
Egypt
Same I just wasnβt sure if u were talking bout food
Plz halloumi and falafel in a wrap
koshari >>>>>
koshari fills you up and is awesome
nice! I love shawirma
1 sec, let me act smart and open Uber eats on some random Arab place and act like I know what I'm talking about π
I'm kidding, I know the menu by heart 
War Ο API . it's like a poem
Warpi
In the context of a Java Q&A discord server, "warpi" is not a recognized term or concept in the Java programming language. It is possible that it could be a typo or a misspelling of a different term or word related to Java programming.
If you are looking for assistance with a specific Java programming topic or issue, it would be helpful to provide more context or clarification on what you are referring to as "warpi." This will allow other members of the server to better understand your question and provide relevant assistance.
In general, when asking for help or clarification on a technical topic in a discord server, it is important to be clear and specific in your communication. Providing details such as code snippets, error messages, and any relevant background information can help others assist you more effectively.
Overall, if you are unsure about the meaning of "warpi" in the context of Java programming, it may be helpful to double-check your spelling or try providing more information to clarify your question.
yk what I'm saying
ok we use warpi
I'd do the same
oh cool I've never been pinned in a big server
tbh I donβt like any of these 
What are you making?
i swear i just want a name at this point so we can move away from "java-discord-api"
a discord framework 
Yeah but naming is very important
But also hard
How about jiscord
That sound sus
I wouldn't go for names that cast shade on other projects like BetterJDA.
but u voted openjda
ah well java discord api
maybe
they cause shame on themselves for going with the name JDA to begin with
Yea "open" isn't a good idea in general
Let's call it Angklung

i can imagine a viking saying "AngC0RD!!"
DrocsidA?
peeps should consider SEO 
-cord makes me think about music cords
I googled favorite music instrument of java island, and I got Angklung
it looks too much like game
yea
wait
Jazzcord
π
Anyway, pick your poison https://en.wikipedia.org/wiki/Music_of_Indonesia
As it is a country with many different tribes and ethnic groups, the music of Indonesia (Indonesian: Musik Indonesia) itself is also very diverse, coming in hundreds of different forms and styles. Every region has its own culture and art, and as a result traditional music from area to area also uniquely differs from one another. For example, eac...
Also make sure it's SEO friendly. Disbot/uranium/... don't tick that box.
I made uranium name as a joke lol
I didn't expect him to add it to a list of things to choose from
π
not too long, after our testing and docs are done...
the promotional campaign 
"THIS VIDEO IS SPONSORED BY <insert name>"
i kid :3 - i'm gonna message discord directly
ey so if I contribute that CMD lib and discord sponsors us will you get me a new PC bc I can't earn income ykykyk
what am i, jeff bezos?
idk maybe send a selfie
i mean if discord really did sponsor us
i'd split
if they don't - im at least gonna try get us lifetime nitro
lol
but anyways, i do wanna say great job to everyone so far - we've made such good progress - i never expected us to do as much as we did in the time we've spent so far
honestly I could make 2 kinds of CMD libs built in
one without annotations where you are required to extend a class and you have to register it manually but executes faster
and one that is exactly the opposite of that I just said
we need that
the annotations lib is a users only way into using any type of annotation processing
so we need the traditional way inside :core available
I could literally make registerCommand and it checks if it's an instanceof something, if it's instanceof the command class and has an annotation it throws
or it just loops over methods
this is our manual when not using annotations
We might have a drag and drop editor
u know how expensive that'll be develop
It's doable
The only complexity is the frontend which can do in html
JavaFX >
also, instead of staying limited to a certain number of events why don't this FW just give devs ability to create their own events? 
Imagine something like my crap drawing
On the left it is all the "actions" and "events"
You can drag an event listener onto the drawing board
Then under it drag a "action" to listen for
Add a simple "if-statement"
.
And call one of the API requests
Then when you press generate, it should create a .java file
@light loom? 
if we do ever actually make this, make it not spit out the code and commercialize
for hosting
You think we should charge money?
ofc
I didn't understand
ofc
it'll not only be demotivating but also depressing for me to work on smth like that for free
no like, devs can create their own events, like there's a message event, channel create, etc etc
just let devs make their own alongside the default events
Idk what that looks like
Sure, I don't mind us monetizing convince tooling
I made a menus lib that actually has something like this
it's basically platform independany
this is not the final code btw
I have almost a complete rework of this
but with like a few lines of code you get the point
just remember
this code is bad only because it isn't the final product xd
don't forget to get me a car
convertible specifically
good for back
I don't need the money for myself, so it's for you peeps
wew thanks but I'm mostly grateful for what I have
does that mean all the money is for me?
nah I'm gonna upgrade my PC and give the rest to charity
I'm thinking a Ryzen 5 3400G and GTX 1080
16gb ram ykyk
if I can get GTX 1660 I will use 2 monitors
lets move to #chit-chat
Woah my friend
@orchid portal can we merge??
hey guys
i'd like to know is there any architecture drawings for the new framework ?
documentations or meetings ?
i dunno about the progress, but ig these are essential before coding
No we have a task to document this, all my architecture are on scrap paper
The architecture is good though but it's not important to understand the code, the modules are small on their own
it'd be nice to understand the what and why; the packages and components; as models
to make good design
otherwise, we may get into serious design troubles (like others ;.)
We won't run to any troubles because we're #experts 
i know that it could be time consumming, and NOT ez
But if you have specific questions, I can answer it, documentation is a future task for us
The code is pretty self documenting imo, if you have a look at it, stuff does make sense
And screw your lead

It's okay, you're a babyy 
A lot of our choices are in this thread though
You'll find some interesting stuff by reading the chat
But there's over 3000 messages 
that's the point
i cannot read all of it
Our docs are gonna be longer 
wdym
There's so much to write
ah
we gotta be smart in that
ig drawings can help
anyway, im gonna take a look soon
Did u fix everything?
i'd like to know who is surajkumar ?
wazei
alright ty
Hopefully the non java docs are not that long
Dont u think it would be better to make a dedicated discord server for this project?
Way too easy for important info to get lost in a single thread like this imo
i merged screw it π
it's not
it's now testing season!!!
if everyone can test the life out of this with me 
I cant
Smh
I'm sorry 
hey guys
i was checking the project and tickets on GH
it seems there are tons
i wonder how those were made and analyzed ?
i need to talk a bit before i get started
(knowing that currenly im cloning the repo)
Went over the docs and made the tickets like that, with some being just general programming wisdom
And some are just a collated from what everyone else has recognised as either something we need to do, or tech debt that's been racking up
went over the docs
What docs?
discord api docs
peeps can somebody review https://github.com/javadiscord/java-discord-api/pull/95?
best to review by commits
oh nice the tests are failing now
Hey waz
hi
Oh you're doing some work nice
ah tests are failing because missing env var on gh
but they're also failing for me locally when i do gradle build but work when running standalone π¦

"devops is not a role"
it's a skill
Received HTTP status code 400 {"username": ["You are changing your username or Discord Tag too fast. Try again later."]}
rip my tests π¦
Wtf
its okay, i've tested and it works so ill keep it disabled
is it not on the imposter api?
using the real api - imposter wouldn't tell me if there are any errors besides the basic validation of our decoders
useful for testing that our models are in the right shape - that's a different part of the testing though
What needs to be worked on currently for the wrapper?
I think integration & Unit tests
documenting code
what would you recommend me to start with?
well no
we're done functionally
I am not familiar with the project at all
ah it's simple to write tests actually
we're testing the method calls work in discord as expected
yeah but I have zero context
i can show u
i am going to be showing chris too, maybe I can do something in the vc
to show how it all works
and write some tests in front of u
so u get an idea
I want to get an idea of the project
want me to walk you through the entire project?
there's this ticket you can trry working on
or maybe anything else in the no status if you're interested
hm, what kind of logging are we using, and I kinda have no idea how to implement this "flow id"
1 sec
#1223284116263276637 message
read down from here
look into "mapped diagnostic context" (MDC) on google for log4j and run some experiments
ah nice there is some baeldung article about that
do you already have a pattern in mind?
i guess just add [id] to the front maybe?
yeah, at what point should context happen?
good question
look inside :core
this class essentially is our "Action Sender"
and you can see some methods like
channel() invite() user()
those link to the actual sending methods which are located in :api
from here you can do stuff like getUser() or leaveGuild()
eventually, everything ends up inside https://github.com/javadiscord/java-discord-api/blob/main/api/src/main/java/com/javadiscord/jdi/internal/api/DiscordRequestDispatcher.java
which sends the request and gets the response
it's a bit tricky because it's async so maybe you have to link the flowId to the DiscordRequest
cancer lmao
it's a little tricky but really helpful, it was the feature zabu requested π
the main point of it all is to know which log messages are related to a specific thing
well yeah
seems quite hard though imo
if the user starts with a call to Guild#..., then the context should start
but idk
the context can start much earlier
as far as receiving an event from the websocket
most typical usecase is a response to an event e.g. channel created, message received etc
as that's what triggers the handlers the users are using
however, the scenario where we start from Guild is something like running a scheduled action (so not responding to an event but manually invoking)
im not familiar with the websocket, but like giving each websocket event its own flow id?
yeah would be nice
jump in vc
com.javadiscord.jdi.internal.gateway.handlers.events.EventCodecHandler = entry point for gateway events
:gateway module
com.javadiscord.jdi.core.Discord = entry point for sending requests
:core module
so gateway events are from discord -> bot
and sending requests are from bot -> discord
right?
yess
what happens if I start the context in the gateway EventCodecHandler and it calls a listener created by a user of the library?
because I need to specify the pattern in log4j2.xml, can users of the library also benefit from this and just update their pattern to use the context, even though it is in a different unrelated package?
that's fine - it shows the user where in the code something started from
so if an error occurs - they can know "okay so its this handler that error started from"
I am talking if they log in their code as well
i don't think it updates their own log messages?
yeah experiment, I have no idea on this stuff myself, never done it before
even mapped diagnostic context, I had to google this never heard of it before
might not even be the right solution, maybe something custom will have to be done, I am not sure π¦
We will see
π π
there is no resources folder in core? and no log4j2.xml in core? is that intended?
it might be getting inherited from another module
I am going to add one anyways
anything I need to look out for?
well I just see that only gateway got a resources folder
if you delete it, what happens, do all logs stop?
oki
ERROR com.javadiscord.jdi.internal.gateway.WebSocketHandler - [4014] Disallowed intent(s).
uh what do I do here?
Ah you didn't setup the bot properly
Give me like 15 mins I'm just away from my PC - I'll show you how to do it.
okay im here
what did I do wrong?
thid doesnt work
if you select bot you also need to select permissions
can I just select everything again?
still same error
and I think there is some bug in the websocket stuff
the first error gives 2sec delay as stated, but everything after spams instantly
yes
if u try hard enough
yeah they stop
it seems like one is enough actually
it applies to other modules as well
what can cause that
and where should the log4j2.xml be located then?
bruh
so it seems like if the module is imported its going to use that config if not specified
im just going to modify gateways existing log4j2 and check this later
also I need ideas for generating the ids
what would fit here?
first test works pretty nice
just need to find a way to make that optional
or well maybe not
going to look deeper later or tomorrow
Could just use an Integer and increment it for the time being?
Hi, this project looks interesting, I want to poke around the code. I cloned the repo but gradle doesn't seem to be pulling in any dependencies out of the box. I'm not experienced with gradle but have worked with Maven extensively. Which JDK does this project use, and how do I get Gradle to recognize the dependencies? Using Intellij 2024.1
It says 'no local installed toolchains match and toolchain download repositories have not been configured'
I'm assuming that means Gradle is either not installed or not properly configured. Looks like Gradle is installed though since I have it in my User folder
hm I just cloned it today as well, everything worked fine
might be worth creating a #1051826284008853505
I might be able to help with gradle, you dont need to install it, project provides wrapper
which Java SDK are you using?
check build.gradle ig
let me check
java 21
otherwise try to press this button in intellij
ok yeah, but where should I store that integer? it should ideally share it across the modules
the implementation seems quite easy, just some questions that needs to be answered first
let me create a list of questions in the pr
hm, well it could be anyway, in a class called FlowId with a static getter?
in which module though?
i guess make a new one called :logging or :util since it'll need to be accessible by everything?
since it'll need to be accessible by everything?
that depends
if we want all logging to have flow ids
or just stuff that relates to user stuff
like outgoing/incoming stuff
but then we simply change build.gradle for that specific module
yeah probably everything
how configurable is it?
i'd love a demo of what's possible and we can then all agree on what's best
well technically everything, as far as I understand we just need to group logging by defining a start and end of a group
for some stuff it is easy to group
for example gateway events
mhm
but for others there needs to be some analysis on how to group, for example group all initializing logging? etc
yeah all good
secret
I can wait
π
no
i'm eating
Actually I ordered food
lazy ass

squid, this now a good time or want to discuss it tomorrow?
i dont mind either way
have you got something you could show me?
ah you haven't actually implemented it right?
give me one sec
or you have?
I did, but just for one case, no need for the others its really simple
you remember EventCodecHandler#handle
yeah
basically did this:
int counter = 0;
@Override
@SuppressWarnings({"unchecked"})
public void handle(GatewayEvent gatewayEvent, ConnectionMediator connectionMediator) {
ThreadContext.put("flow.id", String.valueOf(counter++));
// actual logic
ThreadContext.clearAll();
}
and the actual logic uses logging
using this pattern in the log4j2.xml automatically going to put the id into its place:
<PatternLayout pattern="%X{flow.id} - %d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n" />
ooooooh
were u able to see that flowId through an entire journey?
and the actual complete implementation depends on the questions asked
well in this case everything that is happening in the actual logic
even in custom listener
because you call them in this logic
and the user of the library can change their log4j2.xml while still being able to optionally take use of the flow.id value
great find, let me run some tests, i'm curious how it looks with the multi-threaded parts
want to watch? I can share my screen
yeah in a sec
the first got no id because thats not in the current implementation so its fine
but you can also see that some numbers get "skipped", that happens if the EventCodecHandler#handle get called but no logging happens,
is this a problem? it kinda looks unclean, but the idea still works, having unique ids for unique flows
maybe we can set it from main?
i want to watch u
sure
what do you mean?
i'll show you
you guys in a room somewhere? or already done?
i can come in ur room if u wnt
@light loom are we switching off of the vertx ws
i need to think hard about this
Heyy noob question, I was messing around iwith the example bot, got it connected to discord and added to my server, but whenever I send a message in the channel, the bot throws NPE in the GatewayEventListener because there is no guild object in the cache... is there something I need to configure for this to be populated?
@floral halo thanks for checking, so there will be bugs, the project is still in development
I've already spotted the issue while I was writing tests and it'll eventually get fixed
Any bugs, issues etc you find, would be great if you could let us know but just so you're aware, there will be plenty of bugs 
Cool, thanks for verifying, good to know 
is there a preferred method for reporting bugs, like if I find one, should I add a new issue to the Git repo, or should I just report them in one of the Discord channels?
Issue on GH is easier to track but you can also post them here 
@light loom I'm done with exams
you german?
egyptian
but i finished early and not in june bc I'm 7th grade (preparatory 1st)
well nvm 
@light loom how are you testing btw? You just change test bot and try out stuff?
Also how can I see what you tested already and what still needs testing?
mb
so for some of the testing I am testing it by running it locally
then once I know it works I add @Disabled
because some of the actions break everything
e.g. if i did a "guild leave"
well gg im no longer in a server π
I think once this PR is fixed and merged
that gives you all the boilerplate for everyone else to write tests because they can reference this
the PR also has fixes for issues I found during testing
for example for us to decode enums properly we need a @JsonCreator
what are these countdownlatches? just used to await the asynchronous code?
yeah it basically blocks the thread until it gets woken up or times out
is there no better way?
nope - discord could be slow or rate limit could be slowing us down or anything
the tests are quick though
is there no blocking method in AsyncResponse?
nope
any reason for that?
I don't know how to make it blocking without blocking the entire application
if your handler is blocked, then you're blocking events
and if events are blocked
it'll bubble up all the way to the important areas like the gateway connection
so we'd need to do some heavy multi threading
which makes no sense to do anyway
but then we kinda have a worse api than other discord libraries
because the user of the library is forced to use async
consider this:
let me think about it - maybe I can do it
you can chain but not different requests
e.g.
getChannel()
.sendMessage()
.getUser()````
that would be dumb
but you can chain the AsyncResponse
but i often don't like it because the code ends up heavily indented
yeah exactly what I mean, you end up with ten lambdas and heavy indentation
public T block() throws Exception {
CompletableFuture<T> future = new CompletableFuture<>();
this.successConsumer = future::complete;
this.exceptionConsumer = result -> {
throw new RuntimeException(result);
};
return future.get();
}
i think this might work
weird approach lmao
it's fine imo
not sure if this even works lmao
is this fully single threaded?
networking isn't
everything else is
we're piggy backing each of the network threads
ok so is discord.start a blocking call or not? I am trying to understand lol
and there is a loop waiting for async stuff right?
yea
Yeah there's a loop in the request dispatcher class
But that loop is just to handle rate limiting
well yeah, but its not
just to handle rate limiting
this loop causes start to be blocking right?
so outgoing are single threaded
and incoming is handled by network stuff
Nope
That's running on a different thread
These are the threads:
- main
- gateway
- api calls
Vert.x under the hood handles all the threading, so we're getting free async it's just we don't have to write async code
a well my question way earlier was stupid
I asked if the start method is a blocking call
though I meant if its like blocking forever because of some loop
caused misunderstanding mb
but for example if I have a listener and it gets triggered its going to run on the gateway thread right?
so if a listener would have a heavy task it would only block some internal thread from thread pool?
Yeah
But on heavy traffic events such as message create
If you're blocking in your listener
You're potentially spawning loads of threads now
(at least that's how I think it works?)
yeah I am trying to understand what happens here as well
But this is regular java concepts
yeah ofc
I'm not sure exactly what vert.x does I think it's uncapped using the cachedThreadPool but I can't remember
It can handle a few thousand non-blocking requests per second anyway
I just remembered I need to create an issue
I set a reminder π
The issue is: we have cached objects
But we're not using them!!
what are we even caching?
Models, so stuff like channel objects, users, etc
It's internally tracked and updated
what happens if they change? the cached object would be outdated no?
ah ok
Some things we don't get events for maybe but I'll make it configurable
Maybe I can make a method in Guild
and a "is cached" boolean
So users can check before they actually make a request
The cache system is cool and simple
There's 3 types
A full cache i.e. cache everything
Partial cache which only caches models you tell it to
And no caching
By default it's set to full
But configure as you please from Discord class
That's the only module with unit tests and complete coverage 
wouldnt that need to be in the request classes?
like for example ChannelRequest#fetchChannel:
- check if caching for that is activated
- check if cached object for that id exists
- return AsyncResponse with cached object or make request
thats how I understand what you are talking about right now
I don't wanna do that in secrecy from the user because discord sends partial objects sometimes so we don't have all the fields in some of the cached objects
They might only send 3 fields when an object might have 8
Our caching updates that though (you might remember the reflection I was doing way back)
I want the user to specifically choose or configure caching behaviour
e.g. maybe they can set a property "always check cache first"
So then your scenario kicks in
Otherwise if they wanna check cache, go into it and check
ah you mean like two endpoints returning object with same id, but one endpoint might give more information than the other?
Yes
cancer
going to make caching harder and unpredicable for the user
a solution would be to have cache per endpoint in such a scenario
but thats also cancer
btw in the request dispatcher, why does it create a new httpclient for every request a user sends?
Actually we've solved the problem already 
Any object, no matter where it's from, if we've cached it - we update any null fields with the values and update the existing ones with the new data π
Oversight, if it doesn't need to be recreated, we can move it outside 
well I generally think of something redundant in the case of httpclient
Just make sure that we can still run multiple requests by having a single http client
but I might not be familiar with the api for it
The overhead is small anyway if any
not sure, quick look shows that it initialises a new cached thread pool every time
but it is definitely designed to be re-used for multiple calls
Ah perfect, we can just move it outside of the method call then, good catch
btw for the implementation of a blocking get method in AsyncResponse couldnt we simply use some lock that waits and gets notified in the setResult method?
then we additionally store a field for the result and then return it in the blocking call?
What didn't you like about the completable future?
It's actually a pretty nice implementation imo
It's pretty safe too
what if user wants to have a successConsumer and still using a blocking call?
you override it
same with error
also doesnt this introduce some new thread stuff?
and you dont even need to use wait/notify directly, you can easily use some higher level stuff from java.util.concurrent
I could try this
We can do a check
if(successConsumer != null) throw
Or we can handle multiple consumers
nah thats bad approach, you can actually just chain them
and then still use completable future
but it seems like abusing it for this case maybe?
Yeah can do, it's not making the code ugly or anything so I don't mind
well why are we even introducing asyncresponse in the first place? instead of using some existing stuff?
Primarily, flexibility and future maintainability, once we use something existing, we're stuck with the provided pattern and implementation
I would disagree
Here we can just change, extend and do anything
we can do with existing as well?
Sure, but the logic is so small and simple, the only difference at the moment is the class name and method names, in concept it's the same style as a Future
hm idk
but like CompletableFuture already comes with all the features, like chaining etc
and it is easier for user of the libary
they dont need to look up another way of the same shit
Maybe but it's really a small nitpick and I like knowing that I have complete control over our AsyncResponse
well you got complete control over completable future as well
We don't
Yeah that is an option
and then still return completable future
or if you need to introduce smth new you return your new class
the javadocs even shares an example for extending it
there is not a single final method
anyways good night
so maybe think about it 
speaking of which, there is an object mapper in DiscordResponseParser that is being instantiated with every method call, it can be updated to use the object mapper that already exists at the field level
Good catch if that's the case, it should be class level
guild.channel().createReaction(message.channelId(), message.id(), ":joy:");
randomly found issue with this:
07:13:07.170 [pool-2-thread-1] ERROR com.javadiscord.jdi.internal.api.DiscordRequestDispatcher - Failed to send request to https://discord.com/api/channels/1237095281846255699/messages/1241257237192904716/reactions/:joy:/@me
java.lang.NullPointerException: null
at java.base/java.util.Objects.requireNonNull(Objects.java:233) ~[?:?]
at java.net.http/jdk.internal.net.http.HttpRequestBuilderImpl.PUT(HttpRequestBuilderImpl.java:192) ~[java.net.http:?]
at com.javadiscord.jdi.internal.api.DiscordRequestDispatcher.sendRequest(DiscordRequestDispatcher.java:98) ~[api-1.0.0.jar:?]
at com.javadiscord.jdi.internal.api.DiscordRequestDispatcher.run(DiscordRequestDispatcher.java:58) ~[api-1.0.0.jar:?]
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1144) ~[?:?]
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:642) ~[?:?]
at java.base/java.lang.Thread.run(Thread.java:1583) [?:?]
the lines in the DiscordRequestDispatcher might not match with main
as I modified it
// DiscordRequestDispatcher.java:98
requestBuilder.PUT(discordRequestBuilder.getBody());
ah well
seems like the body is null by default
and the CreateReactionRequest is not setting it:
@Override
public DiscordRequestBuilder create() {
return new DiscordRequestBuilder()
.put()
.path(
"/channels/%s/messages/%s/reactions/%s/@me"
.formatted(channelId, messageId, emoji));
}
body should be body = HttpRequest.BodyPublishers.noBody() by default instead of null ig?
Good catch, yeah it should be if that's what works
Can you raise a PR and a test for it too?
Or create the test in my branch?
If you don't want to that's fine, I can do it
yeah I can do that
maybe later though
but if I do I just going to add it in your branch, makes more sense
btw why do we use this kind of switch in the DiscordRequestDispatcher:
switch (discordRequestBuilder.getMethod()) {
case HttpMethod.GET:
requestBuilder.GET();
break;
case HttpMethod.POST:
requestBuilder.POST(discordRequestBuilder.getBody());
break;
case HttpMethod.DELETE:
requestBuilder.DELETE();
break;
case HttpMethod.PUT:
requestBuilder.PUT(discordRequestBuilder.getBody());
break;
case HttpMethod.PATCH:
requestBuilder.method(HttpMethod.PATCH.name(), discordRequestBuilder.getBody());
break;
default:
throw new IllegalArgumentException(
"Unsupported HTTP method: " + discordRequestBuilder.getMethod());
}
why not enhanced switch with ->?
also what do we do with the example bot module? I think it should only contain print statements by default.
For example currently it does this:
public class ExampleNoAnnotate implements EventListener {
@Override
public void onMessageCreate(Message message, Guild guild) {
System.out.println("Received a message in ExampleNoAnnotate");
guild.channel()
.createInvite(1232064259085828228L, 1000, 10, true)
.onSuccess(res -> System.out.println("Result: " + res))
.onError(System.err::println);
guild.auditLogs()
.getAuditLogs(new GetAuditLogsBuilder())
.onSuccess(res -> System.out.println("Result: " + res))
.onError(System.err::println);
}
}
and this doesnt even work if you dont have permissions set for this
also it is annoying that I always need to manually rollback all the example files to not create unwanted changes
any way to fix that?
I usually do it through intellij and just keep the files I don't want committed unticked
These are very small things that don't make any difference to maintainability and functionality but if you wanna change it feel free
well readability is important as well, all the break statements are useless

what about this?
I didn't understand the question, can you explain again? Sorry
basically the default code throwing exception for me
oooh
because of some bot permissions iirc
If it's onError then that's all cool - the example itself is pretty crap, we should make a proper example lol
java.lang.Exception: Received HTTP status code 403 {"message": "Missing Permissions", "code": 50013}
com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot deserialize value of type `java.util.ArrayList<com.javadiscord.jdi.core.models.audit_log.AuditLogEntry>` from Object value (token `JsonToken.START_OBJECT`)
at [Source: REDACTED (`StreamReadFeature.INCLUDE_SOURCE_IN_LOCATION` disabled); line: 1, column: 1]
ok yeah thats easier I just noticed, but what happens if I change branch again? does it keep the uncommited changes?
bruh seems like git couldnt properly install pre commit hook
well there is none 
did I miss smth?
You can't do this, you have to commit or stash your changes before switching branches
@light loom
create issue for using cached objects!!
Ok good to know, especially putting bot token again and again can be annoying
Got pinged?
Couple of issues with GatewayEventListener line 44:
long guildId = (long) guildIdField.get(event);
Sometimes guildIdField.get(event) returns String instead of Long, so it throws ClassCastException
When it does return Long, it returns Long object instead of long primitive, so it throws ClassCastException: cannot cast java.lang.Long to long
So I think there needs to be some branching logic that checks for instanceof String, and the existing cast should be (Long) instead of (long)
just some screenshots for verification
the String issue looks like something to do with message pin (and I discovered it when pinning a message with the bot)
yeah, is it something to do with the codecs perhaps? I'm still learning the system
It's discord sending it as a String, they make things so hard 
But it's not a hard issue :p just annoying that it's an issue to begin with
haha yeah
Guys we have a new guy
He randomly joined my server
And said "hey I wanna contribute"
haha nice!
I didn't expect this at all
Pretty nice
They're gonna be working on logging
I think they had javascript in mind haha
ok nice
ping me if I can continue with flow ids
wdym
lmao
I think there is an issue in private DiscordResponseParser::parseResponse
It tries to deserialize the response directly into a List, but looks like the repsonse is actually a Map of Lists, so the response needs to be deserialized as a Map, then the appropriate list needs to be fetched by key, e.g. "audit_log_entries"
Otherwise, it throws MismatchedInputException
I can create issues on the GitHub repo, but I prefer to get confirmation before doing so, that way I don't create duplicate tickets or misreport something that isn't actually a bug
you talking about this for example?
@floral halo mind writing all these out on GH please? It's just I haven't got time to go through the stuff you've raised atm
sure no problem!
yup that's it. the ObjectMapper is trying to deserialize the response json directly into a List, but the list is inside a Map
added a few issues to the backlog
thanks 
Actually, in this case, the mapper is trying to deserialize the error message into a list, when there is no list at all. I ran into this as well. When there is no error message, however, it still doesn't deserialize properly because the list is inside a map
Hey can someone authorize me to push branches to the repo? https://github.com/NightTripperID
wym?
or do I have to fork the repo?
okies mb 
that's np π
idk might not even be on this server π€·ββοΈ
ask him
I'm gonna work on some of these bug tickets
I might as well
no problem!
28 open issues - amazing 
can you assign me to 104?
for sure! done 
106 and 103 are pretty much the same issue, I think that one will require some consideration on how to solve
106 is strange
we should only be decoding on a 200 error
unless they send a 200 with error lol
it came for me when audit logs are requested
.getAuditLogs(new GetAuditLogsBuilder())
.onSuccess(res -> System.out.println("Result: " + res))
.onError(System.err::println);```
but you get audit logs, users, webhooks, everything basically
yeah that's how it should work
so there probably needs to be some sort of mapping for elementType to response key, (e.g. AuditLogEntry.class maps to "audit_log_entries"), so it knows which list to parse, and also a way to know how to parse error responses, and afaik it's not sending 200 with error, the error response I got was a 403
hmm needs further investigation I suppose 
private <T> void success(
Class<T> type, DiscordResponse response, AsyncResponse<T> asyncResponse) {
if (response.status() >= 200 && response.status() < 300) {
try {
T result = OBJECT_MAPPER.readValue(response.body(), type);
asyncResponse.setResult(result);
} catch (JsonProcessingException e) {
asyncResponse.setException(e);
}
} else {
asyncResponse.setException(
new Exception(
"Received HTTP status code "
+ response.status()
+ " "
+ response.body()));
}
}
public <T> AsyncResponse<T> callAndParse(Class<T> clazz, DiscordRequest request) {
AsyncResponse<T> asyncResponse = new AsyncResponse<>();
DiscordResponseFuture future = dispatcher.queue(request);
future.onSuccess(res -> success(clazz, res, asyncResponse));
future.onError(asyncResponse::setException);
return asyncResponse;
}
it looks like it should just work lol
debugging timeeee
will do it once ala jshell gets deployed
private final DiscordResponseParser responseParser;
private final long guildId;
public AuditLogsRequest(DiscordResponseParser responseParser, long guildId) {
this.responseParser = responseParser;
this.guildId = guildId;
}
public AsyncResponse<List<AuditLogEntry>> getAuditLogs(GetAuditLogsBuilder builder) {
return responseParser.callAndParseList(
AuditLogEntry.class, builder.guildId(guildId).build());
}
}```
it's because getAuditLogs directly calls responseParser.callAndParseList
okay the logic is obvious now
yeah mb the issue ticket is a bit misleading
callAndParseList just needs to check the status
which it doesn't do before trying to parse to a List
at least that's one way
well, yes, for the error status, that is true
but on success, it appears the list needs to be extracted from a map
so a new method on top
welcome @floral halo
thank you!
one more detail, private <T> void success is called if the future is successful in callAndParse, but it is not called if the future is successful in callAndParseList, just to avoid confusion
do you want to work on it? π
sure I can give it a shot
i can help as much as you need
lel
Can you review his PR?
link
I'm suprised we're getting randoms contributing, it's awesome
yeah very nice
(randoms from the internet, not this server)
is a websocketmanager and all its stuff instance heavy?
like does it make sense to move the initialization in the constructor and then using the start method?
not sure how all of them work though
in which constructor?
Discord.java and start method
no i don't think so - i want to keep it as simple to call
?
like my question is if they actually do anything before this line:
webSocketManagerProxy.start(connectionMediator);
so it looks like just the audit log entries are coming as a map, all the other DiscordRequests that utilize callAndParseList appear to be coming as lists, so it's unique to that endpoint. I tried it in Postman and it's also coming as a Map there as well. Was this this what was expected to come from this endpoint?
So I think, yeah, another method, callAndParseMapToList or something would be the best solution, and you can pass a key as a parameter
ill check soon
we just made guesses, the phase rn is testing and correcting - this issue might not be unique to this endpoint
cool, no worries, I think I can draft a solution that can be applied to any other endpoints we find that might fit this bill
uh I cant review using intellij?
@oak flare wazel denied this earlier
he did?
can you add me to 103 and 106?
pr to fix those:
https://github.com/javadiscord/java-discord-api/pull/113
Hey guys, im new here. Im the "mennafabio" guy from github. Found your Discord Server, happy to be here. I dont have much to do with Discord Bots and that topic but looking forward to learn more about that :)!
Hi, thanks for your contribution
note that this server isnt technically related to the project itself
Sure, im glad i finally found an interesting "Java" Topic based Discord Server.
welcome! I'm surpised you found us on TJ!
also im looking at your comments rn, so about the little stop method in the setter or method. Isnt there then redundant or duplicated code? since we already then have the "stop" method.
Actually i found this project via the "good first issues" website, since i've never contributed to any project, i wanted to try this out and there i saw some first grabs for this project
what good first issue website? π
lol
this one https://goodfirstissues.com/
Good First Issues empowers first-time contributors of open-source software. This website is primarily targeted at developers who want to contribute to open source software but do not know where or how to start. By providing developers with filters, the website empowers them to browse and select issues/repositories based on programming languages ...
just googled and this website came up, and if you filter "java" your project is also there.
wow that's insane
think there is a scanner whichs scans github labels and index it in there
pretty cool though
lol thats nice
i'm surprised to see organic contributors - really nice
I was talking about replacing the setter
public class DiscordRequestDispatcher implements Runnable {
// ...
private boolean running = false;
// ...
@Override
public void run() {
running = true;
while (running) {
// ...
}
}
public void stop() {
running = false;
}
}
I thought about smth like this instead
and then maybe introduce logic if we want to let already queued requests to run
same idea what executors shutdown vs shutdownNow does maybe
yeah possible 2 variants, a graceful shutdown were the dispatcher rejects additional requests but still finishes the current queue
and then a forced shutdown that completely stops the dispatcher
But then the while condition of "running" becomes useless i think, since it checks if it is true but thats always the case since we are setting running = true always first in the run() method
or maybe i understand the Runnable interface wrong, could also be the case π
well its supposed to be a while true loop until someone uses the stop method to stop the loop
run() gets invoked by the start() however, if you set it in the constructor the value will be running = true but the thread might not have started, so it's not actually running
if we had a getter e.g. isRunning that would return true even if the thread had not started
something to think about, should running be Atomic?
yeah I was questioning smth like that as well 
I think maybe but my brain isn't working right now lol
since stop() will be called by another thread, it should be ig
Mhh good point, that would make the boolean thread-safe. I've implemented the stop() also now in DiscordRequestDispatcher with a TODO for the implementation. Think it makes sense to open a new Isse for that since it has nothign to do with the actual Discord stop method.
I also need to think on how to handle the queue in that stop method 
wouldnt volatile be enough here?
well no ig
both threads write to the variable
well im not sure
not that into thread safety
?
I was just updating the main post with the list of contributors and then dyno bot said "don't mass mention members"
and deleted the entire post
lol?
@lavish nest
this is so stupid π
can you keep it safe so I can figure out how to bring it back
just stupid that it deleted the original message, looks weird in #1150852739467849829
i am actually so annoyed lol
A wrapper over the discord API to create bots using Java - javadiscord/java-discord-api
sad pin lmao
well - i was using it to keep track of all the members that have contributed - we have 8 people that have raised PRs and they have been merged, with 4 people with work in progress, it was a way for me to keep track of you all and to show that you're efforts were not going unnoticed - still - we can take the L with the original post and continue as normal 
Stupid dyno 
It's not dyno's fault, he was just programmed that way 

declaration: module: java.compiler, package: javax.annotation.processing, class: AbstractProcessor
i tried fixing the spotless
will make a pr
pls merge and we'll improve it over time
hey guys
i think about getting started soon, anybody helps me to find something to do ?
I may pick something that is already in progress with someone else
see the job board
where ?
alright i see it
what i do next ?
pick one from redy
how do i pick it ?
comment on the issue
ah !
i'll assign u
alr thanks
you can do #81
wazei decided to take some time off, and focus on himself 
so in terms of his responsibilities and commitments, everything he has been contributing to on this server is on pause, including this project
cant we continue? or would you say we should stop and wait for him?
he is currently not on the server, so please try to respect that and not DM him ^^
he has opened pull request today
he deserves break 
yeah, of course ^^
we can give wazei a surprise for when he is back 
it's in review ?
@oak flare when you get the chance, can you move 103, 104, and 106 to done? The code for those has been merged
yea
well seems like the issue arent linked to the prs
because the issues are still open
instead of relates to issue ... use github keywords like
resolves #103
hmm, I tried linking the prs to the issues but I couldn't figure it out, not sure if it is a permissions thing
oh is it a keyword thing?
well editing afterwards wont close them automatically anymore
but I am going to close them manually 
thanks
which pr relates to #108?
let me check
yes, issue 104 is pr 108
all should be closed now
I don't know
yea i talked ho him
I know, just wanted to let everyone else know ^^
but he also said this project doesnt have to be on pause
he'll do his part from github
yup ^^
but also do not want people to ping him too much, or expect feedback from him
he will probably be low availability, and that's fine, he deserves a break 
doesn't mean project won't continue to function
I have maintainer role now as well, and will be here if needed for my access
actually we all got maintainer lol


