Giter Club home page Giter Club logo

discord-webhooks's People

Contributors

almighty-satan avatar atakku avatar balam314 avatar bungeefan avatar dan-dr avatar fratik avatar github-actions[bot] avatar jroy avatar justpyrrha avatar kantenkugel avatar minndevelopment avatar mrletsplay2003 avatar nea89o avatar xirado avatar zavarov avatar zbutwialypiernik avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

discord-webhooks's Issues

shadowJar command not found

Tried to use ./gradlew shadowJar (./ because im on mac) and it failed because shadowJar command was "not found"
Im probably just dumb, but if you could help me I would be very happy
BTW im using this for a minecraft mod, if that info helps.

Catching HttpExceptions in own code

Currently I use this library for logging by sending embeds to specified webhooks. But if the channels get remade and the new webhook link is still not replaced I get the following error.

Sending a webhook message failed with non-OK http response 
club.minnced.discord.webhook.exception.HttpException: Request returned failure 404: {"message": "Unknown Webhook", "code": 10015}
	at club.minnced.discord.webhook.WebhookClient.failure(WebhookClient.java:722)
	at club.minnced.discord.webhook.WebhookClient.executePair(WebhookClient.java:797)
	at club.minnced.discord.webhook.WebhookClient.drainQueue(WebhookClient.java:766)
	at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515)
	at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
	at java.base/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:304)
	at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1130)
	at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:630)
	at java.base/java.lang.Thread.run(Thread.java:831)

Is there any way to catch these exceptions or have them not display in the log files?

Issue with gradle implementation

Hi,

I recently transferred one of my discord bot projects to gradle. When I try to compile it with the dependencies I get an error.

org.gradle.api.tasks.TaskExecutionException: Execution failed for task ':jar Caused by: org.gradle.api.GradleException: Could not expand ZIP 'C:\Users\drews\.gradle\caches\modules-2\files-2.1\club.minnced\opus-java\1.0.4\596995aaf2f5b5091c4d251fdc11fa62680cc59e\opus-java-1.0.4.pom'' Caused by: java.util.zip.ZipException: archive is not a ZIP archive

It looks like a .pom file (which is for maven) is put into the opus folder and gradle tries to open that like a jar file. I'm not sure if this is something you have control over, but it only happens for this dependency.

Support for changing webhook channels

I have been making a bot like tupperBox using JDA and discord-webhooks, that uses webhooks to send messages. The problem is that they are limited to a channel per webhook only, and I would like to reuse the same webhook on multiple channels, by changing the webhook's channel. I have seen no way to achieve this so far...
image

Sending multiple embeds in one WebhookMesssage

I'm attempting to get a queue-based system up and running, which will collapse all given embeds into one message to send them speedily, but still comply with Discord's rate limits. Essentially, here is where I am at now:

// called every few seconds
fun run(): () -> Unit = {
    if (embeds.isNotEmpty()) {
        val toAdd = mutableListOf<WebhookEmbed>()
        for (i in 0 until 10) {
            val embed = embeds.poll()
            if (embed != null) toAdd.add(embed)
        }
        println("Amount of embeds in toAdd: ${toAdd.size}")
        send(WebhookMessage.embeds(toAdd)) // works perfectly as intended
    }
}

The amount of embeds that are added is the proper amount, and when I later check directly from the WebhookMessage object, I get the proper amount. However, in practice, the amount that is sent per message is only one.

I'm not receiving any errors or anything really indicating something not working correctly. I've tried multiple ways of creating the WebhookMessage object like using the WebhookMessageBuilder to test if the way they were being created could be the cause, but always got the same result so it must be something about how they're being sent.

I absolutely adore this library... it's been real handy for me and my projects and I hope that this can be fixed soon, or that I could be directed to a possible solution. If you require more information or code snippets, don't hesitate to let me know.

Error in Sending Webhooks

Version :

<dependency>
    <groupId>club.minnced</groupId>
    <artifactId>discord-webhooks</artifactId>
    <version>0.3.2</version>
</dependency>

Environment:
Java 8 with SpringBoot

Code:

WebhookClient.withUrl("https://discordapp.com/api/webhooks/736596600071127061/[REDACTED]")
     .send("Test");

Error:

ERROR 20760 --- [596600071127061] c.minnced.discord.webhook.WebhookClient  : Sending a webhook message failed with non-OK http response

