From 7b5d99e5dd3191fbc1e945702878d3596360c915 Mon Sep 17 00:00:00 2001 From: ITOH Date: Sun, 2 Apr 2023 18:27:48 +0200 Subject: [PATCH] refactor(rest): interaction handling (#2944) * refactor(rest): interaction handling Currently some interaction handling uses `sendRequest` directly. This adds the `runThroughQueue` option, which prevents the request to be handled by a queue effectively giving the same effect as using `sendRequest` directly. This prevents code repetition and supports future endpoints which might not have a rate limit too. Further more all interaction related endpoints have now been set to not send the bots authorization header. * fix invalid file * fix eslint * fix: followups have a rate limit * fix awaiting --- packages/rest/src/manager.ts | 67 +++++++++++++++--------------------- packages/rest/src/types.ts | 21 +++++++---- 2 files changed, 41 insertions(+), 47 deletions(-) diff --git a/packages/rest/src/manager.ts b/packages/rest/src/manager.ts index 5b5e276d1..338403701 100644 --- a/packages/rest/src/manager.ts +++ b/packages/rest/src/manager.ts @@ -924,7 +924,7 @@ export function createRestManager(options: CreateRestManagerOptions): RestManage return parts.join('/') }, - processRequest(request: SendRequestOptions) { + async processRequest(request: SendRequestOptions) { const route = request.url.substring(request.url.indexOf('api/')) const parts = route.split('/') // Remove the api/ @@ -935,6 +935,13 @@ export function createRestManager(options: CreateRestManagerOptions): RestManage request.url = `${rest.baseUrl}/v${rest.version}/${parts.join('/')}` const url = rest.simplifyUrl(request.url, request.method) + + if (request.runThroughQueue === false) { + await rest.sendRequest(request) + + return + } + const queue = rest.queues.get(url) if (queue !== undefined) { @@ -964,22 +971,23 @@ export function createRestManager(options: CreateRestManagerOptions): RestManage return result.status !== 204 ? ((await result.json()) as any) : undefined } - return await new Promise((resolve, reject) => { + return await new Promise(async (resolve, reject) => { const payload: SendRequestOptions = { url, method, requestBodyOptions: options, retryCount: 0, retryRequest: async function (payload: SendRequestOptions) { - rest.processRequest(payload) + await rest.processRequest(payload) }, resolve: (data) => { resolve(data.status !== 204 ? JSON.parse(data.body ?? '{}') : undefined) }, reject, + runThroughQueue: options?.runThroughQueue, } - rest.processRequest(payload) + await rest.processRequest(payload) }) }, @@ -1127,7 +1135,7 @@ export function createRestManager(options: CreateRestManagerOptions): RestManage }, async deleteFollowupMessage(token, messageId) { - await rest.delete(rest.routes.interactions.responses.message(rest.applicationId, token, messageId)) + await rest.delete(rest.routes.interactions.responses.message(rest.applicationId, token, messageId), { unauthorized: true }) }, async deleteGlobalApplicationCommand(commandId) { @@ -1172,7 +1180,7 @@ export function createRestManager(options: CreateRestManagerOptions): RestManage }, async deleteOriginalInteractionResponse(token) { - await rest.delete(rest.routes.interactions.responses.original(rest.applicationId, token)) + await rest.delete(rest.routes.interactions.responses.original(rest.applicationId, token), { unauthorized: true }) }, async deleteOwnReaction(channelId, messageId, reaction) { @@ -1268,6 +1276,7 @@ export function createRestManager(options: CreateRestManagerOptions): RestManage return await rest.patch(rest.routes.interactions.responses.message(rest.applicationId, token, messageId), { body, files: body.files, + unauthorized: true, }) }, @@ -1315,6 +1324,7 @@ export function createRestManager(options: CreateRestManagerOptions): RestManage data: options, }, files: options.files, + unauthorized: true, }) }, @@ -1457,7 +1467,7 @@ export function createRestManager(options: CreateRestManagerOptions): RestManage }, async getFollowupMessage(token, messageId) { - return await rest.get(rest.routes.interactions.responses.message(rest.applicationId, token, messageId)) + return await rest.get(rest.routes.interactions.responses.message(rest.applicationId, token, messageId), { unauthorized: true }) }, async getGatewayBot() { @@ -1525,7 +1535,7 @@ export function createRestManager(options: CreateRestManagerOptions): RestManage }, async getOriginalInteractionResponse(token) { - return await rest.get(rest.routes.interactions.responses.original(rest.applicationId, token)) + return await rest.get(rest.routes.interactions.responses.original(rest.applicationId, token), { unauthorized: true }) }, async getPinnedMessages(channelId) { @@ -1656,43 +1666,20 @@ export function createRestManager(options: CreateRestManagerOptions): RestManage await rest.delete(rest.routes.channels.threads.user(channelId, userId)) }, - // TODO: why that async sendFollowupMessage(token, options) { - return await new Promise((resolve, reject) => { - rest.sendRequest({ - url: rest.routes.webhooks.webhook(rest.applicationId, token), - method: 'POST', - requestBodyOptions: { body: options, files: options.files }, - retryCount: 0, - retryRequest: async function (options: SendRequestOptions) { - // TODO: should change to reprocess queue item - await rest.sendRequest(options) - }, - resolve: (data) => { - resolve(data.status !== 204 ? JSON.parse(data.body ?? '{}') : undefined) - }, - reject, - }) + return await rest.post(rest.routes.webhooks.webhook(rest.applicationId, token), { + body: options, + files: options.files, + unauthorized: true, }) }, - // TODO: why that async sendInteractionResponse(interactionId, token, options) { - await new Promise((resolve, reject) => { - rest.sendRequest({ - url: rest.routes.interactions.responses.callback(interactionId, token), - method: 'POST', - requestBodyOptions: { body: options }, - retryCount: 0, - retryRequest: async function (options: SendRequestOptions) { - // TODO: should change to reprocess queue item - await rest.sendRequest(options) - }, - resolve: (data) => { - resolve(data.status !== 204 ? JSON.parse(data.body ?? '{}') : undefined) - }, - reject, - }) + return await rest.post(rest.routes.interactions.responses.callback(interactionId, token), { + body: options, + files: options.data?.files, + runThroughQueue: false, + unauthorized: true, }) }, diff --git a/packages/rest/src/types.ts b/packages/rest/src/types.ts index 82ae2dfcd..e96514ee4 100644 --- a/packages/rest/src/types.ts +++ b/packages/rest/src/types.ts @@ -169,19 +169,19 @@ export interface RestManager { /** Split a url to separate rate limit buckets based on major/minor parameters. */ simplifyUrl: (url: string, method: RequestMethods) => string /** Make a request to be sent to the api. */ - makeRequest: (method: RequestMethods, url: string, options?: Omit) => Promise + makeRequest: (method: RequestMethods, url: string, options?: MakeRequestOptions) => Promise /** Takes a request and processes it into a queue. */ - processRequest: (request: SendRequestOptions) => void + processRequest: (request: SendRequestOptions) => Promise /** Make a get request to the api */ - get: (url: string, options?: Omit) => Promise> + get: (url: string, options?: Omit) => Promise> /** Make a post request to the api. */ - post: (url: string, options?: Omit) => Promise> + post: (url: string, options?: MakeRequestOptions) => Promise> /** Make a put request to the api. */ - put: (url: string, options?: Omit) => Promise> + put: (url: string, options?: MakeRequestOptions) => Promise> /** Make a delete request to the api. */ - delete: (url: string, options?: Omit) => Promise + delete: (url: string, options?: Omit) => Promise /** Make a patch request to the api. */ - patch: (url: string, options?: Omit) => Promise> + patch: (url: string, options?: MakeRequestOptions) => Promise> /** * Adds a reaction to a message. * @@ -2531,6 +2531,8 @@ export interface CreateRequestBodyOptions { files?: FileContent[] } +export type MakeRequestOptions = Omit & Pick + export interface RequestBody { headers: Record body?: string | FormData @@ -2554,6 +2556,11 @@ export interface SendRequestOptions { bucketId?: string /** Additional request options, used for things like overriding authorization header. */ requestBodyOptions?: CreateRequestBodyOptions + /** + * Whether the request should be run through the queue. + * Useful for routes which do not have any rate limits. + */ + runThroughQueue?: boolean } export interface RestRateLimitedPath {