diff --git a/apps/electron/src/main/ui/handlers.ts b/apps/electron/src/main/ui/handlers.ts index 607ae69b2e..271a139643 100644 --- a/apps/electron/src/main/ui/handlers.ts +++ b/apps/electron/src/main/ui/handlers.ts @@ -2,6 +2,7 @@ import { app, BrowserWindow, nativeTheme } from 'electron'; import { getLinkPreview } from 'link-preview-js'; import { isMacOS } from '../../shared/utils'; +import { logger } from '../logger'; import type { NamespaceHandlers } from '../type'; import { getGoogleOauthCode } from './google-auth'; @@ -45,29 +46,59 @@ export const uiHandlers = { return getGoogleOauthCode(); }, getBookmarkDataByLink: async (_, link: string) => { - const previewData = (await getLinkPreview(link, { - timeout: 6000, - headers: { - 'user-agent': 'googlebot', - }, - followRedirects: 'follow', - }).catch(() => { - return { - title: '', - siteName: '', - description: '', - images: [], - videos: [], - contentType: `text/html`, - favicons: [], - }; - })) as any; + if ( + (link.startsWith('https://x.com/') || + link.startsWith('https://www.x.com/') || + link.startsWith('https://www.twitter.com/') || + link.startsWith('https://twitter.com/')) && + link.includes('/status/') + ) { + // use api.fxtwitter.com + link = + 'https://api.fxtwitter.com/status/' + /\/status\/(.*)/.exec(link)?.[1]; + try { + const { tweet } = await fetch(link).then(res => res.json()); + return { + title: tweet.author.name, + icon: tweet.author.avatar_url, + description: tweet.text, + image: tweet.media?.photos[0].url || tweet.author.banner_url, + }; + } catch (err) { + logger.error('getBookmarkDataByLink', err); + return { + title: undefined, + description: undefined, + icon: undefined, + image: undefined, + }; + } + } else { + const previewData = (await getLinkPreview(link, { + timeout: 6000, + headers: { + 'User-Agent': + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36', + }, + followRedirects: 'follow', + }).catch(() => { + return { + title: '', + siteName: '', + description: '', + images: [], + videos: [], + contentType: `text/html`, + favicons: [], + }; + })) as any; - return { - title: previewData.title, - description: previewData.description, - icon: previewData.favicons[0], - image: previewData.images[0], - }; + return { + title: previewData.title, + description: previewData.description, + icon: previewData.favicons[0], + image: previewData.images[0], + }; + } }, } satisfies NamespaceHandlers;