club.minnced.discord.webhook.exception.HttpException: Request returned failure 400: {"code": 50035, "errors": {"allowed_mentions": {"_errors": [{"code": "MODEL_TYPE_CONVERT", "message": "Only dictionaries may be used in a ModelType"}]}}, "message": "Invalid Form Body"}
	at club.minnced.discord.webhook.WebhookClient.failure(WebhookClient.java:375) [discord-webhooks-0.3.2.jar:na]
	at club.minnced.discord.webhook.WebhookClient.executePair(WebhookClient.java:438) [discord-webhooks-0.3.2.jar:na]
	at club.minnced.discord.webhook.WebhookClient.drainQueue(WebhookClient.java:411) [discord-webhooks-0.3.2.jar:na]
	at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) ~[na:1.8.0_252]
	at java.util.concurrent.FutureTask.run(FutureTask.java:266) ~[na:1.8.0_252]
	at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:180) ~[na:1.8.0_252]
	at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:293) ~[na:1.8.0_252]
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) ~[na:1.8.0_252]
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) ~[na:1.8.0_252]
	at java.lang.Thread.run(Thread.java:748) ~[na:1.8.0_252]

WebhookClient process still running after its closure

I tried to run a simple code to test my webhook. I did succeed at sending my message but the program kept running after it and i also received an SLF4 error. dunno why

code:

var url = "my webhook link";
try (WebhookClient webhook = WebhookClient.withUrl(url)) {
  webhook.send("test").thenRun(() -> {
    System.out.println("message sent");
  });
}

output:

SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.
message sent

i also tried by explicitly closing the webhookclient without using the try(){ } statement but the issue still persist

I'm using intellij and jdk 11.0.10
library version i'm using is 0.5.5-rc

cannot enter string in #setTitle

WebhookEmbed embed = new WebhookEmbedBuilder()
     .setThumbnailUrl(headURL)
     .setColor(0x55e9e9)
     .setTitle("This is a title")
     .setDescription("This is a description")
     .build();

returns the error:

Required type: EmbedTitle
Provided: String

footer and author icon url not working - output shows it as iconUrl instead of icon_url

// add author
embedBuilder.setAuthor(new EmbedAuthor("Author", "https://example.com/png.png", "https://example.com"));

// ... later after creating a message
webhookMessage.getBody().writeTo(buffer);
LOGGER.debug("getBody: " + buffer.readUtf8());

//in the output i see
"author":{"name":"Author","iconUrl":"https://example.com/png.png","url":"https://example.com"}

I believe that's what's sent to discord. it should be "icon_url", and so the icon isn't visible on my embed as a result.
Maybe a json library conflict?

`org.json.JSONException: JSONObject["url"] not found`

