import { APIChatInputApplicationCommandInteraction, ButtonStyle, Routes } from 'discord-api-types/v10'; import { InteractionResponseType } from 'discord-api-types/v10'; import { command } from "../types/command.js"; import { ActionRowBuilder, ButtonBuilder } from '@discord-interactions/builders'; import getMeme from '../utils/getMeme.js'; export default { name: "meme", handle: async ({ interaction, response, wait, env }) => { const deferredResponse = response({ type: InteractionResponseType.DeferredChannelMessageWithSource }); wait((async () => { function getId(interaction: APIChatInputApplicationCommandInteraction) { return interaction.user?.id ?? interaction.member?.user.id; } type ResponseData = { userId: string; preferredSubreddit?: string; }; const query = await env.DB .prepare(`SELECT * FROM Users WHERE userId = ?1`) .bind(getId(interaction)) .first(); const subreddits = ['memes', 'dankmemes', 'me_irl']; const subreddit = query?.preferredSubreddit ?? subreddits[Math.floor(Math.random() * subreddits.length)]; const memeData = await getMeme(subreddit); const webhookUrl = `https://discord.com/api/v10${Routes.webhookMessage(env.discord_application_id, interaction.token, '@original')}`; if (!memeData || !memeData.url) { await fetch(webhookUrl, { body: JSON.stringify({ content: "I was unable to get a random meme at this time :(" }), method: 'PATCH', headers: { "Content-Type": "application/json" } }); return; } try { const memeBuffer = await getBuffer(memeData.url); const formData = new FormData(); formData.append("file", memeBuffer, "meme.png"); formData.append("payload_json", JSON.stringify({ components: [ new ActionRowBuilder().addComponents( new ButtonBuilder() .setCustomId('meme') .setLabel('Another meme') .setStyle(ButtonStyle.Secondary) ).toJSON() ], })); const editResponse = await fetch(webhookUrl, { method: "PATCH", body: formData, }); const jsonResponse = await editResponse.json(); if(!editResponse.ok) { console.log(jsonResponse); } } catch (error) { console.error("Failed to edit response:", error); } })()); return deferredResponse; } } satisfies command; async function getBuffer(url: string): Promise { const response = await fetch(url); if (!response.ok) throw new Error('Failed to fetch the image'); return await response.blob(); }