65 lines
1.9 KiB
TypeScript
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 |