Fixes embed links for twitter and tiktok (#74)
parent
d4b9ef3b0a
commit
2fce1637b4
File diff suppressed because one or more lines are too long
|
@ -1,6 +1,7 @@
|
||||||
import {extractHtmlMeta} from '../../src/lib/extractHtmlMeta'
|
import {extractHtmlMeta} from '../../src/lib/extractHtmlMeta'
|
||||||
import {exampleComHtml} from './__mocks__/exampleComHtml'
|
import {exampleComHtml} from './__mocks__/exampleComHtml'
|
||||||
import {youtubeHTML} from './__mocks__/youtubeHtml'
|
import {youtubeHTML} from './__mocks__/youtubeHtml'
|
||||||
|
import {tiktokHtml} from './__mocks__/tiktokHtml'
|
||||||
|
|
||||||
describe('extractHtmlMeta', () => {
|
describe('extractHtmlMeta', () => {
|
||||||
const cases = [
|
const cases = [
|
||||||
|
@ -56,6 +57,18 @@ describe('extractHtmlMeta', () => {
|
||||||
expect(output).toEqual(expectedOutput)
|
expect(output).toEqual(expectedOutput)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it('extracts title and description from a Tiktok HTML page', () => {
|
||||||
|
const input = tiktokHtml
|
||||||
|
const expectedOutput = {
|
||||||
|
title:
|
||||||
|
'Coca-Cola and Mentos! Super Reaction! #cocacola #mentos #reaction #bal... | TikTok',
|
||||||
|
description:
|
||||||
|
'5.5M Likes, 20.8K Comments. TikTok video from Power Vision Tests (@_powervision_): "Coca-Cola and Mentos! Super Reaction! #cocacola #mentos #reaction #balloon #sciencemoment #scienceexperiment #experiment #test #amazing #pvexp". оригинальный звук - Power Vision Tests.',
|
||||||
|
}
|
||||||
|
const output = extractHtmlMeta({html: input, hostname: 'tiktok.com'})
|
||||||
|
expect(output).toEqual(expectedOutput)
|
||||||
|
})
|
||||||
|
|
||||||
it('extracts title and description from a generic youtube page', () => {
|
it('extracts title and description from a generic youtube page', () => {
|
||||||
const input = youtubeHTML
|
const input = youtubeHTML
|
||||||
const expectedOutput = {
|
const expectedOutput = {
|
||||||
|
@ -67,4 +80,37 @@ describe('extractHtmlMeta', () => {
|
||||||
const output = extractHtmlMeta({html: input, hostname: 'youtube.com'})
|
const output = extractHtmlMeta({html: input, hostname: 'youtube.com'})
|
||||||
expect(output).toEqual(expectedOutput)
|
expect(output).toEqual(expectedOutput)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it('extracts username from the url a twitter profile page', () => {
|
||||||
|
const expectedOutput = {
|
||||||
|
title: '@bluesky on Twitter',
|
||||||
|
}
|
||||||
|
const output = extractHtmlMeta({
|
||||||
|
hostname: 'twitter.com',
|
||||||
|
pathname: '/bluesky',
|
||||||
|
})
|
||||||
|
expect(output).toEqual(expectedOutput)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('extracts username from the url a tweet', () => {
|
||||||
|
const expectedOutput = {
|
||||||
|
title: 'Tweet by @bluesky',
|
||||||
|
}
|
||||||
|
const output = extractHtmlMeta({
|
||||||
|
hostname: 'twitter.com',
|
||||||
|
pathname: '/bluesky/status/1582437529969917953',
|
||||||
|
})
|
||||||
|
expect(output).toEqual(expectedOutput)
|
||||||
|
})
|
||||||
|
|
||||||
|
it("does not extract username from the url when it's not a tweet or profile page", () => {
|
||||||
|
const expectedOutput = {
|
||||||
|
title: 'Twitter',
|
||||||
|
}
|
||||||
|
const output = extractHtmlMeta({
|
||||||
|
hostname: 'twitter.com',
|
||||||
|
pathname: '/i/articles/follows/-1675653703?time_window=24',
|
||||||
|
})
|
||||||
|
expect(output).toEqual(expectedOutput)
|
||||||
|
})
|
||||||
})
|
})
|
|
@ -1,15 +1,18 @@
|
||||||
|
import {extractTwitterMeta} from './extractTwitterMeta'
|
||||||
import {extractYoutubeMeta} from './extractYoutubeMeta'
|
import {extractYoutubeMeta} from './extractYoutubeMeta'
|
||||||
|
|
||||||
interface ExtractHtmlMetaInput {
|
interface ExtractHtmlMetaInput {
|
||||||
html: string
|
html: string
|
||||||
hostname?: string
|
hostname?: string
|
||||||
|
pathname?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
export const extractHtmlMeta = ({
|
export const extractHtmlMeta = ({
|
||||||
html,
|
html,
|
||||||
hostname,
|
hostname,
|
||||||
|
pathname,
|
||||||
}: ExtractHtmlMetaInput): Record<string, string> => {
|
}: ExtractHtmlMetaInput): Record<string, string> => {
|
||||||
const htmlTitleRegex = /<title>([^<]+)<\/title>/i
|
const htmlTitleRegex = /<title.*>([^<]+)<\/title>/i
|
||||||
|
|
||||||
let res: Record<string, string> = {}
|
let res: Record<string, string> = {}
|
||||||
|
|
||||||
|
@ -56,9 +59,12 @@ export const extractHtmlMeta = ({
|
||||||
|
|
||||||
const isYoutubeUrl =
|
const isYoutubeUrl =
|
||||||
hostname?.includes('youtube.') || hostname?.includes('youtu.be')
|
hostname?.includes('youtube.') || hostname?.includes('youtu.be')
|
||||||
|
const isTwitterUrl = hostname?.includes('twitter.')
|
||||||
|
// Workaround for some websites not having a title or description in the meta tags in the initial serve
|
||||||
if (isYoutubeUrl) {
|
if (isYoutubeUrl) {
|
||||||
// Workaround for Youtube not having a title in the meta tags
|
|
||||||
res = {...res, ...extractYoutubeMeta(html)}
|
res = {...res, ...extractYoutubeMeta(html)}
|
||||||
|
} else if (isTwitterUrl) {
|
||||||
|
res = {...extractTwitterMeta({pathname})}
|
||||||
}
|
}
|
||||||
|
|
||||||
return res
|
return res
|
||||||
|
|
|
@ -0,0 +1,20 @@
|
||||||
|
export const extractTwitterMeta = ({
|
||||||
|
pathname,
|
||||||
|
}: {
|
||||||
|
pathname: string
|
||||||
|
}): Record<string, string> => {
|
||||||
|
const res = {title: 'Twitter'}
|
||||||
|
const parsedPathname = pathname.split('/')
|
||||||
|
if (parsedPathname.length <= 1 || parsedPathname[1].length <= 1) {
|
||||||
|
// Excluding one letter usernames as they're reserved by twitter for things like cases like twitter.com/i/articles/follows/-1675653703
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
const username = parsedPathname?.[1]
|
||||||
|
const isUserProfile = parsedPathname?.length === 2
|
||||||
|
|
||||||
|
res.title = isUserProfile
|
||||||
|
? `@${username} on Twitter`
|
||||||
|
: `Tweet by @${username}`
|
||||||
|
|
||||||
|
return res
|
||||||
|
}
|
|
@ -63,6 +63,7 @@ export async function getLinkMeta(
|
||||||
const httpResMeta = extractHtmlMeta({
|
const httpResMeta = extractHtmlMeta({
|
||||||
html: httpResBody,
|
html: httpResBody,
|
||||||
hostname: urlp?.hostname,
|
hostname: urlp?.hostname,
|
||||||
|
pathname: urlp?.pathname,
|
||||||
})
|
})
|
||||||
meta.title = httpResMeta.title ? he.decode(httpResMeta.title) : undefined
|
meta.title = httpResMeta.title ? he.decode(httpResMeta.title) : undefined
|
||||||
meta.description = httpResMeta.description
|
meta.description = httpResMeta.description
|
||||||
|
|
Loading…
Reference in New Issue