better cards
This commit is contained in:
@@ -6,11 +6,26 @@ type YoutubeApiVideo = {
|
||||
id: string;
|
||||
url: string;
|
||||
title: string;
|
||||
summary?: string;
|
||||
publishedAt: string;
|
||||
thumbnailUrl?: string;
|
||||
views?: number;
|
||||
};
|
||||
|
||||
function stripHtml(s: string) {
|
||||
return (s || "")
|
||||
.replace(/<[^>]+>/g, " ")
|
||||
.replace(/\s+/g, " ")
|
||||
.trim();
|
||||
}
|
||||
|
||||
function truncate(s: string, n: number) {
|
||||
const t = stripHtml(s);
|
||||
if (!t) return "";
|
||||
if (t.length <= n) return t;
|
||||
return `${t.slice(0, Math.max(0, n - 1)).trimEnd()}…`;
|
||||
}
|
||||
|
||||
export async function fetchYoutubeViaRss(channelId: string, limit = 20): Promise<ContentItem[]> {
|
||||
const feedUrl = `https://www.youtube.com/feeds/videos.xml?channel_id=${encodeURIComponent(channelId)}`;
|
||||
const parser = new Parser();
|
||||
@@ -32,11 +47,16 @@ export function normalizeYoutubeRssFeedItems(items: any[], limit: number): Conte
|
||||
const url = it.link || "";
|
||||
const id = (it.id || url).toString();
|
||||
const publishedAt = (it.isoDate || it.pubDate || new Date(0).toISOString()).toString();
|
||||
const summary = truncate(
|
||||
(it.contentSnippet || it.summary || it.content || it["content:encoded"] || "").toString(),
|
||||
240,
|
||||
);
|
||||
return {
|
||||
id,
|
||||
source: "youtube" as const,
|
||||
url,
|
||||
title: (it.title || "").toString(),
|
||||
summary: summary || undefined,
|
||||
publishedAt: new Date(publishedAt).toISOString(),
|
||||
thumbnailUrl: (it.enclosure?.url || undefined) as string | undefined,
|
||||
};
|
||||
@@ -47,7 +67,12 @@ export function normalizeYoutubeRssFeedItems(items: any[], limit: number): Conte
|
||||
export function normalizeYoutubeApiVideos(
|
||||
items: Array<{
|
||||
id: string;
|
||||
snippet: { title: string; publishedAt: string; thumbnails?: Record<string, { url: string }> };
|
||||
snippet: {
|
||||
title: string;
|
||||
description?: string;
|
||||
publishedAt: string;
|
||||
thumbnails?: Record<string, { url: string }>;
|
||||
};
|
||||
statistics?: { viewCount?: string };
|
||||
}>,
|
||||
): ContentItem[] {
|
||||
@@ -55,6 +80,7 @@ export function normalizeYoutubeApiVideos(
|
||||
id: v.id,
|
||||
url: `https://www.youtube.com/watch?v=${encodeURIComponent(v.id)}`,
|
||||
title: v.snippet.title,
|
||||
summary: v.snippet.description ? truncate(v.snippet.description, 240) : undefined,
|
||||
publishedAt: new Date(v.snippet.publishedAt).toISOString(),
|
||||
thumbnailUrl: v.snippet.thumbnails?.high?.url || v.snippet.thumbnails?.default?.url,
|
||||
views: v.statistics?.viewCount ? Number(v.statistics.viewCount) : undefined,
|
||||
@@ -65,6 +91,7 @@ export function normalizeYoutubeApiVideos(
|
||||
source: "youtube",
|
||||
url: v.url,
|
||||
title: v.title,
|
||||
summary: v.summary,
|
||||
publishedAt: v.publishedAt,
|
||||
thumbnailUrl: v.thumbnailUrl,
|
||||
metrics: v.views !== undefined ? { views: v.views } : undefined,
|
||||
|
||||
Reference in New Issue
Block a user