[[33m[23:53:34.556][[0;39m [[[35mpool-2-thread-1[[0;39m/[[1;31mERROR[[0;39m] [[36mc.m.d.w.WebhookClient[[0;39m: There was some error while sending a webhook message
org.json.JSONException: JSONObject["url"] not found.
        at org.json.JSONObject.get(JSONObject.java:572)
        at org.json.JSONObject.getString(JSONObject.java:859)
        at club.minnced.discord.webhook.receive.EntityFactory.makeEmbedProvider(EntityFactory.java:176)
        at club.minnced.discord.webhook.receive.EntityFactory.makeEmbed(EntityFactory.java:213)
        at club.minnced.discord.webhook.receive.EntityFactory.convertToList(EntityFactory.java:276)
        at club.minnced.discord.webhook.receive.EntityFactory.makeMessage(EntityFactory.java:257)
        at club.minnced.discord.webhook.WebhookClient.executePair(WebhookClient.java:601)
        at club.minnced.discord.webhook.WebhookClient.drainQueue(WebhookClient.java:561)
        at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515)
        at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
        at java.base/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:304)
        at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1130)
        at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:630)
        at java.base/java.lang.Thread.run(Thread.java:832)

My guess: Seems to be related to webhooks with URLs, all webhooks that I'm sending have Twitch URLs.

More examples

I'm looking for more examples in the README to make usage of this library a bit less research heavy. If anyone wants to open a pull request with examples and usage details I would appreciate it.

I'm also happy to take examples that include other libraries like javacord/d4j/jda as long as the used library is clear through the description.

Question about your queue

I was reading through WebhookClient and I was wondering after you send the first initial 5 webhooks will it wait to send the 6ith?

I made some mock code

WebhookClient client = WebhookClient.withUrl("WEBHOOK_URL");

for(int i = 0; i < 6; i++) {
   client.send("test #" + i);
}

after the 5th one I get

21:06:15.009 [Webhook-RateLimit Thread WebhookID: WEBHOOK_ID] DEBUG club.minnced.discord.webhook.WebhookClient - Backing off queue for 1999

but the 6ith is never sent? after waiting sometime it never sent so I was wondering if its setup to send after the wait or something.

[Feature] Allow disabling thread pool shutdown

It would be nice if you could disable the shutdown of the thread pool.

Because for some bots that send a lot of webhooks in many servers, it might be of interest to provide their own custom thread pool as opposed to constantly creating a new one. The only problem is, with the current implementation, the thread pool is always shut down when the webhook client is shut down.

Might PR with changes, since this is pretty simple & easy to do.

X-RateLimit* headers should be optional

Currently, WebhookClient::update0 requires 3 response headers to prevent a NPE.

X-RateLimit-Remaining
X-RateLimit-Limit
X-RateLimit-Reset-After

This causes NullPointerException when pointing to a mock discord server

Easiest solution is to provide a sensible default using response.header(key,value) instead of response.header(key)

Webhook fails to edit due to missing author field

I currently get this error message when trying to edit any message with a webhook, I've tried this in 2 different servers and get the same result, just in case it's a discord issue and I still believe it might be. I've used the most basic way to edit a message to make sure it's not on my end

java.lang.NumberFormatException: null
	at java.base/java.lang.Integer.parseInt(Integer.java:620)
	at java.base/java.lang.Integer.parseInt(Integer.java:776)
	at club.minnced.discord.webhook.WebhookClient$Bucket.update0(WebhookClient.java:678)
	at club.minnced.discord.webhook.WebhookClient$Bucket.update(WebhookClient.java:692)
	at club.minnced.discord.webhook.WebhookClient.executePair(WebhookClient.java:585)
	at club.minnced.discord.webhook.WebhookClient.drainQueue(WebhookClient.java:560)
	at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515)
	at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
	at java.base/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:304)
	at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
	at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
	at java.base/java.lang.Thread.run(Thread.java:835)
51116 [pool-11-thread-1] ERROR club.minnced.discord.webhook.WebhookClient - There was some error while sending a webhook message
org.json.JSONException: JSONObject["author"] not found.
	at org.json.JSONObject.get(JSONObject.java:566)
	at org.json.JSONObject.getJSONObject(JSONObject.java:778)
	at club.minnced.discord.webhook.receive.EntityFactory.makeMessage(EntityFactory.java:248)
	at club.minnced.discord.webhook.WebhookClient.executePair(WebhookClient.java:600)
	at club.minnced.discord.webhook.WebhookClient.drainQueue(WebhookClient.java:560)
	at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515)
	at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
	at java.base/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:304)
	at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
	at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
	at java.base/java.lang.Thread.run(Thread.java:835)

Using Components

Hello I've just started using this library, but I don't find anyway of adding Components to the webhook message, is this possible?

I need to add a button to the last sent webhook message, patching last one if it was sent before.

Groovy compatibility broken

I use this lib from Groovy and used 0.1.8 before which worked fine.
Now I updated to 0.8.2 and it is not working anymore due to https://issues.apache.org/jira/browse/GROOVY-11116.
Summarized, having an optional dependency in the signature of a method makes the class unloadable if the dependency is absent.
So currently you can only use this lib from Groovy if you have all the optional dependencies present at runtime.
Would be nice if the WebhookClientBuilder could be split into one class per optional dependency to restore Groovy compatibility.

How do I cast to EmbedAuthor?

Why can't WebhookEmbedBuilder().setAuthor() accept a string? I'm looking at the docs and it must be EmbedAuthor type, I've tried casting but I don't understand how to.

[BUG] File upload issue

When I try to upload a file to Discord using a webhook, which includes an embed, I get this error:

Could not pass event AFRenderEvent to ActionFoto v2.7.3
java.lang.NoSuchMethodError: okhttp3.MultipartBody.appendQuotedString(Ljava/lang/StringBuilder;Ljava/lang/String;)V
    at okhttp3.MultipartBody$Part.createFormData(MultipartBody.java:251) ~[?:?]
    at okhttp3.MultipartBody$Builder.addFormDataPart(MultipartBody.java:327) ~[?:?]
    at club.minnced.discord.webhook.send.WebhookMessage.getBody(WebhookMessage.java:328) ~[?:?]
    at club.minnced.discord.webhook.WebhookClient.send(WebhookClient.java:217) ~[?:?]
    at nl.sbdeveloper.actionfoto.listeners.ActionFotoTakeListener.onActionFotoTake(ActionFotoTakeListener.java:68) ~[?:?]
    at com.destroystokyo.paper.event.executor.asm.generated.GeneratedEventExecutor294.execute(Unknown Source) ~[?:?]
    at org.bukkit.plugin.EventExecutor.lambda$create$1(EventExecutor.java:69) ~[patched_1.16.5.jar:git-Paper-457]
    at co.aikar.timings.TimedEventExecutor.execute(TimedEventExecutor.java:76) ~[patched_1.16.5.jar:git-Paper-457]
    at org.bukkit.plugin.RegisteredListener.callEvent(RegisteredListener.java:70) ~[patched_1.16.5.jar:git-Paper-457]
    at org.bukkit.plugin.SimplePluginManager.callEvent(SimplePluginManager.java:607) ~[patched_1.16.5.jar:git-Paper-457]
    at nl.sbdeveloper.actionfoto.api.FrameAPI.lambda$renderAFFrame$2(FrameAPI.java:415) ~[?:?]
    at org.bukkit.craftbukkit.v1_16_R3.scheduler.CraftTask.run(CraftTask.java:99) ~[patched_1.16.5.jar:git-Paper-457]
    at org.bukkit.craftbukkit.v1_16_R3.scheduler.CraftAsyncTask.run(CraftAsyncTask.java:54) ~[patched_1.16.5.jar:git-Paper-457]
    at com.destroystokyo.paper.ServerSchedulerReportingWrapper.run(ServerSchedulerReportingWrapper.java:22) ~[patched_1.16.5.jar:git-Paper-457]
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) [?:1.8.0_201]
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) [?:1.8.0_201]
    at java.lang.Thread.run(Thread.java:748) [?:1.8.0_201]

I'm on version 0.5.5-rc of Discord-Webhooks. This is my code:

// These values come from a config file or API. I've put them there to show the reference.
String nameOrID = ...;
RenderedImage img = ...;

String title = ...;
String description = ...;
String copy = ...;
String copyimg = ...;
Integer color = ...;

WebhookEmbed embed = new WebhookEmbedBuilder()
        .setTitle(new WebhookEmbed.EmbedTitle(title, ""))
        .setDescription(description)
        .setFooter(new WebhookEmbed.EmbedFooter(copy, copyimg))
        .setColor(color)
        .build();

WebhookMessage message = new WebhookMessageBuilder()
        .addEmbeds(embed)
        .addFile("af-picture-" + nameOrID + ".png", RenderAPI.imgToByteArray(img, "png"))
        .build();

Main.getWebhookClient().send(message);

RenderAPI.imgToByteArray returns the byte[] of my image.

Am I doing anything wrong, or is this an issue in Discord-webhooks?

Message is not sent

Hey!
I use the following code, but the message isn't being sent
No errors.

package com.nelmin.friendfinder.api

import club.minnced.discord.webhook.WebhookClient
import club.minnced.discord.webhook.send.WebhookMessageBuilder
import com.nelmin.friendfinder.Secrets

class DiscordWebhook(content: String) {

    init {
        val webhook: WebhookClient = WebhookClient.withUrl(Secrets.DISCORD_WEBHOOK_URL)
        val message = WebhookMessageBuilder()

        message.setUsername("FriendFinder App Errors")
        message.setContent(content)

        webhook.send(message.build())
    }
}

Support for component types such as buttons and select menus

Since this library can be used to handle interaction webhooks, it should also support message components. This would need to be added to WebhookMessage and WebhookMessageBuilder. For more details on components, read up here: Message Components.

A possible implementation could look like this:

ActionRow buttons = ActionRow.of(
  Button.primary("custom_id", "Label")
);

WebhookMessage message = new WebookMessageBuilder()
  .addComponents(buttons)
  .build();

ActionRow would be an implementation of LayoutComponent and Button would be an ActionComponent.

interface Component extends JSONString {
  int getType();
}

interface LayoutComponent extends Component {
  List<ActionComponent> getComponents();
}

interface ActionComponent extends Component {
  String getCustomId();
}

Since this library only handles incoming webhooks, events and similar cannot be supported. I'm only looking for the support of sending message components in webhook messages.

Edit or remove some attachments of already sent webhooks.

To add an attachment of a webhook that has already been sent, I can simply use client.edit.
But according to https://discord.com/developers/docs/resources/channel#attachment-object I need to provide a header named attachments to modify or remove existing attachments.
I provided the following headers to leave the attachment with ID '0002' in the webhook '0001' and remove all other attachments, and it worked correctly.

curl -X PATCH \
  -H "Content-Type: application/json" \
  -d '{
    "attachments": [
      {
        "id": "0002"
      }
    ]
  }' \
  'https://discord.com/api/v10/webhooks/<kamilake>/messages/0001'

The code below is my Java implementation.

public class Main {
    public static void main(String[] args) throws Throwable {
        String url = "https://discord.com/api/v10/webhooks/1234/messages/0001";
        String attachmentId = "0002";

        OkHttpClient client = new OkHttpClient();
        String json = "{\"attachments\": [{\"id\": \"" + attachmentId + "\"}]}";
        RequestBody body = RequestBody.create(json, MediaType.get("application/json; charset=utf-8"));
        Request request = new Request.Builder().url(url).patch(body).build();
        Response response = client.newCall(request).execute()
        System.out.println(response.body().string());
    }
}

I couldn't find an API that does the above operation, so I made it myself. Is that implemented in discord-webhooks?

Let me know if it exists! I'm going to fix my bot.
If not.. Shall I make one?

[Question] How does the lib handle rate limits

I'm curious to know how exactly this library handles rate limits. By that I mean the following questions:

  • How does it set/obtain rate limit information. Is it a hard-coded value it gets from somewhere in the lib itself? Is it retrieved from something like a response header from discord?
  • How exactly does it handle new requests when the current rate limit is used up? Simply queue them for future sending? Print warns?

I'm asking this because a software I use (A plugin) uses this library. And whenever there is a large number of text to be send through a webhook is the WebhookClient encountering 429 errors and prints those in the console:

errors

According to the dev, and from my own checks, is the library used as it should. A single WebhookClient instance is created and used for a single webhook without recreating it during the entire use.

What could be possible causes for this random issue?

On 0.4.1 WebhookClient cannot be used as a bean in Spring Boot

From the 0.4.1 update on, the WebhookClient cannot be used as a bean anymore in a Spring Boot application because it uses parameters of types of optional dependencies (other discord api libs) that are usually not included in the runtime classpath, so some Spring bean introspection fails.

I can write myself a wrapper fine, so it can be worked around easily, just thought you might want to know.

Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'botStatusWebhookClient' defined in class path resource [space/npstr/aki/config/WebhookConfiguration.class]: Post-processing of merged bean definition failed; nested exception is java.lang.IllegalStateException: Failed to introspect Class [club.minnced.discord.webhook.WebhookClient] from ClassLoader [org.springframework.boot.loader.LaunchedURLClassLoader@4f2fe9c1]
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:571) ~[spring-beans-5.2.8.RELEASE.jar!/:5.2.8.RELEASE]
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:516) ~[spring-beans-5.2.8.RELEASE.jar!/:5.2.8.RELEASE]
	at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:324) ~[spring-beans-5.2.8.RELEASE.jar!/:5.2.8.RELEASE]
	at org.springframework.beans.factory.support.AbstractBeanFactory$$Lambda$249/000000001102D280.getObject(Unknown Source) ~[na:na]
	at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:226) ~[spring-beans-5.2.8.RELEASE.jar!/:5.2.8.RELEASE]
	at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:322) ~[spring-beans-5.2.8.RELEASE.jar!/:5.2.8.RELEASE]
	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202) ~[spring-beans-5.2.8.RELEASE.jar!/:5.2.8.RELEASE]
	at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:276) ~[spring-beans-5.2.8.RELEASE.jar!/:5.2.8.RELEASE]
	at org.springframework.beans.factory.support.DefaultListableBeanFactory$2.resolveCandidate(DefaultListableBeanFactory.java:1765) ~[spring-beans-5.2.8.RELEASE.jar!/:5.2.8.RELEASE]
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1307) ~[spring-beans-5.2.8.RELEASE.jar!/:5.2.8.RELEASE]
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.createOptionalDependency(DefaultListableBeanFactory.java:1768) ~[spring-beans-5.2.8.RELEASE.jar!/:5.2.8.RELEASE]
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1214) ~[spring-beans-5.2.8.RELEASE.jar!/:5.2.8.RELEASE]
	at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:884) ~[spring-beans-5.2.8.RELEASE.jar!/:5.2.8.RELEASE]
	at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:788) ~[spring-beans-5.2.8.RELEASE.jar!/:5.2.8.RELEASE]
	... 42 common frames omitted
