#We're making a wrapper over the Discord API using Java!!

1 messages Β· Page 4 of 1

light loom
#
  • annotation based processing
  • you don't need to start a gateway session to use their web API
  • We're gonna have hot reloading
  • We might have a drag and drop editor
steep spruce
#

yes, I'm middle eastern silly
I know falafel and tasted it

light loom
#

Yeah error handling

tawdry pewter
#

u from lebanon?

steep spruce
#

I just prefer shawarma or koshari

light loom
#

Oh guess what we're also gonna have tests, JDA has 0 pepekek

steep spruce
plain ledge
light loom
#

Plz halloumi and falafel in a wrap

steep spruce
#

koshari fills you up and is awesome

tawdry pewter
light loom
#

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 pepe_sad

tawdry pewter
#

War Ο€ API . it's like a poem

light loom
#

Warpi

steep spruce
#

omg yes

#

I love warpi

#

I love to warpi mi shawarmi

placid wharfBOT
#
TJ-Bot
What does warpi mean

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.

steep spruce
#

yk what I'm saying

light loom
#

Perfect

#

It's unused

#

Let's give it a meaning

steep spruce
steep spruce
#

it's easi

light loom
#

warpi Uranus

steep spruce
#

sorry

light loom
#

It's okay to fight me , I'm kinda trolling on a serious topic

#

Warpi

steep spruce
#

I'd do the same

light loom
#

Just pinning so we don't forget

steep spruce
#

oh cool I've never been pinned in a big server

light loom
#

I pinned some of the suggestions

light loom
#

Let's poll

light loom
#

cast your votes

oak flare
#

tbh I don’t like any of these pepekek

plain ledge
#

What are you making?

light loom
light loom
oak flare
#

But also hard

plain ledge
#

How about jiscord

oak flare
#

That sound sus

light loom
#

until i read this

brave ridge
#

I wouldn't go for names that cast shade on other projects like BetterJDA.

light loom
#

but u voted openjda

#

ah well java discord api

#

maybe

#

they cause shame on themselves for going with the name JDA to begin with

sharp ferry
light loom
#

it can be in some scenarios

#

but i'm gonna leave the naming to the community

sharp ferry
#

Let's call it Angklung

oak flare
sharp ferry
#

Angcord

#

so my idea is the following :

light loom
#

i can imagine a viking saying "AngC0RD!!"

brave ridge
#

DrocsidA?

light loom
#

peeps should consider SEO pepe_sad

sharp ferry
#

-cord makes me think about music cords
I googled favorite music instrument of java island, and I got Angklung

light loom
#

Cord&Coffee

#

sound cools - looks ugly 😐

sharp ferry
#

Gamecord

#

from Gamelan, a music nstrument from java

#

wait

#

no

light loom
sharp ferry
#

it looks too much like game

#

yea

#

wait

#

Jazzcord

#

πŸ™‚

#

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...

brave ridge
#

Also make sure it's SEO friendly. Disbot/uranium/... don't tick that box.

steep spruce
#

I didn't expect him to add it to a list of things to choose from

light loom
#

i thought u were srs

#

the explosive framework

steep spruce
#

πŸ’€

light loom
#

not too long, after our testing and docs are done...

#

the promotional campaign animesmile

#

"THIS VIDEO IS SPONSORED BY <insert name>"

#

i kid :3 - i'm gonna message discord directly

steep spruce
#

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

light loom
#

what am i, jeff bezos?

steep spruce
#

idk maybe send a selfie

light loom
#

i mean if discord really did sponsor us

#

i'd split

#

if they don't - im at least gonna try get us lifetime nitro

steep spruce
#

lol

light loom
#

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

steep spruce
#

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

light loom
#

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

steep spruce
#

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

light loom
#

this is our manual when not using annotations

orchid portal
oak flare
#

Would be doable for me

#

Though not sure what you mean by drag and drop editor

light loom
#

The only complexity is the frontend which can do in html

oak flare
#

JavaFX >

