send responses based on Accept header, add pages for error cases

This commit is contained in:
2025-07-18 21:29:50 +02:00
parent 6b794c9f7c
commit 8ac518e4cb
4 changed files with 301 additions and 9 deletions
@@ -8,12 +8,34 @@ import me.youhavetrouble.inviter.discord.GuildSettings;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.util.regex.Pattern; import java.util.regex.Pattern;
public class GetDiscordInviteByGuildId implements EndpointHandler { public class GetDiscordInviteByGuildId implements EndpointHandler {
private final Pattern pathPattern = Pattern.compile("^/invite/\\d{10,18}$"); private final Pattern pathPattern = Pattern.compile("^/invite/\\d{10,18}$");
private final String invitesDisabledTemplate, botNotInGuildTemplate;
public GetDiscordInviteByGuildId() {
String invitesDisabledTemplate = null;
try (InputStream resource = this.getClass().getResourceAsStream("/template/invites-paused.html")) {
invitesDisabledTemplate = new String(resource.readAllBytes());
} catch (IOException | NullPointerException e) {
Main.LOGGER.warn("Failed to load template for invites disabled page", e);
}
this.invitesDisabledTemplate = invitesDisabledTemplate;
String botNotInGuildTemplate = null;
try (InputStream resource = this.getClass().getResourceAsStream("/template/guild-not-supported.html")) {
botNotInGuildTemplate = new String(resource.readAllBytes());
} catch (IOException | NullPointerException e) {
Main.LOGGER.warn("Failed to load template for guild not supported page", e);
}
this.botNotInGuildTemplate = botNotInGuildTemplate;
}
@NotNull @NotNull
@Override @Override
public Pattern pathPattern() { public Pattern pathPattern() {
@@ -39,17 +61,18 @@ public class GetDiscordInviteByGuildId implements EndpointHandler {
return; return;
} }
DiscordInviteManager inviteManager = Main.getDiscordInviteMenager();
GuildSettings settings = Main.getStorage().getGuildSettings(guildIdLong); GuildSettings settings = Main.getStorage().getGuildSettings(guildIdLong);
DiscordInvite invite = inviteManager.getInvite(guildIdLong);
if (invite == null) { if (!settings.invitesEnabled()) {
exchange.sendResponseHeaders(404, -1); // Not Found sendInvitesPausedTemplate(exchange);
return; return;
} }
if (!settings.invitesEnabled()) { DiscordInviteManager inviteManager = Main.getDiscordInviteMenager();
exchange.sendResponseHeaders(401, -1); // Not Found DiscordInvite invite = inviteManager.getInvite(guildIdLong);
if (invite == null) {
sendBotNotInGuildTemplate(exchange);
return; return;
} }
@@ -72,10 +95,62 @@ public class GetDiscordInviteByGuildId implements EndpointHandler {
exchange.sendResponseHeaders(307, -1); exchange.sendResponseHeaders(307, -1);
} }
} }
} }
private void sendInvitesPausedTemplate(HttpExchange exchange) throws IOException {
String message = "Guild you were invited to currently has invites disabled. Try again later.";
switch (exchange.getRequestHeaders().getFirst("Accept")) {
case "text/plain" -> {
exchange.getResponseHeaders().set("Content-Type", "text/plain; charset=UTF-8");
exchange.sendResponseHeaders(401, message.getBytes(StandardCharsets.UTF_8).length);
exchange.getResponseBody().write(message.getBytes(StandardCharsets.UTF_8));
}
case "application/json" -> {
exchange.getResponseHeaders().set("Content-Type", "application/json; charset=UTF-8");
String jsonResponse = "{\"error\": \"%s\"}".formatted(message);
exchange.sendResponseHeaders(401, jsonResponse.length());
exchange.getResponseBody().write(jsonResponse.getBytes(StandardCharsets.UTF_8));
}
default -> {
if (invitesDisabledTemplate != null) {
exchange.getResponseHeaders().set("Content-Type", "text/html; charset=UTF-8");
exchange.sendResponseHeaders(401, invitesDisabledTemplate.getBytes(StandardCharsets.UTF_8).length);
exchange.getResponseBody().write(invitesDisabledTemplate.getBytes(StandardCharsets.UTF_8));
exchange.getResponseBody().close();
} else {
exchange.sendResponseHeaders(401, -1);
}
}
}
}
private void sendBotNotInGuildTemplate(HttpExchange exchange) throws IOException {
String message = "Guild you were invited to is not supported by the bot. Try again later.";
switch (exchange.getRequestHeaders().getFirst("Accept")) {
case "text/plain" -> {
exchange.getResponseHeaders().set("Content-Type", "text/plain; charset=UTF-8");
exchange.sendResponseHeaders(404, message.getBytes(StandardCharsets.UTF_8).length);
exchange.getResponseBody().write(message.getBytes(StandardCharsets.UTF_8));
}
case "application/json" -> {
exchange.getResponseHeaders().set("Content-Type", "application/json; charset=UTF-8");
String jsonResponse = "{\"error\": \"%s\"}".formatted(message);
exchange.sendResponseHeaders(404, jsonResponse.length());
exchange.getResponseBody().write(jsonResponse.getBytes(StandardCharsets.UTF_8));
}
default -> {
if (botNotInGuildTemplate != null) {
exchange.getResponseHeaders().set("Content-Type", "text/html; charset=UTF-8");
exchange.sendResponseHeaders(404, botNotInGuildTemplate.getBytes(StandardCharsets.UTF_8).length);
exchange.getResponseBody().write(botNotInGuildTemplate.getBytes(StandardCharsets.UTF_8));
exchange.getResponseBody().close();
} else {
exchange.sendResponseHeaders(404, -1);
}
}
}
}
} }
@@ -0,0 +1,107 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="title" content="Discord Inviter">
<meta name="description" content="A simple tool to invite users to a Discord server"/>
<meta name="keywords" content="Discord, Inviter, Tool, Invite Users"/>
<meta name="author" content="YouHaveTrouble"/>
<meta name="og:type" content="website"/>
<meta name="og:title" content="Discord Inviter"/>
<meta name="og:description" content="A simple tool to invite users to a Discord server"/>
<meta name="og:url" content="https://inviter.yht.one"/>
<meta name="twitter:title" content="Discord Inviter"/>
<meta name="twitter:description" content="A simple tool to invite users to a Discord server"/>
<title>Discord Inviter</title>
<style>
:root {
--color-primary: #5865F2;
--color-primary-highlight: #4752C4;
--color-text: #f0f0f0;
}
* {
box-sizing: border-box;
margin: 0;
padding: 0;
font-family: system-ui, sans-serif;
font-weight: normal;
vertical-align: baseline;
overflow-wrap: break-word;
-webkit-font-smoothing: antialiased;
}
body {
line-height: 1.5;
background-color: #272727;
color: var(--color-text);
}
main {
min-height: 100vh;
padding: 1rem;
gap: 2rem;
text-align: center;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
ol, ul {
text-align: left;
margin-left: 2rem;
}
.highlight {
display: inline-block;
padding: 0.1rem 0.2rem;
background-color: rgba(255, 255, 255, 0.05);
border-radius: 0.2rem;
white-space: break-spaces;
overflow-wrap: anywhere;
}
a[href]:not([role="button"]) {
color: var(--color-primary);
text-decoration: none;
transition: color 0.2s ease;
}
a[href]:not([role="button"]):hover {
color: var(--color-primary-highlight);
}
[role="button"] {
display: inline-block;
padding: 0.5rem 1rem;
margin-top: 1rem;
background-color: var(--color-primary);
color: var(--color-text);
text-decoration: none;
border-radius: 0.25rem;
transition: background-color 0.2s ease;
border: none;
cursor: pointer;
font-size: 1rem;
}
[role="button"]:hover {
background-color: var(--color-primary-highlight);
}
</style>
</head>
<body>
<main>
<form method="get">
<h1>Inviter</h1>
<p>Inviter bot is not present in the guild you're trying to join.</p>
<button
type="submit"
role="button"
>Try again</button>
</form>
</main>
</body>
</html>
+3
View File
@@ -82,6 +82,9 @@
text-decoration: none; text-decoration: none;
border-radius: 0.25rem; border-radius: 0.25rem;
transition: background-color 0.2s ease; transition: background-color 0.2s ease;
border: none;
cursor: pointer;
font-size: 1rem;
} }
[role="button"]:hover { [role="button"]:hover {
@@ -0,0 +1,107 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="title" content="Discord Inviter">
<meta name="description" content="A simple tool to invite users to a Discord server"/>
<meta name="keywords" content="Discord, Inviter, Tool, Invite Users"/>
<meta name="author" content="YouHaveTrouble"/>
<meta name="og:type" content="website"/>
<meta name="og:title" content="Discord Inviter"/>
<meta name="og:description" content="A simple tool to invite users to a Discord server"/>
<meta name="og:url" content="https://inviter.yht.one"/>
<meta name="twitter:title" content="Discord Inviter"/>
<meta name="twitter:description" content="A simple tool to invite users to a Discord server"/>
<title>Discord Inviter</title>
<style>
:root {
--color-primary: #5865F2;
--color-primary-highlight: #4752C4;
--color-text: #f0f0f0;
}
* {
box-sizing: border-box;
margin: 0;
padding: 0;
font-family: system-ui, sans-serif;
font-weight: normal;
vertical-align: baseline;
overflow-wrap: break-word;
-webkit-font-smoothing: antialiased;
}
body {
line-height: 1.5;
background-color: #272727;
color: var(--color-text);
}
main {
min-height: 100vh;
padding: 1rem;
gap: 2rem;
text-align: center;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
ol, ul {
text-align: left;
margin-left: 2rem;
}
.highlight {
display: inline-block;
padding: 0.1rem 0.2rem;
background-color: rgba(255, 255, 255, 0.05);
border-radius: 0.2rem;
white-space: break-spaces;
overflow-wrap: anywhere;
}
a[href]:not([role="button"]) {
color: var(--color-primary);
text-decoration: none;
transition: color 0.2s ease;
}
a[href]:not([role="button"]):hover {
color: var(--color-primary-highlight);
}
[role="button"] {
display: inline-block;
padding: 0.5rem 1rem;
margin-top: 1rem;
background-color: var(--color-primary);
color: var(--color-text);
text-decoration: none;
border-radius: 0.25rem;
transition: background-color 0.2s ease;
border: none;
cursor: pointer;
font-size: 1rem;
}
[role="button"]:hover {
background-color: var(--color-primary-highlight);
}
</style>
</head>
<body>
<main>
<form method="get">
<h1>Inviter</h1>
<p>Guild you were invited to currently has invites disabled. Try again later.</p>
<button
type="submit"
role="button"
>Try again</button>
</form>
</main>
</body>
</html>