const { InteractionContextType, ApplicationIntegrationType, SlashCommandBuilder, EmbedBuilder, ButtonBuilder, ButtonStyle } = require("discord.js"); const { readFileSync } = require("node:fs"); const { stringify } = require("node:querystring"); const { Pagination } = require("pagination.djs"); const data = new SlashCommandBuilder() .setName("file") .setDescription("SearxNG-powered file search") .addStringOption(builder => builder // .setName("query") .setRequired(true) .setDescription("What to search for") ) .setContexts([ InteractionContextType.Guild, InteractionContextType.BotDM, InteractionContextType.PrivateChannel ]) .setIntegrationTypes([ ApplicationIntegrationType.GuildInstall, ApplicationIntegrationType.UserInstall ]); function notEmpty(str) { return str && str.trim() !== '' } const emojis = JSON.parse(readFileSync("config/emojis.json")); module.exports = { data, async execute(interaction) { const query = interaction.options.getString("query"); await interaction.deferReply(); var queryString = stringify({ "categories": "files", "format": "json", "q": query }); const embeds = []; const data = await (await fetch(`${process.env.SEARXNG_INSTANCE}/search?${queryString}`)).json(); for (const result of data.results) { if (result.magnetlink) result.magnetlink = `[magnet](${process.env.BASE_URL}/magnet/${result.magnetlink})`; const footerText = ([ result.filesize, `${result.seed} S`, `${result.leech} L` ]).filter(notEmpty).join(" • "); const site = result.parsed_url.slice(0, 2).join("://"); const description = [ "Downloads:", result.magnetlink, result.torrentfile, result.url ].filter(notEmpty).join("\n"); const embed = new EmbedBuilder() .setAuthor({ name: result.engine, iconURL: `https://vault.incest.world/icons/${result.parsed_url[1]}/icon.png` }) .setTitle(result.title) .setURL(result.url) .setColor("#cba6f7") .setDescription(description) .setFooter({ text: footerText }) .setTimestamp(result.publishedDate ? new Date(result.publishedDate) : null); embeds.push(embed); } const pagination = new Pagination(interaction); pagination.setEmbeds(embeds, (embed, index, array) => { const footerText = [ `${index + 1}/${array.length}`, embed.data.footer.text ].filter(notEmpty).join(' • ') return embed.setFooter({ text: footerText }); }); pagination.render(); } }