steep spruce
light loom
#

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"

steep spruce
#

.

light loom
#

And call one of the API requests

#

Then when you press generate, it should create a .java file

orchid portal
# light loom

if we do ever actually make this, make it not spit out the code and commercialize

#

for hosting

light loom
#

You think we should charge money?

orchid portal
#

ofc

light loom
steep spruce
#

ofc

light loom
#

Bet bet

orchid portal
steep spruce
# light loom I didn't understand

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

light loom
steep spruce
#

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

light loom
#

I'll look later

#

If we make commercial tooling and it actually sells wow.

steep spruce
steep spruce
#

convertible specifically

#

good for back

light loom
#

I don't need the money for myself, so it's for you peeps

steep spruce
orchid portal
steep spruce
#

I'm thinking a Ryzen 5 3400G and GTX 1080

#

16gb ram ykyk

#

if I can get GTX 1660 I will use 2 monitors

orchid portal
plain ledge
steep spruce
#

ik

light loom
#

@orchid portal can we merge??

worthy flower
#

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

light loom
#

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

worthy flower
#

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 ;.)

light loom
#

We won't run to any troubles because we're #experts peepo_heart

worthy flower
#

i know that it could be time consumming, and NOT ez

light loom
#

But if you have specific questions, I can answer it, documentation is a future task for us

worthy flower
#

it's not that

#

but ok iget it

#

(same as my team lead usually says)

#

:p

light loom
#

The code is pretty self documenting imo, if you have a look at it, stuff does make sense

#

And screw your lead peepo_heart peepo_knife

worthy flower
#

i understand

#

i hope im wrong

light loom
#

It's okay, you're a babyy peepo_heart

#

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 peepoW

worthy flower
#

i cannot read all of it

light loom
#

Our docs are gonna be longer pepe_sad

worthy flower
#

wdym

light loom
#

There's so much to write

worthy flower
#

ah

#

we gotta be smart in that

#

ig drawings can help

#

anyway, im gonna take a look soon

orchid portal
worthy flower
#

i'd like to know who is surajkumar ?

oak flare
#

wazei

worthy flower
#

alright ty

plain ledge
restive void
#

Way too easy for important info to get lost in a single thread like this imo

orchid portal
#

the myth

#

the legend

light loom
#

i merged screw it 😐

oak flare
#

last words

#

before disaster

light loom
#

it's not

#

it's now testing season!!!

#

if everyone can test the life out of this with me peepo_heart

oak flare
#

I cant

plain ledge
#

Smh

light loom
worthy flower
#

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)

light loom
#

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

worthy flower
oak flare
light loom
#

time to write some tests

#

this will take me forever

light loom
#

best to review by commits

#

oh nice the tests are failing now

worthy flower
#

Hey waz

light loom
#

hi

worthy flower
#

Oh you're doing some work nice

light loom
#

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 😦

worthy flower
light loom
#

it's a skill

light loom
#

Received HTTP status code 400 {"username": ["You are changing your username or Discord Tag too fast. Try again later."]}

#

rip my tests 😦

worthy flower
#

Wtf

light loom
#

its okay, i've tested and it works so ill keep it disabled

orchid portal
light loom
#

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

restive void
#

What needs to be worked on currently for the wrapper?

plain ledge
#

documenting code

restive void
#

Oh nah

#

U guys got that one πŸ‘πŸ‘

light loom
#

Testing pepe_sad

oak flare
#

what would you recommend me to start with?

light loom
#

testssss]

#

test anything

oak flare
#

well no

light loom
#

we're done functionally

oak flare
#

I am not familiar with the project at all

light loom
#

ah it's simple to write tests actually

#

we're testing the method calls work in discord as expected

oak flare
#

yeah but I have zero context

light loom
#

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

oak flare
#

I want to get an idea of the project

light loom
#

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

oak flare
#

hm, what kind of logging are we using, and I kinda have no idea how to implement this "flow id"

light loom
#

1 sec

#

