Skip to content

Instantly share code, notes, and snippets.

@Jaimss
Forked from k3kdude/DiscordWebhook.java
Last active June 13, 2023 14:55
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Jaimss/42fed5695f5bfb6a3282abe8bfc7c229 to your computer and use it in GitHub Desktop.
Save Jaimss/42fed5695f5bfb6a3282abe8bfc7c229 to your computer and use it in GitHub Desktop.
Java DiscordWebhook class to easily execute Discord Webhooks. Scroll down for Kotlin
import java.awt.Color
import java.io.IOException
import java.lang.reflect.Array
import java.net.URL
import java.util.*
import javax.net.ssl.HttpsURLConnection
import kotlin.collections.HashMap
import kotlin.collections.set
/**
* Class used to execute Discord Webhooks with low effort
*
* Kotlinified version of https://gist.github.com/k3kdude/fba6f6b37594eae3d6f9475330733bdb
*/
@Suppress("unused")
class DiscordWebhook(private val url: String) {
private var content: String? = null
private var username: String? = null
private var avatarUrl: String? = null
private var tts = false
private val embeds: MutableList<EmbedObject> = ArrayList()
fun setContent(content: String?) = apply { this.content = content }
fun setUsername(username: String?) = apply { this.username = username }
fun setAvatarUrl(avatarUrl: String?) = apply { this.avatarUrl = avatarUrl }
fun setTts(tts: Boolean) = apply { this.tts = tts }
fun addEmbed(embed: EmbedObject) = apply { embeds.add(embed) }
@Throws(IOException::class)
fun execute() {
if (content == null && embeds.isEmpty()) {
throw IllegalArgumentException("Set content or add at least one EmbedObject")
}
val json = JSONObject()
json.put("content", content)
json.put("username", username)
json.put("avatar_url", avatarUrl)
json.put("tts", tts)
if (embeds.isNotEmpty()) {
val embedObjects: MutableList<JSONObject> = ArrayList()
for (embed: EmbedObject in embeds) {
val jsonEmbed = JSONObject()
jsonEmbed.put("title", embed.title)
jsonEmbed.put("description", embed.description)
jsonEmbed.put("url", embed.url)
val color = embed.color
if (color != null) {
var rgb = color.red
rgb = (rgb shl 8) + color.green
rgb = (rgb shl 8) + color.blue
jsonEmbed.put("color", rgb)
}
val footer: Footer? = embed.footer
val image = embed.image
val thumbnail: Thumbnail? = embed.thumbnail
val author: Author? = embed.author
val fields = embed.fields
if (footer != null) {
val jsonFooter = JSONObject()
jsonFooter.put("text", footer.text)
jsonFooter.put("icon_url", footer.iconUrl)
jsonEmbed.put("footer", jsonFooter)
}
if (image != null) {
val jsonImage = JSONObject()
jsonImage.put("url", image.url)
jsonEmbed.put("image", jsonImage)
}
if (thumbnail != null) {
val jsonThumbnail = JSONObject()
jsonThumbnail.put("url", thumbnail.url)
jsonEmbed.put("thumbnail", jsonThumbnail)
}
if (author != null) {
val jsonAuthor = JSONObject()
jsonAuthor.put("name", author.name)
jsonAuthor.put("url", author.url)
jsonAuthor.put("icon_url", author.iconUrl)
jsonEmbed.put("author", jsonAuthor)
}
val jsonFields: MutableList<JSONObject> = ArrayList()
for (field in fields) {
val jsonField = JSONObject()
jsonField.put("name", field.name)
jsonField.put("value", field.value)
jsonField.put("inline", field.isInline)
jsonFields.add(jsonField)
}
jsonEmbed.put("fields", jsonFields.toTypedArray())
embedObjects.add(jsonEmbed)
}
json.put("embeds", embedObjects.toTypedArray())
}
val url = URL(url)
val connection = url.openConnection() as HttpsURLConnection
connection.addRequestProperty("Content-Type", "application/json")
connection.addRequestProperty("User-Agent", "Java-DiscordWebhook-BY-Gelox_")
connection.doOutput = true
connection.requestMethod = "POST"
val stream = connection.outputStream
stream.write(json.toString().toByteArray())
stream.flush()
stream.close()
connection.inputStream.close() //I'm not sure why but it doesn't work without getting the InputStream
connection.disconnect()
}
}
@Suppress("unused")
class EmbedObject {
var title: String? = null
var description: String? = null
var url: String? = null
var color: Color? = null
var footer: Footer? = null
var thumbnail: Thumbnail? = null
var image: Image? = null
var author: Author? = null
val fields: MutableList<Field> = ArrayList()
fun setTitle(title: String?): EmbedObject {
this.title = title
return this
}
fun setDescription(description: String?): EmbedObject {
this.description = description
return this
}
fun setUrl(url: String): EmbedObject {
this.url = url
return this
}
fun setColor(color: String): EmbedObject {
fun String.toColor(): Color? {
if (!this.matches("[#][0-9a-fA-F]{6}".toRegex())) return null
val digits: String = this.substring(1, this.length.coerceAtMost(7))
val hxstr = "0x$digits"
return Color.decode(hxstr)
}
this.color = color.toColor()
return this
}
fun setColor(color: Color?): EmbedObject {
this.color = color
return this
}
fun setFooter(text: String, icon: String): EmbedObject {
footer = Footer(text, icon)
return this
}
fun setThumbnail(url: String): EmbedObject {
thumbnail = Thumbnail(url)
return this
}
fun setImage(url: String): EmbedObject {
image = Image(url)
return this
}
fun setAuthor(name: String, url: String, icon: String): EmbedObject {
author = Author(name, url, icon)
return this
}
fun addField(name: String, value: String, inline: Boolean): EmbedObject {
fields.add(Field(name, value, inline))
return this
}
}
data class Footer(val text: String, val iconUrl: String)
data class Thumbnail(val url: String)
data class Image(val url: String)
data class Author(
val name: String,
val url: String,
val iconUrl: String
)
data class Field(
val name: String,
val value: String,
val isInline: Boolean
)
class JSONObject {
private val map = HashMap<String, Any>()
fun put(key: String, value: Any?) {
if (value != null) {
map[key] = value
}
}
override fun toString(): String {
val builder = StringBuilder()
val entrySet: Set<Map.Entry<String, Any>> = map.entries
builder.append("{")
var i = 0
entrySet.forEach { (key, value) ->
builder.append(quote(key)).append(":")
when (value) {
is String -> builder.append(quote(value))
is Int -> builder.append(value)
is Boolean -> builder.append(value)
is JSONObject -> builder.append(value.toString())
javaClass.isArray -> {
builder.append("[")
val len = Array.getLength(value)
for (j in 0 until len) {
builder.append(Array.get(value, j).toString())
.append(if (j != len - 1) "," else "")
}
builder.append("]")
}
}
builder.append(if (++i == entrySet.size) "}" else ",")
}
return builder.toString()
}
private fun quote(string: String): String {
return "\"$string\""
}
}
import javax.net.ssl.HttpsURLConnection;
import java.awt.Color;
import java.io.IOException;
import java.io.OutputStream;
import java.lang.reflect.Array;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* Class used to execute Discord Webhooks with low effort
*/
public class DiscordWebhook {
private final String url;
private String content;
private String username;
private String avatarUrl;
private boolean tts;
private List<EmbedObject> embeds = new ArrayList<>();
/**
* Constructs a new DiscordWebhook instance
*
* @param url The webhook URL obtained in Discord
*/
public DiscordWebhook(String url) {
this.url = url;
}
public void setContent(String content) {
this.content = content;
}
public void setUsername(String username) {
this.username = username;
}
public void setAvatarUrl(String avatarUrl) {
this.avatarUrl = avatarUrl;
}
public void setTts(boolean tts) {
this.tts = tts;
}
public void addEmbed(EmbedObject embed) {
this.embeds.add(embed);
}
public void execute() throws IOException {
if (this.content == null && this.embeds.isEmpty()) {
throw new IllegalArgumentException("Set content or add at least one EmbedObject");
}
JSONObject json = new JSONObject();
json.put("content", this.content);
json.put("username", this.username);
json.put("avatar_url", this.avatarUrl);
json.put("tts", this.tts);
if (!this.embeds.isEmpty()) {
List<JSONObject> embedObjects = new ArrayList<>();
for (EmbedObject embed : this.embeds) {
JSONObject jsonEmbed = new JSONObject();
jsonEmbed.put("title", embed.getTitle());
jsonEmbed.put("description", embed.getDescription());
jsonEmbed.put("url", embed.getUrl());
if (embed.getColor() != null) {
Color color = embed.getColor();
int rgb = color.getRed();
rgb = (rgb << 8) + color.getGreen();
rgb = (rgb << 8) + color.getBlue();
jsonEmbed.put("color", rgb);
}
EmbedObject.Footer footer = embed.getFooter();
EmbedObject.Image image = embed.getImage();
EmbedObject.Thumbnail thumbnail = embed.getThumbnail();
EmbedObject.Author author = embed.getAuthor();
List<EmbedObject.Field> fields = embed.getFields();
if (footer != null) {
JSONObject jsonFooter = new JSONObject();
jsonFooter.put("text", footer.getText());
jsonFooter.put("icon_url", footer.getIconUrl());
jsonEmbed.put("footer", jsonFooter);
}
if (image != null) {
JSONObject jsonImage = new JSONObject();
jsonImage.put("url", image.getUrl());
jsonEmbed.put("image", jsonImage);
}
if (thumbnail != null) {
JSONObject jsonThumbnail = new JSONObject();
jsonThumbnail.put("url", thumbnail.getUrl());
jsonEmbed.put("thumbnail", jsonThumbnail);
}
if (author != null) {
JSONObject jsonAuthor = new JSONObject();
jsonAuthor.put("name", author.getName());
jsonAuthor.put("url", author.getUrl());
jsonAuthor.put("icon_url", author.getIconUrl());
jsonEmbed.put("author", jsonAuthor);
}
List<JSONObject> jsonFields = new ArrayList<>();
for (EmbedObject.Field field : fields) {
JSONObject jsonField = new JSONObject();
jsonField.put("name", field.getName());
jsonField.put("value", field.getValue());
jsonField.put("inline", field.isInline());
jsonFields.add(jsonField);
}
jsonEmbed.put("fields", jsonFields.toArray());
embedObjects.add(jsonEmbed);
}
json.put("embeds", embedObjects.toArray());
}
URL url = new URL(this.url);
HttpsURLConnection connection = (HttpsURLConnection) url.openConnection();
connection.addRequestProperty("Content-Type", "application/json");
connection.addRequestProperty("User-Agent", "Java-DiscordWebhook-BY-Gelox_");
connection.setDoOutput(true);
connection.setRequestMethod("POST");
OutputStream stream = connection.getOutputStream();
stream.write(json.toString().getBytes());
stream.flush();
stream.close();
connection.getInputStream().close(); //I'm not sure why but it doesn't work without getting the InputStream
connection.disconnect();
}
public static class EmbedObject {
private String title;
private String description;
private String url;
private Color color;
private Footer footer;
private Thumbnail thumbnail;
private Image image;
private Author author;
private List<Field> fields = new ArrayList<>();
public String getTitle() {
return title;
}
public String getDescription() {
return description;
}
public String getUrl() {
return url;
}
public Color getColor() {
return color;
}
public Footer getFooter() {
return footer;
}
public Thumbnail getThumbnail() {
return thumbnail;
}
public Image getImage() {
return image;
}
public Author getAuthor() {
return author;
}
public List<Field> getFields() {
return fields;
}
public EmbedObject setTitle(String title) {
this.title = title;
return this;
}
public EmbedObject setDescription(String description) {
this.description = description;
return this;
}
public EmbedObject setUrl(String url) {
this.url = url;
return this;
}
public EmbedObject setColor(Color color) {
this.color = color;
return this;
}
public EmbedObject setFooter(String text, String icon) {
this.footer = new Footer(text, icon);
return this;
}
public EmbedObject setThumbnail(String url) {
this.thumbnail = new Thumbnail(url);
return this;
}
public EmbedObject setImage(String url) {
this.image = new Image(url);
return this;
}
public EmbedObject setAuthor(String name, String url, String icon) {
this.author = new Author(name, url, icon);
return this;
}
public EmbedObject addField(String name, String value, boolean inline) {
this.fields.add(new Field(name, value, inline));
return this;
}
private class Footer {
private String text;
private String iconUrl;
private Footer(String text, String iconUrl) {
this.text = text;
this.iconUrl = iconUrl;
}
private String getText() {
return text;
}
private String getIconUrl() {
return iconUrl;
}
}
private class Thumbnail {
private String url;
private Thumbnail(String url) {
this.url = url;
}
private String getUrl() {
return url;
}
}
private class Image {
private String url;
private Image(String url) {
this.url = url;
}
private String getUrl() {
return url;
}
}
private class Author {
private String name;
private String url;
private String iconUrl;
private Author(String name, String url, String iconUrl) {
this.name = name;
this.url = url;
this.iconUrl = iconUrl;
}
private String getName() {
return name;
}
private String getUrl() {
return url;
}
private String getIconUrl() {
return iconUrl;
}
}
private class Field {
private String name;
private String value;
private boolean inline;
private Field(String name, String value, boolean inline) {
this.name = name;
this.value = value;
this.inline = inline;
}
private String getName() {
return name;
}
private String getValue() {
return value;
}
private boolean isInline() {
return inline;
}
}
}
private class JSONObject {
private final HashMap<String, Object> map = new HashMap<>();
void put(String key, Object value) {
if (value != null) {
map.put(key, value);
}
}
@Override
public String toString() {
StringBuilder builder = new StringBuilder();
Set<Map.Entry<String, Object>> entrySet = map.entrySet();
builder.append("{");
int i = 0;
for (Map.Entry<String, Object> entry : entrySet) {
Object val = entry.getValue();
builder.append(quote(entry.getKey())).append(":");
if (val instanceof String) {
builder.append(quote(String.valueOf(val)));
} else if (val instanceof Integer) {
builder.append(Integer.valueOf(String.valueOf(val)));
} else if (val instanceof Boolean) {
builder.append(val);
} else if (val instanceof JSONObject) {
builder.append(val.toString());
} else if (val.getClass().isArray()) {
builder.append("[");
int len = Array.getLength(val);
for (int j = 0; j < len; j++) {
builder.append(Array.get(val, j).toString()).append(j != len - 1 ? "," : "");
}
builder.append("]");
}
builder.append(++i == entrySet.size() ? "}" : ",");
}
return builder.toString();
}
private String quote(String string) {
return "\"" + string + "\"";
}
}
}
@cancel-cloud
Copy link

Is there an example or and explanation somewhere? @Jaimss

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment