| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354 |
- // Fetches the public Telegram channel feed (t.me/s/...) and saves the latest
- // posts for the home-page Telegram widget. Run manually: npm run fetch-news
- import * as cheerio from "cheerio";
- import { mkdir, writeFile } from "node:fs/promises";
- import path from "node:path";
- const CHANNEL = "scientia_ru";
- const UA =
- "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36";
- const res = await fetch(`https://t.me/s/${CHANNEL}`, { headers: { "User-Agent": UA } });
- if (!res.ok) {
- console.error(`Failed to fetch channel: HTTP ${res.status}`);
- process.exit(1);
- }
- const $ = cheerio.load(await res.text());
- const posts = [];
- $(".tgme_widget_message").each((_, el) => {
- const $el = $(el);
- const textNode = $el.find(".tgme_widget_message_text").first();
- // Keep basic formatting tags, drop telegram-internal spans/attrs
- textNode.find("a, b, i, u, s, strong, em, code, br").each((__, keep) => {
- const attrs = $(keep).attr() || {};
- for (const name of Object.keys(attrs)) {
- if (name !== "href") $(keep).removeAttr(name);
- }
- });
- const text = textNode.html()?.trim() || "";
- const datetime = $el.find("time").first().attr("datetime") || "";
- const photoStyle = $el.find(".tgme_widget_message_photo_wrap").first().attr("style") || "";
- const photo = photoStyle.match(/url\('([^']+)'\)/)?.[1]?.split("?")[0] || "";
- const link = $el.find(".tgme_widget_message_date").first().attr("href") || `https://t.me/${CHANNEL}`;
- if (text || photo) posts.push({ text, datetime, photo, link });
- });
- const latest = posts.slice(-4).reverse();
- await mkdir(path.dirname("src/data/telegram-news.json"), { recursive: true });
- await writeFile("src/data/telegram-news.json", JSON.stringify(latest, null, 2));
- console.log(`saved ${latest.length} posts`);
- // Channel avatar for the widget header
- const avatar = await fetch(`https://t.me/i/userpic/320/${CHANNEL}.jpg`, { headers: { "User-Agent": UA } });
- if (avatar.ok) {
- const buf = Buffer.from(await avatar.arrayBuffer());
- if (buf.length > 500) {
- await writeFile("public/images/telegram-avatar.jpg", buf);
- console.log("avatar saved");
- } else {
- console.log("avatar looks empty, skipped");
- }
- } else {
- console.log(`avatar fetch failed: HTTP ${avatar.status}`);
- }
|