Caused by: java.lang.IllegalStateException: Failed to introspect Class [club.minnced.discord.webhook.WebhookClient] from ClassLoader [org.springframework.boot.loader.LaunchedURLClassLoader@4f2fe9c1]
	at org.springframework.util.ReflectionUtils.getDeclaredMethods(ReflectionUtils.java:481) ~[spring-core-5.2.8.RELEASE.jar!/:5.2.8.RELEASE]
	at org.springframework.util.ReflectionUtils.doWithLocalMethods(ReflectionUtils.java:321) ~[spring-core-5.2.8.RELEASE.jar!/:5.2.8.RELEASE]
	at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor.buildLifecycleMetadata(InitDestroyAnnotationBeanPostProcessor.java:232) ~[spring-beans-5.2.8.RELEASE.jar!/:5.2.8.RELEASE]
	at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor.findLifecycleMetadata(InitDestroyAnnotationBeanPostProcessor.java:210) ~[spring-beans-5.2.8.RELEASE.jar!/:5.2.8.RELEASE]
	at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor.postProcessMergedBeanDefinition(InitDestroyAnnotationBeanPostProcessor.java:149) ~[spring-beans-5.2.8.RELEASE.jar!/:5.2.8.RELEASE]
	at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.postProcessMergedBeanDefinition(CommonAnnotationBeanPostProcessor.java:294) ~[spring-context-5.2.8.RELEASE.jar!/:5.2.8.RELEASE]
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyMergedBeanDefinitionPostProcessors(AbstractAutowireCapableBeanFactory.java:1093) ~[spring-beans-5.2.8.RELEASE.jar!/:5.2.8.RELEASE]
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:568) ~[spring-beans-5.2.8.RELEASE.jar!/:5.2.8.RELEASE]
	... 55 common frames omitted