#1223284116263276637 message

#

read down from here

#

look into "mapped diagnostic context" (MDC) on google for log4j and run some experiments

oak flare
#

ah nice there is some baeldung article about that

#

do you already have a pattern in mind?

light loom
#

i guess just add [id] to the front maybe?

oak flare
#

yeah, at what point should context happen?

light loom
#

good question

oak flare
#

on some request?

#

or do we have an action system or whatever?

light loom
#

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()

#

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

oak flare
#

cancer lmao

light loom
#

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

oak flare
#

well yeah

#

seems quite hard though imo

#

if the user starts with a call to Guild#..., then the context should start

#

but idk

light loom
#

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)

oak flare
#

im not familiar with the websocket, but like giving each websocket event its own flow id?

light loom
#

mhm

#

would you like a walk through the codebase squid?

oak flare
#

yeah would be nice

light loom
#

jump in vc

light loom
#

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

oak flare
#

so gateway events are from discord -> bot
and sending requests are from bot -> discord
right?

light loom
#

yess

oak flare
#

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?

light loom
#

so if an error occurs - they can know "okay so its this handler that error started from"

oak flare
#

I am talking if they log in their code as well

light loom
#

i don't think it updates their own log messages?

oak flare
#

but if its still in the same context?

#

whatever I will just try it out πŸ˜›

light loom
#

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 😦

oak flare
#

We will see

light loom
#

πŸ™‚ πŸ™‚

oak flare
#

there is no resources folder in core? and no log4j2.xml in core? is that intended?

light loom
#

no, probably just didn't notice

#

but we do get logs

#

so not sure xd

oak flare
#

huh

#

tf

light loom
#

it might be getting inherited from another module

oak flare
#

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

light loom
#

if you delete it, what happens, do all logs stop?

oak flare
#

well let me setup a bot token

#

so I can test

light loom
#

oki

oak flare
#

ERROR com.javadiscord.jdi.internal.gateway.WebSocketHandler - [4014] Disallowed intent(s).
uh what do I do here?

light loom
#

Ah you didn't setup the bot properly

oak flare
#

probably lmao

#

just selected everything

#

lmao

light loom
#

Give me like 15 mins I'm just away from my PC - I'll show you how to do it.

oak flare
#

ah ok

#

all good

light loom
#

okay im here

oak flare
#

what did I do wrong?

light loom
#

tick these in the "Bot" page

oak flare
#

ah thanks

#

they changed the ui again peepo_sad_2

light loom
#

under "Installation"

#

oh

#

this is the new bit

oak flare
#

if you select bot you also need to select permissions

#

can I just select everything again?

light loom
#

yeah try that

#

it's new so i'm not sure about this page

oak flare
#

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

light loom
#

can you send me ur token?

#

this was an issue a long time ago but I had fixed it since

oak flare
#

uh yeah

#

can you even send them through discord though?

light loom
#

yes

orchid portal
oak flare
#

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?

#

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

light loom
#

Could just use an Integer and increment it for the time being?

floral halo
#

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

oak flare
#

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

floral halo
#

which Java SDK are you using?

oak flare
#

check build.gradle ig

#

let me check

#

java 21

#

otherwise try to press this button in intellij

floral halo
#

i just added java 21 and that fixed it

#

thanks bro

oak flare
#

the implementation seems quite easy, just some questions that needs to be answered first

#

let me create a list of questions in the pr

light loom
#

hm, well it could be anyway, in a class called FlowId with a static getter?

oak flare
#

in which module though?

light loom
#

i guess make a new one called :logging or :util since it'll need to be accessible by everything?

oak flare
#

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

light loom
#

how configurable is it?

#

i'd love a demo of what's possible and we can then all agree on what's best

oak flare
#

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

light loom
#

mhm

oak flare
#

but for others there needs to be some analysis on how to group, for example group all initializing logging? etc

light loom
#

ah i see, cool will discuss with you later

#

i'm currently...

#

you know...

oak flare
#

