const Command = require("../lib/command.js"); const CATEGORY = "misc"; const fetch = require("node-fetch"); const {hastebin, safeString, parseHtmlEntities} = require("../lib/utils.js"); const GoogleImages = require("google-images"); const imagesClient = new GoogleImages(hf.apikeys.gimg, hf.apikeys.google); const yt = new Command("youtube"); yt.addAlias("yt"); yt.category = CATEGORY; yt.helpText = "Search YouTube"; yt.usage = "[search term]"; yt.callback = async function (msg, line) { if (!line) return "Arguments are required."; const req = await fetch( `https://www.googleapis.com/youtube/v3/search?key=${ hf.apikeys.google }&maxResults=5&part=snippet&type=video&q=${encodeURIComponent(line)}` ).then((x) => x.json()); const topVid = req.items[0]; let out = `**${safeString( parseHtmlEntities(topVid.snippet.title) )}** | \`${safeString( parseHtmlEntities(topVid.snippet.channelTitle) )}\`\nhttps://youtu.be/${topVid.id.videoId}\n\n**__See Also:__**\n`; for (let i = 1; i < req.items.length; i++) { const vid = req.items[i]; out += `- **${safeString( parseHtmlEntities(vid.snippet.title) )}** | By: \`${safeString( parseHtmlEntities(vid.snippet.channelTitle) )}\` | \n`; } return out; }; hf.registerCommand(yt); const fyt = new Command("fyt"); fyt.category = CATEGORY; fyt.helpText = "Search YouTube and take the first result."; fyt.usage = "[search term]"; fyt.callback = async function (msg, line) { if (!line) return "Arguments are required."; const req = await fetch( `https://www.googleapis.com/youtube/v3/search?key=${ hf.apikeys.google }&maxResults=2&part=snippet&type=video&q=${encodeURIComponent(line)}` ).then((x) => x.json()); const vid = req.items[0]; return `**${safeString( parseHtmlEntities(vid.snippet.title) )}** | \`${safeString( parseHtmlEntities(vid.snippet.channelTitle) )}\`\nhttps://youtu.be/${vid.id.videoId}`; }; hf.registerCommand(fyt); const WA_NO_ANSWER = "<:ms_cross:503341994974773250> No answer."; const wolfram = new Command("wolfram"); wolfram.category = CATEGORY; wolfram.helpText = "Wolfram Alpha"; wolfram.usage = "<-v> [query]"; wolfram.addAlias("wa"); wolfram.callback = async function (msg, line) { let verbose = false; if (line.includes("-v")) { line = line.replace("-v", "").trim(); verbose = true; } const req = await fetch( `http://api.wolframalpha.com/v2/query?input=${encodeURIComponent( line )}&appid=LH2K8H-T3QKETAGT3&output=json` ).then((x) => x.json()); const data = req.queryresult.pods; if (!data) return WA_NO_ANSWER; // fake no answer if (data[0].subpods[0].plaintext.includes("geoIP")) return WA_NO_ANSWER; if (verbose) { const embed = { title: `Result for: \`${safeString(line)}\``, fields: [], footer: { icon_url: "http://www.wolframalpha.com/share.png", text: "Powered by Wolfram Alpha", }, image: { url: data[1].subpods[0].img.src, }, }; const extra = data.slice(1, 6); for (const x in extra) { embed.fields.push({ name: extra[x].title, value: `[${ extra[x].subpods[0].plaintext.length > 0 ? extra[x].subpods[0].plaintext : "" }](${extra[x].subpods[0].img.src})`, inline: true, }); } return {embed}; } else { let image; if (data[1].subpods[0].img.src) image = Buffer.from( await fetch(data[1].subpods[0].img.src).then((x) => x.arrayBuffer()) ); let string = ""; if (data[1].subpods[0].plaintext.length > 0) string = safeString(data[1].subpods[0].plaintext); if (string.length > 2000 - (6 + safeString(line).length)) string = "Output too long: " + (await hastebin(string)); return { content: `\`${safeString(line)}\` -> ${string.length > 0 ? string : ""}`, file: image && { file: image, name: "wolfram_output.gif", }, }; } }; hf.registerCommand(wolfram); const gimg = new Command("gimg"); gimg.category = CATEGORY; gimg.helpText = "Search Google Images"; gimg.usage = "[query]"; gimg.addAlias("img"); gimg.callback = async function (msg, line) { if (!line) return "No arguments given."; const images = await imagesClient.search(line, { safe: msg.channel.nsfw && !msg.channel?.topic.includes("[no_nsfw]") ? "off" : "high", }); const index = Math.floor(Math.random() * images.length); const image = images[index]; return { embeds: [ { title: image.description, url: image.parentPage, image: { url: image.url, }, footer: { text: `Image ${index}/${images.length}. Rerun to get a different image.`, }, }, ], }; }; hf.registerCommand(gimg); const fimg = new Command("fimg"); fimg.category = CATEGORY; fimg.helpText = "Send first result from Google Images"; fimg.usage = "[query]"; fimg.callback = async function (msg, line) { if (!line) return "No arguments given."; const images = await imagesClient.search(line, { safe: msg.channel.nsfw && !msg.channel?.topic.includes("[no_nsfw]") ? "off" : "high", }); const image = images[0]; return { embeds: [ { title: image.description, url: image.parentPage, image: { url: image.url, }, }, ], }; }; hf.registerCommand(fimg); const poll = new Command("poll"); poll.category = CATEGORY; poll.helpText = "Start a poll"; poll.usage = "[topic] [option 1] [option 2] [...option 3-10]"; poll.callback = async function (msg, line, topic, ...options) { if (!line || !topic) return 'Usage: hf!poll "topic" "option 1" "option 2" "...options 3-10"'; const arrOptions = [...options].slice(0, 10); if (arrOptions.length < 2) return "A minimum of two options are required."; const reactions = []; let displayString = `**${msg.author.username}#${msg.author.discriminator}** has started a poll:\n**__${topic}__**\n`; for (let i = 0; i < arrOptions.length; i++) { displayString += (i === 9 ? "\ud83d\udd1f" : `${i + 1}\u20e3`) + ": " + arrOptions[i] + "\n"; reactions[i] = i === 9 ? "\ud83d\udd1f" : `${i + 1}\u20e3`; } return { content: displayString, addReactions: reactions, }; }; hf.registerCommand(poll); const vote = new Command("vote"); vote.category = CATEGORY; vote.helpText = "Start a yes/no vote"; vote.usage = "[topic]"; vote.callback = async function (msg, line) { if (!line) return "No topic given."; return { content: `**${msg.author.username}#${msg.author.discriminator}** has started a vote:\n**__${line}__**\n<:ms_tick:503341995348066313>: Yes\n<:ms_cross:503341994974773250>: No`, addReactions: [ ":ms_tick:503341995348066313", ":ms_cross:503341994974773250", ], }; }; hf.registerCommand(vote); const DAYS = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"]; const arsched = new Command("arsched"); arsched.category = CATEGORY; arsched.helpText = "aNONradio.net schedule"; arsched.callback = async function (msg, line) { const now = new Date(); const schedule = await fetch("https://anonradio.net/schedule/").then((res) => res.text() ); let lines = schedule.split("\n"); lines = lines.slice(4, lines.length - 2); const parsedLines = []; for (const line of lines) { const [_, time, id, name] = line.match(/^(.{3,4} .{4})\s+(.+?) {2}(.+?)$/); const tmp = time.split(" "); const day = tmp[0]; let hour = tmp[1]; const currentDay = now.getUTCDay(); const targetDay = DAYS.indexOf(day); const delta = (targetDay + 7 - currentDay) % 7; let currentYear = now.getUTCFullYear(); const currentMonth = now.getUTCMonth(); const currentDateDay = now.getUTCDate(); let targetMonth = currentMonth; const lastDay = new Date(currentYear, currentMonth, 0).getDate(); let targetDateDay = currentDateDay + delta; if (targetDateDay > lastDay) { targetMonth = currentMonth === 12 ? 1 : currentMonth + 1; targetDateDay = 1; if (currentMonth === 12) currentYear++; } hour = hour.slice(0, 2) + ":" + hour.slice(-2); const timestamp = Date.parse( `${DAYS[targetDay]}, ${currentYear}-${targetMonth}-${targetDateDay} ${hour} UTC` ) / 1000; parsedLines.push({timestamp, id, name}); } const liveNow = parsedLines.splice(0, 1)[0]; liveNow.name = liveNow.name.replace(" <- Live NOW", ""); return { embeds: [ { title: "Click to listen", url: "http://anonradio.net:8000/anonradio", author: { name: `LIVE NOW: ${liveNow.name} (\`${liveNow.id}\`)`, }, fields: parsedLines.map((line) => ({ inline: true, name: `${line.name} (\`${line.id}\`)`, value: ``, })), }, ], }; }; hf.registerCommand(arsched);