Caused by: java.lang.NoClassDefFoundError: discord4j.core.object.entity.Webhook
	at java.base/java.lang.Class.getDeclaredMethodsImpl(Native Method) ~[na:na]
	at java.base/java.lang.Class.getDeclaredMethods(Class.java:1129) ~[na:na]
	at org.springframework.util.ReflectionUtils.getDeclaredMethods(ReflectionUtils.java:463) ~[spring-core-5.2.8.RELEASE.jar!/:5.2.8.RELEASE]
	... 62 common frames omitted
Caused by: java.lang.ClassNotFoundException: discord4j.core.object.entity.Webhook
	at java.base/java.net.URLClassLoader.findClass(URLClassLoader.java:605) ~[na:na]
	at java.base/java.lang.ClassLoader.loadClassHelper(ClassLoader.java:1180) ~[na:na]
	at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:1095) ~[na:na]
	at org.springframework.boot.loader.LaunchedURLClassLoader.loadClass(LaunchedURLClassLoader.java:151) ~[aki.jar:na]
	at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:1078) ~[na:na]
	... 65 common frames omitted

0.8.2 causing kotlin to be shaded

0.8.2 causes kotlin to be shaded compared to 0.8.0 when I have this plugin as a dependency. Is this intentional? I don't see any reason why kotlin must be shaded.

