|
|
|
|
@ -1,5 +1,12 @@ |
|
|
|
|
import type { OEmbedUrlContentResult, OEmbedUrlWithMetadata, IMessage, MessageAttachment, OEmbedMeta } from '@rocket.chat/core-typings'; |
|
|
|
|
import { isOEmbedUrlContentResult, isOEmbedUrlWithMetadata } from '@rocket.chat/core-typings'; |
|
|
|
|
import type { |
|
|
|
|
OEmbedUrlContentResult, |
|
|
|
|
OEmbedUrlWithMetadata, |
|
|
|
|
IMessage, |
|
|
|
|
MessageAttachment, |
|
|
|
|
OEmbedMeta, |
|
|
|
|
MessageUrl, |
|
|
|
|
} from '@rocket.chat/core-typings'; |
|
|
|
|
import { isOEmbedUrlWithMetadata } from '@rocket.chat/core-typings'; |
|
|
|
|
import { Logger } from '@rocket.chat/logger'; |
|
|
|
|
import { Messages, OEmbedCache } from '@rocket.chat/models'; |
|
|
|
|
import { serverFetch as fetch } from '@rocket.chat/server-fetch'; |
|
|
|
|
@ -128,6 +135,41 @@ const getUrlContent = async (urlObj: URL, redirectCount = 5): Promise<OEmbedUrlC |
|
|
|
|
}; |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
const parseUrl = async function (url: string): Promise<{ urlPreview: MessageUrl; foundMeta: boolean }> { |
|
|
|
|
const parsedUrlObject: MessageUrl = { url, meta: {} }; |
|
|
|
|
let foundMeta = false; |
|
|
|
|
if (!isURL(url)) { |
|
|
|
|
return { urlPreview: parsedUrlObject, foundMeta }; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
const data = await getUrlMetaWithCache(url); |
|
|
|
|
if (!data) { |
|
|
|
|
return { urlPreview: parsedUrlObject, foundMeta }; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (isOEmbedUrlWithMetadata(data) && data.meta) { |
|
|
|
|
parsedUrlObject.meta = getRelevantMetaTags(data.meta) || {}; |
|
|
|
|
if (parsedUrlObject.meta?.oembedHtml) { |
|
|
|
|
parsedUrlObject.meta.oembedHtml = insertMaxWidthInOembedHtml(parsedUrlObject.meta.oembedHtml) || ''; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
foundMeta = true; |
|
|
|
|
return { |
|
|
|
|
urlPreview: { |
|
|
|
|
...parsedUrlObject, |
|
|
|
|
...((parsedUrlObject.headers || data.headers) && { |
|
|
|
|
headers: { |
|
|
|
|
...parsedUrlObject.headers, |
|
|
|
|
...(data.headers?.contentLength && { contentLength: data.headers.contentLength }), |
|
|
|
|
...(data.headers?.contentType && { contentType: data.headers.contentType }), |
|
|
|
|
}, |
|
|
|
|
}), |
|
|
|
|
}, |
|
|
|
|
foundMeta, |
|
|
|
|
}; |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
const getUrlMeta = async function ( |
|
|
|
|
url: string, |
|
|
|
|
withFragment?: boolean, |
|
|
|
|
@ -151,10 +193,6 @@ const getUrlMeta = async function ( |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (content.attachments) { |
|
|
|
|
return content; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
log.debug('Parsing metadata for URL', url); |
|
|
|
|
const metas: { [k: string]: string } = {}; |
|
|
|
|
|
|
|
|
|
@ -273,37 +311,10 @@ const rocketUrlParser = async function (message: IMessage): Promise<IMessage> { |
|
|
|
|
continue; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (!isURL(item.url)) { |
|
|
|
|
continue; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
const data = await getUrlMetaWithCache(item.url); |
|
|
|
|
|
|
|
|
|
if (!data) { |
|
|
|
|
continue; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (isOEmbedUrlContentResult(data) && data.attachments) { |
|
|
|
|
attachments.push(...data.attachments); |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (isOEmbedUrlWithMetadata(data) && data.meta) { |
|
|
|
|
item.meta = getRelevantMetaTags(data.meta) || {}; |
|
|
|
|
if (item.meta?.oembedHtml) { |
|
|
|
|
item.meta.oembedHtml = insertMaxWidthInOembedHtml(item.meta.oembedHtml) || ''; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (data.headers?.contentLength) { |
|
|
|
|
item.headers = { ...item.headers, contentLength: data.headers.contentLength }; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (data.headers?.contentType) { |
|
|
|
|
item.headers = { ...item.headers, contentType: data.headers.contentType }; |
|
|
|
|
} |
|
|
|
|
const { urlPreview, foundMeta } = await parseUrl(item.url); |
|
|
|
|
|
|
|
|
|
changed = true; |
|
|
|
|
Object.assign(item, foundMeta ? urlPreview : {}); |
|
|
|
|
changed = changed || foundMeta; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (attachments.length) { |
|
|
|
|
@ -321,10 +332,12 @@ const OEmbed: { |
|
|
|
|
getUrlMeta: (url: string, withFragment?: boolean) => Promise<OEmbedUrlWithMetadata | undefined | OEmbedUrlContentResult>; |
|
|
|
|
getUrlMetaWithCache: (url: string, withFragment?: boolean) => Promise<OEmbedUrlWithMetadata | OEmbedUrlContentResult | undefined>; |
|
|
|
|
rocketUrlParser: (message: IMessage) => Promise<IMessage>; |
|
|
|
|
parseUrl: (url: string) => Promise<{ urlPreview: MessageUrl; foundMeta: boolean }>; |
|
|
|
|
} = { |
|
|
|
|
rocketUrlParser, |
|
|
|
|
getUrlMetaWithCache, |
|
|
|
|
getUrlMeta, |
|
|
|
|
parseUrl, |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
settings.watch('API_Embed', (value) => { |
|
|
|
|
|