yeah all good

light loom
#

secret

oak flare
#

I can wait

light loom
#

πŸ˜„

sharp ferry
#

no

light loom
#

i'm eating

oak flare
#

ofc

#

what are you saying in this situation in english? "Enjoy your meal"?

light loom
#

Actually I ordered food

oak flare
#

lazy ass

light loom
#

i got indian

#

it's not lazy, it's difficult

oak flare
light loom
#

squid, this now a good time or want to discuss it tomorrow?

oak flare
#

i dont mind either way

light loom
#

have you got something you could show me?

oak flare
#

well there is not much to show

#

the idea is simple

light loom
#

ah you haven't actually implemented it right?

oak flare
#

give me one sec

light loom
#

or you have?

oak flare
#

you remember EventCodecHandler#handle

light loom
#

yeah

oak flare
#

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" />
light loom
#

ooooooh

oak flare
#

thats it

#

there is not more too it

light loom
#

were u able to see that flowId through an entire journey?

oak flare
#

and the actual complete implementation depends on the questions asked

oak flare
#

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

light loom
#

great find, let me run some tests, i'm curious how it looks with the multi-threaded parts

oak flare
#

well yeah

#

let me show you smth

light loom
#

want to watch? I can share my screen

oak flare
#

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

light loom
#

maybe we can set it from main?

orchid portal
light loom
#

sure

oak flare
light loom
#

i'll show you

floral halo
#

you guys in a room somewhere? or already done?

orchid portal
plain ledge
#

@light loom are we switching off of the vertx ws

light loom
floral halo
#

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?

light loom
#

@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 pepe_sad

floral halo
#

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?

light loom
#

Issue on GH is easier to track but you can also post them here peepo_heart

steep spruce
#

@light loom I'm done with exams

oak flare
#

you german?

steep spruce
#

but i finished early and not in june bc I'm 7th grade (preparatory 1st)

oak flare
#

well nvm pepekek

oak flare
#

@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?

light loom
#

i have a PR

#

sec

oak flare
#

mb

light loom
#

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

oak flare
#

what are these countdownlatches? just used to await the asynchronous code?

light loom
#

yeah it basically blocks the thread until it gets woken up or times out

oak flare
#

is there no better way?

light loom
#

nope - discord could be slow or rate limit could be slowing us down or anything

#

the tests are quick though

oak flare
#

is there no blocking method in AsyncResponse?

light loom
#

nope

oak flare
#

any reason for that?

light loom
#

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

oak flare
#

but then we kinda have a worse api than other discord libraries

light loom
#

why? because we can't block?

#

but what if an error occurs?

oak flare
#

because the user of the library is forced to use async

light loom
#

consider this:

oak flare
#

idc about the implementation right now

#

just talking from the user perspective

light loom
#

let me think about it - maybe I can do it

oak flare
#

same with chaining

#

I like the way jda does it

#

though its not perfect

light loom
#

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

oak flare
#

yeah exactly what I mean, you end up with ten lambdas and heavy indentation

light loom
#
    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

oak flare
#

weird approach lmao

light loom
#

it's fine imo

oak flare
#

not sure if this even works lmao

light loom
#

im testing wait

#

okay

#

i think it works

oak flare
#

is this fully single threaded?

light loom
#

networking isn't

#

everything else is

#

we're piggy backing each of the network threads

oak flare
#

ok so is discord.start a blocking call or not? I am trying to understand lol

light loom
#

yeah its a blocking call

#

but the multi threading is provided by the network code

oak flare
#

and there is a loop waiting for async stuff right?

light loom
#

nope no loop

#

unless you mean sending requests to discord api async? then yes

oak flare
#

yea

light loom
#

Yeah there's a loop in the request dispatcher class

#

But that loop is just to handle rate limiting

oak flare
#

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

light loom
#

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

oak flare
#

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

light loom
#

Ah

#

Yeah it's not blocking the main thread:)

oak flare
#

but for example if I have a listener and it gets triggered its going to run on the gateway thread right?