No virtual method put(Ljava/lang/String;Ljava/util/Collection;)Lorg/json/JSONObject

Hello. I get an error when linking the library:

java.lang.NoSuchMethodError: No virtual method put(Ljava/lang/String;Ljava/util/Collection;)Lorg/json/JSONObject; in class Lorg/json/JSONObject; or its super classes (declaration of 'org.json.JSONObject' appears in /apex/com.android.runtime/javalib/core-libart.jar)
        at club.minnced.discord.webhook.send.WebhookEmbed.toJSONString(WebhookEmbed.java:215)
        at club.minnced.discord.webhook.send.WebhookEmbed.toString(WebhookEmbed.java:190)
        at org.json.JSONStringer.value(JSONStringer.java:261)
        at org.json.JSONArray.writeTo(JSONArray.java:616)
        at org.json.JSONStringer.value(JSONStringer.java:242)
        at org.json.JSONObject.writeTo(JSONObject.java:733)
        at org.json.JSONObject.toString(JSONObject.java:701)
        at club.minnced.discord.webhook.send.WebhookMessage.getBody(WebhookMessage.java:354)
        at club.minnced.discord.webhook.WebhookClient.send(WebhookClient.java:304)

Thread limit reached.

It seems like this libary creates for each Webhook a thread:

return Executors.newSingleThreadScheduledExecutor(factory == null ? new DefaultWebhookThreadFactory(id, isDaemon) : factory);

