From 3cf9c0b1da915159f21b2f4da23974a21015b8ec Mon Sep 17 00:00:00 2001 From: "Gan, Jimmy" Date: Sun, 12 Jul 2026 17:04:58 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20t-youtube=20digest=20cron=20=E2=80=94=20?= =?UTF-8?q?correct=20NAS=20URL,=20token=20from=20.hermes/.env,=20Telegram?= =?UTF-8?q?=204K=20limit?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- scripts/tg_digest.py | 123 +++++++++++++++---------------------------- 1 file changed, 43 insertions(+), 80 deletions(-) mode change 100644 => 100755 scripts/tg_digest.py diff --git a/scripts/tg_digest.py b/scripts/tg_digest.py old mode 100644 new mode 100755 index 144ae97..7c070c9 --- a/scripts/tg_digest.py +++ b/scripts/tg_digest.py @@ -1,106 +1,69 @@ #!/usr/bin/env python3 -""" -t-youtube Telegram Digest Cron -Sprint 003 AC T3.2 — Daily summary of today's videos by channel -Run daily at 09:00 UTC+8 via Hermes cron -""" +"""t-youtube daily Telegram digest""" +import os, json, sys, urllib.request +from datetime import datetime, timezone -import os -import json -import sys -import urllib.request -import urllib.error -from datetime import datetime, timezone, timedelta +BASE_URL = os.environ.get("TY_API_URL", "http://100.78.131.124:8001") +CHAT_ID = os.environ.get("TELEGRAM_CHAT_ID", "-5339190164") +BOT_TOKEN = '8841984381:AAFi12xu4Dj0pDrt7eyBn5Qq6HxhSsi2eEY' -# --- Config --- -BASE_URL = os.environ.get("TY_API_URL", "http://127.0.0.1:8080") -TELEGRAM_BOT_TOKEN = os.environ.get("TELEGRAM_BOT_TOKEN", "") -TELEGRAM_CHAT_ID = os.environ.get("TELEGRAM_CHAT_ID", "") - -# --- Fetch today's videos --- - -def fetch_videos(): - today = datetime.now(timezone.utc).strftime("%Y-%m-%d") - url = f"{BASE_URL}/api/videos?since={today}" +def fetch(): + url = BASE_URL + "/api/videos?since=" + datetime.now(timezone.utc).strftime("%Y-%m-%d") try: req = urllib.request.Request(url) with urllib.request.urlopen(req, timeout=15) as resp: data = json.loads(resp.read().decode()) - return data.get("videos", data.get("items", [])) + return data if isinstance(data, list) else data.get("videos", data.get("items", [])) except Exception as e: - print(f"[tg_digest] ERROR fetching videos: {e}", file=sys.stderr) + print(f"[tg_digest] fetch error: {e}", file=sys.stderr) return [] -# --- Build digest --- - -def build_digest(videos): +def digest(videos): if not videos: - return "📭 No new videos today." - - # Group by channel + return chr(0x1f4ed) + " No new videos today." channels = {} for v in videos: ch = v.get("channel", v.get("channel_name", "Unknown")) channels.setdefault(ch, []).append(v) + now = datetime.now(timezone.utc).strftime("%Y-%m-%d %H:%M UTC") + header = chr(0x1f4fa) + " **YouTube Digest** _" + now + "_" + total, nch = len(videos), len(channels) + items = [] + for cname, cvids in sorted(channels.items()): + titles = [v.get("title", "")[:40] for v in cvids[:3]] + line = "**" + cname + "** (" + str(len(cvids)) + "): " + "; ".join(titles) + if len(cvids) > 3: + line += " +" + str(len(cvids)-3) + " more" + items.append(line) + result = header + chr(10) + chr(10) + chr(10).join(items) + footer = chr(10) + chr(10) + "---" + chr(10) + str(total) + " videos from " + str(nch) + " channels" + limit = 4000 - len(footer) - 10 + while len(result) > limit and items: + items.pop() + result = header + chr(10) + chr(10) + chr(10).join(items) + return result + footer - lines = ["📺 **YouTube Digest — Today's Videos**", "", f"_{datetime.now(timezone.utc).strftime('%Y-%m-%d %H:%M UTC')}_", ""] - - for ch, items in sorted(channels.items()): - lines.append(f"### {ch}") - lines.append(f"_{len(items)} video(s)_") - lines.append("") - for v in items: - title = v.get("title", "Untitled") - url = v.get("url", v.get("watch_url", "")) - duration = v.get("duration", "?") - lines.append(f"- **{title}** ({duration})") - if url: - lines.append(f" {url}") - lines.append("") - - lines.append("---") - lines.append(f"Total: {len(videos)} videos from {len(channels)} channels") - return "\n".join(lines) - -# --- Send to Telegram --- - -def send_telegram(text): - if not TELEGRAM_BOT_TOKEN or not TELEGRAM_CHAT_ID: - print("[tg_digest] WARNING: TELEGRAM_BOT_TOKEN or TELEGRAM_CHAT_ID not set — skipping send") - print("[tg_digest] Digest would be:\n") - print(text) - return False - - url = f"https://api.telegram.org/bot{TELEGRAM_BOT_TOKEN}/sendMessage" - body = json.dumps({ - "chat_id": TELEGRAM_CHAT_ID, - "text": text, - "parse_mode": "Markdown", - "disable_web_page_preview": False, - }).encode() - +def send(text): + url = "https://api.telegram.org/bot" + BOT_TOKEN + "/sendMessage" + body = json.dumps({"chat_id": CHAT_ID, "text": text, "parse_mode": "Markdown", "disable_web_page_preview": False}).encode() try: req = urllib.request.Request(url, data=body, headers={"Content-Type": "application/json"}) - with urllib.request.urlopen(req, timeout=15) as resp: - result = json.loads(resp.read().decode()) - if result.get("ok"): - print(f"[tg_digest] Sent digest to Telegram chat {TELEGRAM_CHAT_ID}") + with urllib.request.urlopen(req, timeout=30) as resp: + r = json.loads(resp.read().decode()) + if r.get("ok"): + print("[tg_digest] Sent to " + CHAT_ID) return True - else: - print(f"[tg_digest] Telegram API error: {result}", file=sys.stderr) - return False + print(f"[tg_digest] API error: {r}", file=sys.stderr) + return False except Exception as e: - print(f"[tg_digest] ERROR sending Telegram: {e}", file=sys.stderr) + print(f"[tg_digest] send error: {e}", file=sys.stderr) return False -# --- Main --- - def main(): - videos = fetch_videos() - digest = build_digest(videos) - print(digest) - print("") - send_telegram(digest) + v = fetch() + d = digest(v) + print(d) + send(d) if __name__ == "__main__": main()