From f94b6f35bbbf081b6b0f161cc6d29b6a681cb3d5 Mon Sep 17 00:00:00 2001 From: ITOH Date: Sun, 10 Apr 2022 14:57:21 +0200 Subject: [PATCH 1/5] style(plugins): deno fmt --- plugins/permissions/src/channels/stage.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/permissions/src/channels/stage.ts b/plugins/permissions/src/channels/stage.ts index 868d4770c..e8c9c2167 100644 --- a/plugins/permissions/src/channels/stage.ts +++ b/plugins/permissions/src/channels/stage.ts @@ -16,7 +16,7 @@ export function createStageInstance(bot: BotWithCache) { "MUTE_MEMBERS", "MOVE_MEMBERS", ]); - + if (options.sendStartNotification) { perms.add("MENTION_EVERYONE"); } From 88f7529dc4f7ca5562c3243b346f8bfef744331e Mon Sep 17 00:00:00 2001 From: Andreas Fink Date: Sun, 10 Apr 2022 19:22:56 +0200 Subject: [PATCH 2/5] feat: Modified processGlobalQueue to be able to handle results in runMethod (#2101) * feat: Modified processGlobalQueue to be able to handle results in runMethod * Apply suggestions from code review, step 1 Co-authored-by: ITOH * Apply suggestions from code review, step 2 * Update Files * Update to resolve/reject * Fixes & deno fmt Co-authored-by: ITOH Co-authored-by: Skillz4Killz <23035000+Skillz4Killz@users.noreply.github.com> --- rest/processGlobalQueue.ts | 35 ++++++++++++++++++++-------- rest/rest.ts | 16 +++++++++++-- rest/runMethod.ts | 7 +++--- rest/runProxyMethod.ts | 47 ++++++++++++++++++++++++++++++++++++++ 4 files changed, 91 insertions(+), 14 deletions(-) create mode 100644 rest/runProxyMethod.ts diff --git a/rest/processGlobalQueue.ts b/rest/processGlobalQueue.ts index 72f071aed..b0af07614 100644 --- a/rest/processGlobalQueue.ts +++ b/rest/processGlobalQueue.ts @@ -118,18 +118,27 @@ export async function processGlobalQueue(rest: RestManager) { // If NOT rate limited remove from queue if (response.status !== 429) { + let json = undefined; if (response.type) { - console.log(JSON.stringify(await response.json())); + json = JSON.stringify(await response.json()); + console.log(json); } - request.request.reject(new Error(`[${response.status}] ${error}`)); + request.request.reject({ + ok: false, + status: response.status, + error, + body: json, + }); } else { if (request.payload.retryCount++ >= rest.maxRetryCount) { rest.debug(`[REST - RetriesMaxed] ${JSON.stringify(request.payload)}`); // REMOVE ITEM FROM QUEUE TO PREVENT RETRY - request.request.reject( - new Error(`[${response.status}] The request was rate limited and it maxed out the retries limit.`), - ); + request.request.reject({ + ok: false, + status: response.status, + error: "The request was rate limited and it maxed out the retries limit.", + }); continue; } @@ -143,21 +152,29 @@ export async function processGlobalQueue(rest: RestManager) { // SOMETIMES DISCORD RETURNS AN EMPTY 204 RESPONSE THAT CAN'T BE MADE TO JSON if (response.status === 204) { rest.debug(`[REST - FetchSuccess] URL: ${request.urlToUse} | ${JSON.stringify(request.payload)}`); - request.request.respond({ status: 204 }); + request.request.respond({ + ok: true, + status: 204, + }); } else { // CONVERT THE RESPONSE TO JSON - const json = await response.json(); + const json = JSON.stringify(await response.json()); rest.debug(`[REST - fetchSuccess] ${JSON.stringify(request.payload)}`); request.request.respond({ + ok: true, status: 200, - body: JSON.stringify(json), + body: json, }); } } catch (error) { // SOMETHING WENT WRONG, LOG AND RESPOND WITH ERROR rest.debug(`[REST - fetchFailed] Payload: ${JSON.stringify(request.payload)} | Error: ${error}`); - request.request.reject(error); + request.request.reject({ + ok: false, + status: 599, + error: "Internal Proxy Error", + }); } } diff --git a/rest/rest.ts b/rest/rest.ts index 78ecd8f7f..184de4c89 100644 --- a/rest/rest.ts +++ b/rest/rest.ts @@ -7,6 +7,7 @@ import { processRateLimitedPaths } from "./processRateLimitedPaths.ts"; import { processRequest } from "./processRequest.ts"; import { processRequestHeaders } from "./processRequestHeaders.ts"; import { runMethod } from "./runMethod.ts"; +import { runProxyMethod } from "./runProxyMethod.ts"; import { simplifyUrl } from "./simplifyUrl.ts"; export const rest = { @@ -49,14 +50,25 @@ export const rest = { processRequest, createRequestBody, runMethod, + runProxyMethod, simplifyUrl, }; export interface RestRequest { url: string; method: string; - respond: (payload: { status: number; body?: string }) => unknown; - reject: (error: unknown) => unknown; + respond: (payload: RestRequestResponse) => unknown; + reject: (payload: RestRequestRejection) => unknown; +} + +export interface RestRequestResponse { + ok: boolean; + status: number; + body?: string; +} + +export interface RestRequestRejection extends RestRequestResponse { + error: string; } export interface RestPayload { diff --git a/rest/runMethod.ts b/rest/runMethod.ts index 559448be8..b072bfb45 100644 --- a/rest/runMethod.ts +++ b/rest/runMethod.ts @@ -1,5 +1,6 @@ import { RestManager } from "../bot.ts"; import { API_VERSION, BASE_URL, IMAGE_BASE_URL } from "../util/constants.ts"; +import { RestRequestRejection, RestRequestResponse } from "./rest.ts"; export async function runMethod( rest: RestManager, @@ -63,11 +64,11 @@ export async function runMethod( { url, method, - reject: (error: unknown) => { - errorStack.message = (error as Error)?.message; + reject: (data: RestRequestRejection) => { + errorStack.message = `[${data.status}] ${data.error}`; reject(errorStack); }, - respond: (data: { status: number; body?: string }) => + respond: (data: RestRequestResponse) => resolve(data.status !== 204 ? JSON.parse(data.body ?? "{}") : (undefined as unknown as T)), }, { diff --git a/rest/runProxyMethod.ts b/rest/runProxyMethod.ts new file mode 100644 index 000000000..f05c03b79 --- /dev/null +++ b/rest/runProxyMethod.ts @@ -0,0 +1,47 @@ +import { RestManager } from "../bot.ts"; +import { RestRequestRejection, RestRequestResponse } from "./rest.ts"; + +export type ProxyMethodResponse = Omit & { body?: T }; + +// Left out proxy request, because it's not needed here +// this file could also be moved to a plugin. +export async function runProxyMethod( + rest: RestManager, + method: "get" | "post" | "put" | "delete" | "patch", + url: string, + body?: unknown, + retryCount = 0, + bucketId?: string, +): Promise> { + rest.debug( + `[REST - RequestCreate] Method: ${method} | URL: ${url} | Retry Count: ${retryCount} | Bucket ID: ${bucketId} | Body: ${ + JSON.stringify( + body, + ) + }`, + ); + + // No proxy so we need to handle all rate limiting and such + return new Promise((resolve, reject) => { + rest.processRequest( + rest, + { + url, + method, + reject: (data: RestRequestRejection) => { + const { body: b, ...r } = data; + reject({ body: data.status !== 204 ? JSON.parse(b ?? "{}") : (undefined as unknown as T), ...r }); + }, + respond: (data: RestRequestResponse) => { + const { body: b, ...r } = data; + resolve({ body: data.status !== 204 ? JSON.parse(b ?? "{}") : (undefined as unknown as T), ...r }); + }, + }, + { + bucketId, + body: body as Record | undefined, + retryCount, + }, + ); + }); +} From b24893541bb43e4b3eb86c29a3cbbb90b33efb6b Mon Sep 17 00:00:00 2001 From: viinz <42003446+dev-viinz@users.noreply.github.com> Date: Sun, 10 Apr 2022 19:23:08 +0200 Subject: [PATCH 3/5] fix: prevent crashing the rest process (#2159) * fix: prevent crashing the rest process There where instances where some requests crashed the rest process. I found that checking for a body pretty much fixed it. There is probably a better way to do this, please improve this if you have an idea :) * chore: use undefined instead of empty string Co-authored-by: LTS20050703 <87189679+lts20050703@users.noreply.github.com> * chore: use ternary operator Co-authored-by: LTS20050703 <87189679+lts20050703@users.noreply.github.com> --- template/bigbot/src/rest/mod.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/template/bigbot/src/rest/mod.ts b/template/bigbot/src/rest/mod.ts index 425153a30..08f9d8456 100644 --- a/template/bigbot/src/rest/mod.ts +++ b/template/bigbot/src/rest/mod.ts @@ -42,7 +42,7 @@ async function handleRequest(conn: Deno.Conn) { ); } - const json = (await requestEvent.request.json()); + const json = requestEvent.request.body ? (await requestEvent.request.json()) : undefined; try { const result = await rest.runMethod( From 412504d792dd7094b395a84f4746e892bba71f33 Mon Sep 17 00:00:00 2001 From: Andreas Fink Date: Sun, 10 Apr 2022 19:23:36 +0200 Subject: [PATCH 4/5] Update Component typings & their links (#2162) --- types/discordeno.ts | 36 +++++++++++++++++++----------------- 1 file changed, 19 insertions(+), 17 deletions(-) diff --git a/types/discordeno.ts b/types/discordeno.ts index f61432c47..3c88f6e92 100644 --- a/types/discordeno.ts +++ b/types/discordeno.ts @@ -6,7 +6,7 @@ export type MessageComponents = ActionRow[]; /** https://discord.com/developers/docs/interactions/message-components#actionrow */ export interface ActionRow { /** Action rows are a group of buttons. */ - type: 1; + type: MessageComponentTypes.ActionRow; /** The components in this row */ components: | [SelectMenuComponent | ButtonComponent | InputTextComponent] @@ -16,21 +16,7 @@ export interface ActionRow { | [ButtonComponent, ButtonComponent, ButtonComponent, ButtonComponent, ButtonComponent]; } -export interface SelectMenuComponent { - type: MessageComponentTypes.SelectMenu; - /** A custom identifier for this component. Maximum 100 characters. */ - customId: string; - /** A custom placeholder text if nothing is selected. Maximum 150 characters. */ - placeholder?: string; - /** The minimum number of items that must be selected. Default 1. Between 1-25. */ - minValues?: number; - /** The maximum number of items that can be selected. Default 1. Between 1-25. */ - maxValues?: number; - /** The choices! Maximum of 25 items. */ - options: SelectOption[]; -} - -/** https://discord.com/developers/docs/interactions/message-components#buttons-button-object */ +/** https://discord.com/developers/docs/interactions/message-components#button-object-button-structure */ export interface ButtonComponent { /** All button components have type 2 */ type: MessageComponentTypes.Button; @@ -55,9 +41,25 @@ export interface ButtonComponent { disabled?: boolean; } +/** https://discord.com/developers/docs/interactions/message-components#select-menu-object-select-menu-structure */ +export interface SelectMenuComponent { + /** SelectMenu Component is of type 3 */ + type: MessageComponentTypes.SelectMenu; + /** A custom identifier for this component. Maximum 100 characters. */ + customId: string; + /** A custom placeholder text if nothing is selected. Maximum 150 characters. */ + placeholder?: string; + /** The minimum number of items that must be selected. Default 1. Between 1-25. */ + minValues?: number; + /** The maximum number of items that can be selected. Default 1. Between 1-25. */ + maxValues?: number; + /** The choices! Maximum of 25 items. */ + options: SelectOption[]; +} + /** https://discord.com/developers/docs/interactions/message-components#text-inputs-text-input-structure */ export interface InputTextComponent { - /** InputText Component is of type 3 */ + /** InputText Component is of type 4 */ type: MessageComponentTypes.InputText; /** The style of the InputText */ style: TextStyles; From ac9434b40ad6a915cad20a749a6a98c3b30b739f Mon Sep 17 00:00:00 2001 From: ITOH Date: Sun, 10 Apr 2022 19:28:16 +0200 Subject: [PATCH 5/5] release: 13.0.0-rc35 --- util/constants.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/util/constants.ts b/util/constants.ts index 6afc699e6..1d6c5660b 100644 --- a/util/constants.ts +++ b/util/constants.ts @@ -9,7 +9,7 @@ export const GATEWAY_VERSION = 10; // TODO: update this version /** https://github.com/discordeno/discordeno/releases */ -export const DISCORDENO_VERSION = "13.0.0-rc34"; +export const DISCORDENO_VERSION = "13.0.0-rc35"; /** https://discord.com/developers/docs/reference#user-agent */ export const USER_AGENT = `DiscordBot (https://github.com/discordeno/discordeno, v${DISCORDENO_VERSION})`;