From acf0a42a45225269439154b53f4309ba2ebddbd2 Mon Sep 17 00:00:00 2001 From: xHyroM Date: Fri, 26 May 2023 23:08:45 +0200 Subject: [PATCH] feat: add support for edit message --- package.json | 3 + packages/bot/src/commands/edit_message.ts | 97 +++++++++++++++++++++++ packages/bot/src/index.ts | 3 + packages/bot/src/modals/setup.ts | 4 + packages/bot/src/types.d.ts | 2 + packages/bot/src/utils/sendFinal.ts | 38 ++++++--- pnpm-lock.yaml | 65 +++++++++++++++ test.txt | 0 8 files changed, 202 insertions(+), 10 deletions(-) create mode 100644 packages/bot/src/commands/edit_message.ts delete mode 100644 test.txt diff --git a/package.json b/package.json index aa8830f..0a59b7b 100644 --- a/package.json +++ b/package.json @@ -18,5 +18,8 @@ "packageManager": "pnpm@8.1.0", "devDependencies": { "rome": "^12.0.0" + }, + "dependencies": { + "turbo": "^1.9.9" } } diff --git a/packages/bot/src/commands/edit_message.ts b/packages/bot/src/commands/edit_message.ts new file mode 100644 index 0000000..89860b2 --- /dev/null +++ b/packages/bot/src/commands/edit_message.ts @@ -0,0 +1,97 @@ +import { + APIMessageApplicationCommandInteractionDataResolved, + InteractionResponseType, + MessageFlags, + RouteBases, + Routes, + APIRole, + ButtonStyle, +} from "discord-api-types/v10"; +import { Command } from "../structs/Command"; +import { ActionRowBuilder, ButtonBuilder } from "builders"; +import { REDIS } from "../things"; +import { encodeToHex } from "serialize"; + +new Command({ + name: "Edit Message", + acknowledge: false, + run: async (ctx) => { + if (!ctx.guildId) + return ctx.respond({ + type: InteractionResponseType.ChannelMessageWithSource, + data: { + content: "Guild not found.", + }, + }); + + const resolved = ctx.interaction.data + .resolved as APIMessageApplicationCommandInteractionDataResolved; + const messages = resolved.messages; + const message = Object.values(messages)[0]; + + if (message.author.id !== ctx.env.applicationId) { + return ctx.respond({ + type: InteractionResponseType.ChannelMessageWithSource, + data: { + content: "This message was not sent by me.", + flags: MessageFlags.Ephemeral, + }, + }); + } + + // Delete the data if it exists + await REDIS.del(`roles-bot-setup:${ctx.guildId}`); + + await REDIS.setex( + `roles-bot-setup:${ctx.guildId}`, + encodeToHex({ + channelId: message.channel_id, + originalMessageId: message.id, + sendAs: "bot", + }), + 600, + ); + + const roles = (await ( + await fetch(`${RouteBases.api}${Routes.guildRoles(ctx.guildId)}`, { + headers: { + Authorization: `Bot ${ctx.env.token}`, + }, + }) + ).json()) as APIRole[]; + + await REDIS.setex( + `roles-bot-setup-roles:${ctx.guildId}`, + encodeToHex( + roles.map((r) => ({ + id: r.id, + name: r.name, + })), + ), + 3600, + ); + + return ctx.respond({ + type: InteractionResponseType.ChannelMessageWithSource, + data: { + content: + "Choose whether you want to use buttons or dropdown menu (select menu).", + components: [ + new ActionRowBuilder() + .addComponents( + new ButtonBuilder() + .setLabel("Buttons") + .setCustomId("setup:part-selecting:buttons") + .setStyle(ButtonStyle.Primary), + new ButtonBuilder() + .setLabel("Dropdowns") + .setCustomId("setup:part-selecting:dropdowns") + .setStyle(ButtonStyle.Primary), + ) + .toJSON(), + ], + flags: MessageFlags.Ephemeral, + }, + }); + }, +}); diff --git a/packages/bot/src/index.ts b/packages/bot/src/index.ts index fca84c6..c26d235 100644 --- a/packages/bot/src/index.ts +++ b/packages/bot/src/index.ts @@ -1,11 +1,13 @@ import "./commands/setup"; import "./commands/info"; +import "./commands/edit_message"; import "./components/setup"; import "./components/select"; import "./modals/setup"; import { APIApplicationCommandInteraction, + APIMessageApplicationCommandInteraction, APIMessageComponentInteraction, APIModalSubmitInteraction, APIPingInteraction, @@ -35,6 +37,7 @@ export default { const interaction = (await request.json()) as | APIPingInteraction | APIApplicationCommandInteraction + | APIMessageApplicationCommandInteraction | APIModalSubmitInteraction | APIMessageComponentInteraction; diff --git a/packages/bot/src/modals/setup.ts b/packages/bot/src/modals/setup.ts index 7fbc16a..b04c4d1 100644 --- a/packages/bot/src/modals/setup.ts +++ b/packages/bot/src/modals/setup.ts @@ -128,6 +128,10 @@ new Modal({ data.message = { content, embedTitle, embedDescription, embedColor }; + if (data.originalMessageId) { + return sendFinal(ctx, data); + } + await REDIS.setex( `roles-bot-setup:${ctx.interaction.guild_id}`, encodeToHex(data), diff --git a/packages/bot/src/types.d.ts b/packages/bot/src/types.d.ts index b56c6d6..8c2d4c7 100644 --- a/packages/bot/src/types.d.ts +++ b/packages/bot/src/types.d.ts @@ -18,6 +18,7 @@ declare type DeclaredId = Record< declare interface Env { publicKey: string; token: string; + applicationId: string; redisApiClientKey: string; redisApiClientHost: string; } @@ -32,6 +33,7 @@ declare interface RoleId { declare interface BasicData { channelId: string; + originalMessageId?: string | null; selecting: "buttons" | "dropdowns"; roleIds: RoleId[]; message: { diff --git a/packages/bot/src/utils/sendFinal.ts b/packages/bot/src/utils/sendFinal.ts index 39734d2..cff4309 100644 --- a/packages/bot/src/utils/sendFinal.ts +++ b/packages/bot/src/utils/sendFinal.ts @@ -115,17 +115,35 @@ export default async function (ctx: Context, data: Data) { switch (data.sendAs) { case "bot": { - const res = await fetch( - `${RouteBases.api}${Routes.channelMessages(data.channelId)}`, - { - method: "POST", - headers: { - Authorization: `Bot ${ctx.env.token}`, - "Content-Type": "application/json", + let res; + if (data.originalMessageId) { + res = await fetch( + `${RouteBases.api}${Routes.channelMessage( + data.channelId, + data.originalMessageId, + )}`, + { + method: "PATCH", + headers: { + Authorization: `Bot ${ctx.env.token}`, + "Content-Type": "application/json", + }, + body: JSON.stringify(payload), }, - body: JSON.stringify(payload), - }, - ); + ); + } else { + res = await fetch( + `${RouteBases.api}${Routes.channelMessages(data.channelId)}`, + { + method: "POST", + headers: { + Authorization: `Bot ${ctx.env.token}`, + "Content-Type": "application/json", + }, + body: JSON.stringify(payload), + }, + ); + } if (!res.ok) { const json: { message: string; code: string } = await res.json(); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 8a033fe..1c467ad 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -3,6 +3,10 @@ lockfileVersion: '6.0' importers: .: + dependencies: + turbo: + specifier: ^1.9.9 + version: 1.9.9 devDependencies: rome: specifier: ^12.0.0 @@ -7337,6 +7341,67 @@ packages: safe-buffer: 5.2.1 dev: false + /turbo-darwin-64@1.9.9: + resolution: {integrity: sha512-UDGM9E21eCDzF5t1F4rzrjwWutcup33e7ZjNJcW/mJDPorazZzqXGKEPIy9kXwKhamUUXfC7668r6ZuA1WXF2Q==} + cpu: [x64] + os: [darwin] + requiresBuild: true + dev: false + optional: true + + /turbo-darwin-arm64@1.9.9: + resolution: {integrity: sha512-VyfkXzTJpYLTAQ9krq2myyEq7RPObilpS04lgJ4OO1piq76RNmSpX9F/t9JCaY9Pj/4TL7i0d8PM7NGhwEA5Ag==} + cpu: [arm64] + os: [darwin] + requiresBuild: true + dev: false + optional: true + + /turbo-linux-64@1.9.9: + resolution: {integrity: sha512-Fu1MY29Odg8dHOqXcpIIGC3T63XLOGgnGfbobXMKdrC7JQDvtJv8TUCYciRsyknZYjyyKK1z6zKuYIiDjf3KeQ==} + cpu: [x64] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /turbo-linux-arm64@1.9.9: + resolution: {integrity: sha512-50LI8NafPuJxdnMCBeDdzgyt1cgjQG7FwkyY336v4e95WJPUVjrHdrKH6jYXhOUyrv9+jCJxwX1Yrg02t5yJ1g==} + cpu: [arm64] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /turbo-windows-64@1.9.9: + resolution: {integrity: sha512-9IsTReoLmQl1IRsy3WExe2j2RKWXQyXujfJ4fXF+jp08KxjVF4/tYP2CIRJx/A7UP/7keBta27bZqzAjsmbSTA==} + cpu: [x64] + os: [win32] + requiresBuild: true + dev: false + optional: true + + /turbo-windows-arm64@1.9.9: + resolution: {integrity: sha512-CUu4hpeQo68JjDr0V0ygTQRLbS+/sNfdqEVV+Xz9136vpKn2WMQLAuUBVZV0Sp0S/7i+zGnplskT0fED+W46wQ==} + cpu: [arm64] + os: [win32] + requiresBuild: true + dev: false + optional: true + + /turbo@1.9.9: + resolution: {integrity: sha512-+ZS66LOT7ahKHxh6XrIdcmf2Yk9mNpAbPEj4iF2cs0cAeaDU3xLVPZFF0HbSho89Uxwhx7b5HBgPbdcjQTwQkg==} + hasBin: true + requiresBuild: true + optionalDependencies: + turbo-darwin-64: 1.9.9 + turbo-darwin-arm64: 1.9.9 + turbo-linux-64: 1.9.9 + turbo-linux-arm64: 1.9.9 + turbo-windows-64: 1.9.9 + turbo-windows-arm64: 1.9.9 + dev: false + /type-check@0.4.0: resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} engines: {node: '>= 0.8.0'} diff --git a/test.txt b/test.txt deleted file mode 100644 index e69de29..0000000