light loom
#

Yeah

#

Which is based on vert.x internal thread pool

oak flare
#

so if a listener would have a heavy task it would only block some internal thread from thread pool?

light loom
#

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?)

oak flare
#

yeah I am trying to understand what happens here as well

light loom
#

But this is regular java concepts

oak flare
#

yeah ofc

light loom
#

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!!

oak flare
#

what are we even caching?

light loom
#

Models, so stuff like channel objects, users, etc

#

It's internally tracked and updated

oak flare
#

what happens if they change? the cached object would be outdated no?

light loom
#

If they change, the gateway sends an update event

#

But

oak flare
#

ah ok

light loom
#

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 pepekek

oak flare
# light loom Maybe I can make a method in Guild

wouldnt that need to be in the request classes?
like for example ChannelRequest#fetchChannel:

  1. check if caching for that is activated
  2. check if cached object for that id exists
  3. return AsyncResponse with cached object or make request

thats how I understand what you are talking about right now

light loom
#

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

oak flare
light loom
#

Yes

oak flare
#

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?

light loom
#

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 😍

light loom
oak flare
#

well I generally think of something redundant in the case of httpclient

light loom
#

Just make sure that we can still run multiple requests by having a single http client

oak flare
#

but I might not be familiar with the api for it

light loom
#

The overhead is small anyway if any

oak flare
#

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

light loom
#

Ah perfect, we can just move it outside of the method call then, good catch

oak flare
#

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?

light loom
#

What didn't you like about the completable future?

#

It's actually a pretty nice implementation imo

#

It's pretty safe too

oak flare
#

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

light loom
#

We can do a check

#

if(successConsumer != null) throw

#

Or we can handle multiple consumers

oak flare
#

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?

light loom
#

Yeah can do, it's not making the code ugly or anything so I don't mind

oak flare
#

well why are we even introducing asyncresponse in the first place? instead of using some existing stuff?

light loom
#

Primarily, flexibility and future maintainability, once we use something existing, we're stuck with the provided pattern and implementation

oak flare
#

I would disagree

light loom
#

Here we can just change, extend and do anything

oak flare
#

we can do with existing as well?

light loom
#

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

oak flare
#

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

light loom
#

Maybe but it's really a small nitpick and I like knowing that I have complete control over our AsyncResponse

oak flare
#

well you got complete control over completable future as well

light loom
#

We don't

oak flare
#

you do

#

you can simply extend it

light loom
#

Yeah that is an option

oak flare
#

and then still return completable future

light loom
#

I'm okay to explore extending

#

Because that retains our control

oak flare
#

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 peepo_heart

floral halo
light loom
oak flare
#
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?

light loom
#

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

oak flare
#

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?

light loom
light loom
oak flare
light loom
#

It's also readable :p

#

But I don't mind the change if you find it less readable

oak flare
light loom
#

I didn't understand the question, can you explain again? Sorry

oak flare
#

basically the default code throwing exception for me

light loom
#

oooh

oak flare
#

because of some bot permissions iirc

light loom
#

Uncaught exception?

#

Or is it the onError

oak flare
#

uh cant tell right now

#

let me test real quick

light loom
#

If it's onError then that's all cool - the example itself is pretty crap, we should make a proper example lol

oak flare
#
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]
light loom
#

Damnit

#

We'll get there

#

Slowly does it πŸ˜„

oak flare
#

yeah all good

#

just wanted to mention it

oak flare
#

bruh seems like git couldnt properly install pre commit hook

#

well there is none peepo_think

#

did I miss smth?

light loom
#

It's just a GHA

light loom
placid wharfBOT
#

@light loom

wazei

create issue for using cached objects!!

oak flare
oak flare
#

Got pinged?

floral halo
#

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)

light loom
#

It's coming back as a String!?

#

Amazing find @floral halo !

floral halo
#

yeah, is it something to do with the codecs perhaps? I'm still learning the system

light loom
#

