tuberepair/src/api/channel.ts
2025-12-22 10:01:19 +02:00

65 lines
1.9 KiB
TypeScript

import { zValidator } from "@hono/zod-validator";
import innertube from "../lib/innertube.js";
import { ChannelFindSchema } from "../models/ChannelFindSchema.js";
import { Hono } from "hono";
import channelData from "../templates/channelData.js";
import { parseSubscriberCount } from "../lib/channel.js";
import { YTNodes } from "youtubei.js";
const channel = new Hono();
channel.get(
"/channels/:id",
zValidator("param", ChannelFindSchema),
async (c) => {
const { id } = c.req.valid("param");
try {
const data = await innertube.getChannel(id);
const { header } = data;
if (!header) {
return c.text("Channel not found", 404);
}
const channelInfo = header.is(YTNodes.PageHeader)
? {
name: header.page_title,
description: header.content?.description?.description?.text || "",
thumbnail: (header.content?.image as YTNodes.DecoratedAvatarView)
?.avatar?.image?.[0]?.url || "",
subCount: parseSubscriberCount(
header.content?.metadata?.metadata_rows?.[1]
?.metadata_parts?.[0]?.text?.text || "0"
),
}
: header.is(YTNodes.C4TabbedHeader)
? {
name: header.author?.name || "",
description: data.metadata?.description || "",
thumbnail: header.author?.best_thumbnail?.url || "",
subCount: parseSubscriberCount(header.subscribers?.text || "0"),
}
: null;
if (!channelInfo) {
return c.text("Channel not found", 404);
}
return c.html(
channelData(
id,
channelInfo.name,
channelInfo.subCount,
channelInfo.description,
channelInfo.thumbnail
)
);
} catch (err) {
console.error("Error fetching channel:", err);
return c.text("Channel not found", 404);
}
}
);
export default channel