|
| 1 | +import { verifyKey } from "discord-interactions"; |
| 2 | +import { ApplicationCommandInteractionDataOptionString as APIStringOption, APIInteraction, APIInteractionResponse, InteractionResponseType, InteractionType, APIGuildInteraction, MessageFlags, APIMessage, APIChannel, PermissionFlagsBits, APIGuildMember, Snowflake, APIInteractionGuildMember, OverwriteType, APIEmbed, APIEmbedImage } from "discord-api-types/v8"; |
| 3 | +import renderMessage from "./render"; |
| 4 | + |
| 5 | +export default async function handleRequest(request: Request): Promise<Response> { |
| 6 | + const signature = request.headers.get("X-Signature-Ed25519"); |
| 7 | + const timestamp = request.headers.get("X-Signature-Timestamp"); |
| 8 | + |
| 9 | + const body = await request.text(); |
| 10 | + |
| 11 | + if (!signature || !timestamp || !verifyKey(body, signature, timestamp, publicKey)) { |
| 12 | + return new Response("", { status: 401 }); |
| 13 | + } |
| 14 | + |
| 15 | + const interaction: APIInteraction = JSON.parse(body); |
| 16 | + |
| 17 | + if (interaction.type === InteractionType.Ping) { |
| 18 | + return respond({ type: InteractionResponseType.Pong }); |
| 19 | + } |
| 20 | + |
| 21 | + if (interaction.type === InteractionType.ApplicationCommand) { |
| 22 | + if (interaction.data!.name === "about") { |
| 23 | + return respond({ |
| 24 | + type: 4, |
| 25 | + data: { |
| 26 | + flags: 1 << 6, |
| 27 | + embeds: [{ |
| 28 | + color: 0x7289DA, |
| 29 | + title: "<:iconquote:778925506081980437> About QuoteBot", |
| 30 | + description: "QuoteBot is a bot made by Daedalus#0001 designed to allow you to send simple, easy to read quotes. To use it, just type `/quote <message link to quote>`.", |
| 31 | + fields: [{ |
| 32 | + name: "» Support Server", |
| 33 | + value: "https://discord.gg/k4Wr7YTQJK", |
| 34 | + inline: true |
| 35 | + }, { |
| 36 | + name: "» Source", |
| 37 | + value: "https://github.com/RedDaedalus/quotebot", |
| 38 | + inline: true |
| 39 | + }] |
| 40 | + }] |
| 41 | + } |
| 42 | + }); |
| 43 | + } |
| 44 | + |
| 45 | + const guildInteraction = interaction as APIGuildInteraction; |
| 46 | + if (!guildInteraction.member) { |
| 47 | + return respond("<:error:837444069974081617> This command cannot be used from direct messages.", MessageFlags.EPHEMERAL); |
| 48 | + } |
| 49 | + |
| 50 | + const messageLink = (interaction.data!.options![0] as APIStringOption).value; |
| 51 | + const data = messageLink.split("/").reverse(); |
| 52 | + |
| 53 | + if (data.length < 3) return respond("<:error:837444069974081617> Please provide a valid message link.", MessageFlags.EPHEMERAL); |
| 54 | + const [messageId, channelId, guildId] = data; |
| 55 | + |
| 56 | + if (guildId !== guildInteraction.guild_id) return respond(`<:error:837444069974081617> You can only quote messages from inside this server. ${guildId} ${guildInteraction.guild_id}`, MessageFlags.EPHEMERAL); |
| 57 | + |
| 58 | + const message: APIMessage = await fetch(`https://discord.com/api/v9/channels/${channelId}/messages/${messageId}`, { |
| 59 | + headers: { |
| 60 | + Authorization: `Bot ${token}` |
| 61 | + } |
| 62 | + }).then(res => res.json()); |
| 63 | + |
| 64 | + if (interaction.data!.name === "quote") { |
| 65 | + const embeds = await renderMessage(message, guildInteraction.member.user, guildInteraction.guild_id); |
| 66 | + if (!embeds) return respond("<:error:837444069974081617> This message cannot be quoted."); |
| 67 | + |
| 68 | + return respond({ |
| 69 | + type: 4, |
| 70 | + data: { |
| 71 | + embeds |
| 72 | + } |
| 73 | + }); |
| 74 | + } |
| 75 | + |
| 76 | + if (interaction.data!.name === "source") { |
| 77 | + return respond("```json\n" + JSON.stringify(message, null, "\t") + "\n```", MessageFlags.EPHEMERAL); |
| 78 | + } |
| 79 | + } |
| 80 | + |
| 81 | + return new Response("Unsupported interaction type", { status: 400 }); |
| 82 | +} |
| 83 | + |
| 84 | +function respond(response: APIInteractionResponse | string, flags?: MessageFlags): Response { |
| 85 | + if (typeof response === "string") return respond({ |
| 86 | + type: 4, |
| 87 | + data: { |
| 88 | + flags, |
| 89 | + content: response |
| 90 | + } |
| 91 | + }); |
| 92 | + |
| 93 | + return new Response(JSON.stringify(response), { |
| 94 | + headers: { |
| 95 | + "Content-Type": "application/json" |
| 96 | + } |
| 97 | + }); |
| 98 | +} |
0 commit comments