It's discord sending it as a String, they make things so hard pepe_sad

#

But it's not a hard issue :p just annoying that it's an issue to begin with

floral halo
#

haha yeah

light loom
#

Guys we have a new guy

#

He randomly joined my server

#

And said "hey I wanna contribute"

floral halo
#

haha nice!

light loom
#

I didn't expect this at all

oak flare
#

Pretty nice

light loom
#

They're gonna be working on logging

floral halo
oak flare
#

ping me if I can continue with flow ids

light loom
#

he...

#

did it in the wrong repo...

oak flare
#

wdym

light loom
#

comments on: java-discord-api

#

does work in lj-discord-bot

oak flare
#

there are 2 repos?

#

lel

light loom
#

this repo has 0 issues

#

its just a bot using JDA

oak flare
#

lmao

floral halo
#

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

oak flare
light loom
#

@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

floral halo
floral halo
#

added a few issues to the backlog

oak flare
#

thanks peepo_heart

floral halo
floral halo
light loom
#

wym?

floral halo
#

or do I have to fork the repo?

light loom
#

yeah

#

fork and create PR πŸ™‚

floral halo
#

okies mb pepekek

light loom
#

npp

#

i just saw the issues - they look well written btw ty peepo_heart

floral halo
#

thanks!

#

I couldn't put labels on them so you'll have to do that part

light loom
#

that's np πŸ™‚

light loom
#

what does WARPI stand for again? lol

oak flare
#

nah bro

#

idk

#

@floral halo thanks for creating the #107 issue, forgot to peepo_heart

light loom
#

who's mennafabio on GH?

oak flare
#

idk might not even be on this server πŸ€·β€β™‚οΈ

light loom
#

lmfao

#

i think it is

#

somebody here

oak flare
#

ask him

light loom
#

I'm gonna work on some of these bug tickets

oak flare
#

I might as well

light loom
#

28 open issues - amazing gigachad

floral halo
light loom
#

for sure! done peepo_heart

floral halo
#

106 and 103 are pretty much the same issue, I think that one will require some consideration on how to solve

light loom
#

106 is strange

#

we should only be decoding on a 200 error

#

unless they send a 200 with error lol

floral halo
#

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

light loom
#

yeah that's how it should work

floral halo
#

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

light loom
#

hmm

#

I would assume the onError would have kicked

#

Maybe there's a small bug there

floral halo
#

hmm needs further investigation I suppose spongehmm

light loom
#
    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

oak flare
#

I can do some debugging

#

link issue

floral halo
#
    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

light loom
#

okay the logic is obvious now

floral halo
#

yeah mb the issue ticket is a bit misleading

light loom
#

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

floral halo
#

well, yes, for the error status, that is true

#

but on success, it appears the list needs to be extracted from a map

light loom
#

so a new method on top

molten tusk
#

welcome @floral halo

floral halo
floral halo
light loom
#

do you want to work on it? πŸ™‚

floral halo
#

sure I can give it a shot

light loom
#

i can help as much as you need

light loom
#

@oak flare

#

u were right!!

oak flare
#

lel

light loom
#

Can you review his PR?

oak flare
#

link

light loom
#

I'm suprised we're getting randoms contributing, it's awesome

oak flare
#

yeah very nice

light loom
#

(randoms from the internet, not this server)

oak flare
#

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

light loom
#

in which constructor?

oak flare
#

Discord.java and start method

light loom
#

no i don't think so - i want to keep it as simple to call

oak flare
#

?

#

like my question is if they actually do anything before this line:

webSocketManagerProxy.start(connectionMediator);
floral halo
#

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

light loom
floral halo
oak flare
#

uh I cant review using intellij?

orchid portal
#

@oak flare wazel denied this earlier

oak flare
#

and?

#

he approved it

#

now

#

lol

orchid portal
oak flare
#

ah nvm

#

it was the other pr

#

mb

#

any reason why he denied it?

light loom
#

uh

#

lol

floral halo
winter jungle
oak flare
#