This causes the thread limit to be reached when e.g. several webhooks are sent per minute.
"java.lang.OutOfMemoryError: unable to create native thread: possibly out of memory or process/resource limits reached"

I profiled it with YourKit, the threads will not be shutdowned.

Solution:
Shutdown the thread or use a Pool of threads. Or make possible to use own thread pool.

Issues with accents

Hi !

Here in france we use characters likes "é", "à", "ù"

And it doesn't works with DiscordWebhooks, idk if its me bc I use webhooks with an Habbo Emulator, is it this?

Thanks

Trying to send a file along with a message

This is my bit of code

long id = 779418282280091669L;
WebhookClient client = WebhookClient.withId(id, "[REDACTED]");
client.send("Hello, lmao test");
WebhookEmbed embed = new WebhookEmbedBuilder()
    .setColor(0x00b3ff)
    .setDescription("test")
    .build();
client.send(embed);
System.out.println("Message Sent!");
client.send(new File("/storage/emulated/0/Downloads/file.txt"));
System.out.println("File sent!");
client.close();

Its using the Android sdk lvl 30
The message sends fine, just not the embed neither the file

image

Ive tried other library's as well, but they dont work either. This library is the nicest one yet so here i am posing my issue.
Im quite a begginer in java so please dont roast me, thank you 😀

Retrying after 429 when sending a file results in an empty file

When I am hitting the Rate limit and receiving a 429 while sending a message with an attachment, it retries after it but then the file upload breaks, and it results in a 0 byte file in the discord client.

I tested some things and couldn't get it working when hitting the limit although it could be also an issue on discord's side.

Would be glad if somebody could check this behavior too.

UnsupportedOperationException when sending DataMessages

When trying to send JDA messages that have been constructed using the MessageBuilder, the Webhook client fails with an UnsupportedOperationException.

The main issue seems to be caused by the isEphemeral() method, which is called regardless of the message type. I suggest allowing this attribute only for received messages.

Here's the corresponding stack trace:

java.lang.UnsupportedOperationException: This operation is not supported for Messages that were created by a MessageBuilder!
	at net.dv8tion.jda.internal.entities.DataMessage.unsupported(DataMessage.java:131) ~[JDA-4.4.0_350.jar:4.4.0_350]
	at net.dv8tion.jda.internal.entities.AbstractMessage.isEphemeral(AbstractMessage.java:610) ~[JDA-4.4.0_350.jar:4.4.0_350]
	at club.minnced.discord.webhook.send.WebhookMessageBuilder.fromJDA(WebhookMessageBuilder.java:436) ~[discord-webhooks-0.7.4.jar:?]
	at club.minnced.discord.webhook.external.JDAWebhookClient.send(JDAWebhookClient.java:119) ~[discord-webhooks-0.7.4.jar:?]

Failed to parse webhook URL

I have:

private val shardHook = WebhookClientBuilder("https://canary.discord.com/api/webhooks/{MY_CHANNEL_ID}/{MY_WEBHOOK_TOKEN}").build()

But it fails to parse the webhook url I copied it from discord in channel settings, I've tried the webhook id and token, but all of three of don't work

Error:

Caused by: java.lang.IllegalArgumentException: Failed to parse webhook URL
        at club.minnced.discord.webhook.WebhookClientBuilder.<init>(WebhookClientBuilder.java:84)
        at bot.hibikibot.utils.WebhookManager.<clinit>(WebhookManager.kt:13)
        ... 26 common frames omitted

Process not terminating correctly

Hello,

when using a WebhookClient and sending a message the process does not finish even when calling client.close().
My current code example is:

public class Main {

    public static void main(String[] args) {

	String url = "discord webhook link";

	System.out.println("Before");

        try (WebhookClient client = WebhookClient.withUrl(url)) {
            client.send("Hello World");
        }

        System.out.println("a");

    }
}

The output is

Before
After

