diff --git a/src/LinkThumbnailWidgetParams.ts b/src/LinkThumbnailWidgetParams.ts index ac22cb8..4aae77a 100644 --- a/src/LinkThumbnailWidgetParams.ts +++ b/src/LinkThumbnailWidgetParams.ts @@ -1,28 +1,32 @@ import { requestUrl } from "obsidian"; import { decode } from 'iconv-lite'; +interface ogData { + "ogTitle": string, + "ogDescription": string, + "ogImage": string, + "ogImageAlt": string, + "ogUrl": string +} + // url 정규식 const urlRegex = new RegExp("^(http:\\/\\/www\\.|https:\\/\\/www\\.|http:\\/\\/|https:\\/\\/)?[a-z0-9]+([\\-.]{1}[a-z0-9]+)*\\.[a-z]{2,5}(:[0-9]{1,5})?(\\/.*)?$"); -export async function LinkThumbnailWidgetParams(url: string) { +async function getOgData(url: string) { const urlArr = urlRegex.exec(url); if (urlArr) { try { - - const response = await requestUrl({ - url:url, - throw: true - }); + const response = await requestUrl(url); if (response && response.headers && response.headers['content-type'] && !response.headers['content-type']?.includes('text/')) { throw new Error('Page must return a header content-type with text/'); } // 인코딩 문제 해결 - const bodyArrayBuffer = response.arrayBuffer; - const charset = response.headers["content-type"].replace("text/html;charset=","").toLowerCase(); - + const bodyArrayBuffer = response.arrayBuffer; + const contentType = response.headers["content-type"].toLowerCase().trim(); + const charset = contentType.substring(contentType.indexOf("charset=") + 8, contentType.length); let body; - if (charset.trim() === "utf-8") { + if (charset === "utf-8") { body = Buffer.from(bodyArrayBuffer).toString('utf-8'); } else { body = decode(Buffer.from(bodyArrayBuffer), charset); @@ -41,20 +45,39 @@ export async function LinkThumbnailWidgetParams(url: string) { const ogImageAlt = document.querySelector("meta[property='og:image:alt']")?.getAttribute("content") || ""; const ogUrl = document.querySelector("meta[property='og:url']")?.getAttribute("content") || url; - const result = ` -
- ${(ogImage === "")? "" : ``} - -
- ` - return result; + const data: ogData = { + "ogTitle": ogTitle, + "ogDescription": ogDescription, + "ogImage": ogImage, + "ogImageAlt": ogImageAlt, + "ogUrl": ogUrl + } + + return data; } catch (error) { - throw new Error(error); + console.error(error); } } - return null +} + +function renderOgData(data:ogData) { + return ` +
+ ${(data?.ogImage === "")? "" : ``} + +
+ `; +} + +export async function LinkThumbnailWidgetParams(url: string) { + const data = await getOgData(url); + if (data) { + const result = renderOgData(data); + return result; + } + return null; }