pissbot-9000/commands/message/search/google.js
2024-08-01 19:39:53 +02:00

200 lines
No EOL
7 KiB
JavaScript
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

const { google } = require('#api');
const { paginator } = require('#client');
const { createEmbed, formatPaginationEmbeds, page } = require('#utils/embed')
const { link, citation, icon, stringwrap, codeblock, pill, smallPill } = require('#utils/markdown')
const { editOrReply } = require('#utils/message')
const { STATICS, STATIC_ICONS } = require('#utils/statics')
// TODO: Turn this into a general purpose permissions constant
const { Permissions } = require("detritus-client/lib/constants");
const { description } = require('../../interaction/slash/search/google');
function renderFooter(context, doodle){
if(doodle.label) return {
iconUrl: doodle.super_g,
text: `${doodle.label} • Google Search`
}
return {
iconUrl: STATICS.google,
text: `Google Search • ${context.application.name}`
}
}
// These have to be synced with the backend (search_service/endpoints/google).
const SEARCH_CARD_TYPES = {
UNKNONW: 0,
SEARCH_RESULT: 1,
KNOWLEDGE_GRAPH: 2,
DOODLE: 3,
ENTITY: 4,
CALCULATOR: 5,
UNIT_CONVERTER: 6,
DICTIONARY: 7,
FUNBOX_COIN_FLIP: 10,
FUNBOX_COLOR_PICKER: 11,
}
// TODO: create a favicon() util
function createSearchResultPage(context, result, doodle){
let res;
switch(result.type){
case SEARCH_CARD_TYPES.SEARCH_RESULT:
res = createEmbed("default", context, {
author: {
iconUrl: `https://www.google.com/s2/favicons?domain=${encodeURIComponent(result.url)}&sz=256`,
name: result.title,
url: result.url
},
description: result.content,
footer: renderFooter(context, doodle)
})
if(result.thumbnail) res.thumbnail = { url: result.thumbnail };
break;
case SEARCH_CARD_TYPES.KNOWLEDGE_GRAPH:
let header = result.card.title;
if(result.card.url) header = link(result.card.url, result.card.title)
res = createEmbed("default", context, {
description: `### ${header}\n`,
footer: renderFooter(context, doodle)
})
if(result.card.image) res.thumbnail = { url: result.card.image };
if(result.card.description) res.description += `-# ${result.card.description}\n`
if(result.card.content){
let cnt = result.card.content.replace(/\n/g, '')
if(cnt.endsWith(" ")) cnt = cnt.substr(0,cnt.length - 1)
res.description += "\n" + cnt + citation(1, result.card.url, "Source")
}
break;
case SEARCH_CARD_TYPES.DOODLE:
res = createEmbed("default", context, {
description: `### ${result.card.title}\n${result.card.description}\n\n${link(result.card.learn_more, `Learn More ${icon("link_open_external")}`, "Learn more about this Doodle")}`,
thumbnail: {
url: result.card.images.thumbnail
},
image: {
url: result.card.images.image
},
footer: renderFooter(context, doodle)
})
break;
case SEARCH_CARD_TYPES.ENTITY:
res = createEmbed("default", context, {
author: {
name: result.card.title
},
thumbnail: {
url: result.card.images.thumbnail
},
description: '',
footer: renderFooter(context, doodle)
})
if(!result.card.images.preview && result.card.link == ""){
delete res.author
res.description = `### ${result.card.title}\n`
}
if(result.card.type) res.description += `-# ${result.card.type}`
if(result.card.color !== "") res.color = parseInt(result.card.color.substring(1,10), 16)
if(result.card.description !== ""){
res.description += "\n\n" + result.card.description
if(result.card.source) res.description += citation(1, result.card.source, "Source") + "\n\n" + link(result.card.source, `Learn More ${icon("link_open_external")}`, "Learn more about this topic");
else if(result.card.link !== "") res.description += "\n\n" + link(result.card.link, `Learn More ${icon("link_open_external")}`, "Learn more about this topic");
}
if(result.card.images.preview) res.author.iconUrl = result.card.images.preview;
if(result.card.link) res.author.url = result.card.link
break;
case SEARCH_CARD_TYPES.CALCULATOR:
res = createEmbed("default", context, {
author: {
name: result.query,
iconUrl: STATIC_ICONS.search_calculator
},
description: codeblock("ansi",[result.result]),
footer: renderFooter(context, doodle)
})
break;
case SEARCH_CARD_TYPES.UNIT_CONVERTER:
res = createEmbed("default", context, {
author: {
name: result.query,
iconUrl: STATIC_ICONS.search_calculator
},
description: `### Unit Converter\n${smallPill(result.units[0])} ${icon("arrow_right")} ${pill(result.units[1])}`,
footer: renderFooter(context, doodle)
})
break;
case SEARCH_CARD_TYPES.FUNBOX_COIN_FLIP:
res = createEmbed("default", context, {
description: `### Flip a coin\n**${result.result}**!`,
thumbnail: {
url: result.sprite
},
footer: renderFooter(context, doodle)
})
break;
case SEARCH_CARD_TYPES.FUNBOX_COLOR_PICKER:
res = createEmbed("default", context, {
description: `### ${result.card.title}\n${result.card.components.map((c)=>`${pill(c.label)} ${smallPill(c.content)}`).join('\n')}`,
thumbnail: {
url: result.card.thumbnail
},
footer: renderFooter(context, doodle)
})
break;
default:
res = createEmbed("error", context, "Unknown GoogleResult Type: " + result.type)
break;
}
return page(res);
}
module.exports = {
name: 'google',
label: 'query',
aliases: ['g', 'search'],
metadata: {
description: 'Returns search results from Google.',
description_short: 'Search on Google',
examples: ['google Eurasian Small Clawed Otter'],
category: 'search',
usage: 'google <query>',
slashCommand: "google"
},
permissionsClient: [Permissions.EMBED_LINKS, Permissions.SEND_MESSAGES, Permissions.USE_EXTERNAL_EMOJIS, Permissions.READ_MESSAGE_HISTORY],
run: async (context, args) => {
context.triggerTyping();
if(!args.query) return editOrReply(context, createEmbed("warning", context, `Missing Parameter (query).`))
try{
let search = await google(context, args.query, context.channel.nsfw)
search = search.response
if(search.body.status == 2) return editOrReply(context, createEmbed("error", context, search.body.message))
let pages = []
for(const res of search.body.results){
pages.push(createSearchResultPage(context, res, search.body.doodle))
}
if(!pages.length) return editOrReply(context, createEmbed("warning", context, `No results found.`))
await paginator.createPaginator({
context,
pages: formatPaginationEmbeds(pages)
});
}catch(e){
console.log(e)
return editOrReply(context, createEmbed("error", context, `Unable to perform google search.`))
}
},
};