but no termination of the program even though it is finished and the WebhookClient should be closed.
When calling a client method that is not send(...), for example isShutdown(), the process terminates as expected with:

Process finished with exit code 0

Other information:
Java 8
Discord-Webhook 0.7.2

Thanks in advance,
Qumo

CloudFlare Ratelimits

I was just wondering if you handle cloudflare bans, because yesterday I hit a cloudflare ban and it seemed the library kept accumulating requests and continuosly tried to send them instead of falling back and waiting for the ban to end which meant I was just guaranteed to get banned for the next hour especially with the amount of requests it was accumulating. So not sure if this is due to the library not handling cloudflare ratelimits or if it has something to do with something else.
image

Support for sending messages with timeouts

The following code is being used to send with a 30 second timeout.

    void sendMessagesWithTimeout(Notification change, Optional<DiscordGuild> guild, List<DiscordGuild> helperGuilds) {
        //message created by some method
        WebhookMessage message = createRemoteHelpMessage(change);
        log.info("Sending {} discord raid request for {} to {} servers", language, change.getId(), helperGuilds.size());
        for (DiscordGuild helperGuild: helperGuilds) {
            try {
                getClient(helperGuild.getId()).send(message, helperGuild).orTimeout(30000, TimeUnit.MILLISECONDS).whenCompleteAsync((result,e) -> {
                    if (e != null) {
                        if (e instanceof TimeoutException) {
                            log.warn("Time out after {}ms sending {} to {}", globalNotificationTimeoutMs ,change.getRaidPartyId(), helperGuild);
                        }
                    }
                });
            } catch (ExecutionException | RuntimeException e) {
                log.error("Not retrying " + change.getId() + ": Could not send discord raid request for " + helperGuild, e);
            }
        }
    }

Unfortunately, this does not currently cancel the request

The following change is required to support timeouts

    private boolean executePair(@Async.Execute Request req) {
        if (req.future.isCancelled()) {

should be

    private boolean executePair(@Async.Execute Request req) {
        if (req.future.isCompletedExceptionally()) {

as TimeoutException is not a CancellationException. Per javadocs, isCompletedExceptionally is a superset of isCancelled.

Embed Issue

it seems that Icon of an EmbedAuthor and EmbedFooter doesn't work properly.
image

I tried many types of image of URL, it still doesn't work.
image

Logging and exception improvements

Currently logging is difficult to configure as there are multiple classifications of errors being passed at different times (asynchronously). Exceptions also are also generic, and there is no clear way to handle fairly common use cases such as invalid webhook urls and deleted webhooks.

Current logging:

  1. LOG.debug("Backing off queue for {}", delay);
  2. LOG.error("Sending a webhook message failed with non-OK http response", exception);
  3. LOG.error("Encountered 429, retrying after {}", delay);
  4. LOG.debug("Failed to update buckets due to unsuccessful response with code: {} and body: \n{}", response.code(), new IOUtil.Lazy(() -> new String(IOUtil.readAllBytes(IOUtil.getBody(response)))));
  5. LOG.error("Could not read http response", ex);

My thoughts on each of the log lines:

  1. This is a rate limit error and should mention that you are being rate limited at the bucket level. Suggest WARN level
  2. This should be split up into multiple categories of exception for example Sending a webhook message failed with non-OK http response club.minnced.discord.webhook.exception.HttpException: Request returned failure 404: {"message": "Unknown Webhook", "code": 10015} should be warn level and throw an UnknownWebhookException. Other common errors such as 400 or 500 should also have their own exception classes if you know what causes them. 400 and 500 I would suggest error level.
  3. This is also a rate limit error and should say so explicitly. Suggest warn level
  4. This seems a duplicate of #2
  5. JSONException would seem to be an error in your own client library. IOException I think is fine to throw as is.

Even with these changes, the errors will be intermingled and difficult to separate what to log. For example, most of these errors are actually returned in the Future and should be handled and logged by the clients so you would want to turn these errors off. The rate limit warnings on the other hand are never sent to the client so you need to keep the logs on. Highly suggest refactoring the code into multiple classes with different loggers. Alternatively, make different loggers for each of the classification of errors so that they can be configured properly.

Arguably, client libraries should never log errors and should simply provide callbacks for the client to perform the logging themselves. This may not be practical for the target audience for this library but I did want to put that option out there.

Overall, I love this library and am willing to make these changes in a PR if you wish but at high volume it becomes excessively noisy.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.