Hi, thanks for your contribution

#

note that this server isnt technically related to the project itself

winter jungle
#

Sure, im glad i finally found an interesting "Java" Topic based Discord Server.

light loom
#

welcome! I'm surpised you found us on TJ!

winter jungle
#

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.

winter jungle
light loom
oak flare
#

lol

winter jungle
#
#

just googled and this website came up, and if you filter "java" your project is also there.

light loom
#

wow that's insane

winter jungle
#

think there is a scanner whichs scans github labels and index it in there

light loom
#

pretty cool though

oak flare
#

lol thats nice

light loom
#

i'm surprised to see organic contributors - really nice

oak flare
#
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

light loom
#

and then a forced shutdown that completely stops the dispatcher

winter jungle
#

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 πŸ˜„

oak flare
#

well its supposed to be a while true loop until someone uses the stop method to stop the loop

light loom
#

if we had a getter e.g. isRunning that would return true even if the thread had not started

light loom
oak flare
#

yeah I was questioning smth like that as well peepo_think

light loom
#

I think maybe but my brain isn't working right now lol

#

since stop() will be called by another thread, it should be ig

winter jungle
#

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 peepo_think

oak flare
#

well no ig

#

both threads write to the variable

#

well im not sure

#

not that into thread safety

light loom
#

WTF

#

IT DELETED THE OP

oak flare
#

?

light loom
#

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

oak flare
#

hell nah

#

thanks dyno

light loom
#

this is so stupid 😐

oak flare
#

well I got the message in logs

#

if you want

light loom
#

can you keep it safe so I can figure out how to bring it back

oak flare
#

just stupid that it deleted the original message, looks weird in #1150852739467849829

light loom
#

i am actually so annoyed lol

oak flare
#

same

#

that just stupid

light loom
oak flare
#

sad pin lmao

light loom
#

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 peepo_heart

molten tusk
#

Stupid dyno reeee

floral halo
#

It's not dyno's fault, he was just programmed that way pepe_sad

orchid portal
orchid portal
#

i tried fixing the spotless

#

will make a pr

#

pls merge and we'll improve it over time

worthy flower
#

hey guys

#

i think about getting started soon, anybody helps me to find something to do ?

molten tusk
#

pick any issues

#

or find bugs

worthy flower
worthy flower
#

where ?

worthy flower
#

what i do next ?

orchid portal
worthy flower
#

how do i pick it ?

orchid portal
worthy flower
orchid portal
#

i'll assign u

worthy flower
#

alr thanks

molten tusk
#

you can do #81

lavish nest
#

so in terms of his responsibilities and commitments, everything he has been contributing to on this server is on pause, including this project

oak flare
#

cant we continue? or would you say we should stop and wait for him?

lavish nest
#

he is currently not on the server, so please try to respect that and not DM him ^^

molten tusk
#

he has opened pull request today

lavish nest
#

he deserves break peepo_heart

lavish nest
molten tusk
#

we can give wazei a surprise for when he is back peepo_heart

worthy flower
floral halo
#

@oak flare when you get the chance, can you move 103, 104, and 106 to done? The code for those has been merged

oak flare
#

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
floral halo
#

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?

oak flare
#

well editing afterwards wont close them automatically anymore

#

but I am going to close them manually cat_thumbs_up

floral halo
#

thanks

oak flare
#

which pr relates to #108?

floral halo
#

let me check

oak flare
#

uh I mean 104

#

but it is fixed by 108

floral halo
#

yes, issue 104 is pr 108

oak flare
#

all should be closed now

molten tusk
lavish nest
#

I know, just wanted to let everyone else know ^^

orchid portal
#

but he also said this project doesnt have to be on pause

#

he'll do his part from github

lavish nest
#

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 peepo_heart

#

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

oak flare
#

actually we all got maintainer lol

lavish nest
#

yeah, I know

#

for people currently working on it

#

things change with time tho, people come and go, it's and open-source project

#

they have other things they need to take care of