diff options
Diffstat (limited to 'src/api/util/handlers/Message.ts')
-rw-r--r-- | src/api/util/handlers/Message.ts | 143 |
1 files changed, 15 insertions, 128 deletions
diff --git a/src/api/util/handlers/Message.ts b/src/api/util/handlers/Message.ts index c0bdb6b0..09b86fc2 100644 --- a/src/api/util/handlers/Message.ts +++ b/src/api/util/handlers/Message.ts @@ -24,9 +24,8 @@ import { MessageCreateSchema, } from "@fosscord/util"; import { HTTPError } from "lambert-server"; -import fetch from "node-fetch"; -import cheerio from "cheerio"; import { In } from "typeorm"; +import { EmbedHandlers } from "@fosscord/api"; const allow_empty = false; // TODO: check webhook, application, system author, stickers // TODO: embed gifs/videos/images @@ -34,18 +33,6 @@ const allow_empty = false; const LINK_REGEX = /https?:\/\/(www\.)?[-a-zA-Z0-9@:%._\+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%_\+.~#?&//=]*)/g; -const DEFAULT_FETCH_OPTIONS: any = { - redirect: "follow", - follow: 1, - headers: { - "user-agent": - "Mozilla/5.0 (compatible; Fosscord/1.0; +https://github.com/fosscord/fosscord)", - }, - // size: 1024 * 1024 * 5, // grabbed from config later - compress: true, - method: "GET", -}; - export async function handleMessage(opts: MessageOptions): Promise<Message> { const channel = await Channel.findOneOrFail({ where: { id: opts.channel_id }, @@ -200,124 +187,24 @@ export async function postHandleMessage(message: Message) { links = links.slice(0, 20) as RegExpMatchArray; // embed max 20 links — TODO: make this configurable with instance policies - const { endpointPublic, resizeWidthMax, resizeHeightMax } = - Config.get().cdn; - for (const link of links) { - try { - const request = await fetch(link, { - ...DEFAULT_FETCH_OPTIONS, - size: Config.get().limits.message.maxEmbedDownloadSize, - }); - - let embed: Embed; - - const type = request.headers.get("content-type"); - if (type?.indexOf("image") == 0) { - embed = { - provider: { - url: link, - name: new URL(link).hostname, - }, - image: { - // can't be bothered rn - proxy_url: `${endpointPublic}/external/resize/${encodeURIComponent( - link, - )}?width=500&height=400`, - url: link, - width: 500, - height: 400, - }, - }; - data.embeds.push(embed); - } else { - const text = await request.text(); - const $ = cheerio.load(text); - - const title = $('meta[property="og:title"]').attr("content"); - const provider_name = $('meta[property="og:site_name"]').text(); - const author_name = $('meta[property="article:author"]').attr( - "content", - ); - const description = - $('meta[property="og:description"]').attr("content") || - $('meta[property="description"]').attr("content"); + let embed: Embed; + const url = new URL(link); - const image = $('meta[property="og:image"]').attr("content"); - const width = - parseInt( - $('meta[property="og:image:width"]').attr("content") || - "", - ) || undefined; - const height = - parseInt( - $('meta[property="og:image:height"]').attr("content") || - "", - ) || undefined; + // bit gross, but whatever! + const { endpointPublic } = Config.get().cdn; + const handler = url.hostname == new URL(endpointPublic!).hostname ? EmbedHandlers["self"] : EmbedHandlers[url.hostname] || EmbedHandlers["default"]; - const url = $('meta[property="og:url"]').attr("content"); - // TODO: color - embed = { - provider: { - url: link, - name: provider_name, - }, - }; - - const resizeWidth = Math.min(resizeWidthMax ?? 1, width ?? 100); - const resizeHeight = Math.min( - resizeHeightMax ?? 1, - height ?? 100, - ); - if (author_name) embed.author = { name: author_name }; - if (image) - embed.thumbnail = { - proxy_url: `${endpointPublic}/external/resize/${encodeURIComponent( - image, - )}?width=${resizeWidth}&height=${resizeHeight}`, - url: image, - width: width, - height: height, - }; - if (title) embed.title = title; - if (url) embed.url = url; - if (description) embed.description = description; - - const approvedProviders = [ - "media4.giphy.com", - "c.tenor.com", - // todo: make configurable? don't really care tho - ]; - - // very bad code below - // don't care lol - if ( - embed?.thumbnail?.url && - approvedProviders.indexOf( - new URL(embed.thumbnail.url).hostname, - ) !== -1 - ) { - embed = { - provider: { - url: link, - name: new URL(link).hostname, - }, - image: { - proxy_url: `${endpointPublic}/external/resize/${encodeURIComponent( - image!, - )}?width=${resizeWidth}&height=${resizeHeight}`, - url: image, - width: width, - height: height, - }, - }; - } + try { + const res = await handler(url); + if (!res) continue; + embed = res; + } + catch (e) { + continue; + } - if (title || description) { - data.embeds.push(embed); - } - } - } catch (error) { } + data.embeds.push(embed); } await Promise.all([ |