Skip to content

Instantly share code, notes, and snippets.

@vpnry
Created April 10, 2026 15:33
Show Gist options
  • Select an option

  • Save vpnry/c18f3c1299460bf064f72268d737e3c5 to your computer and use it in GitHub Desktop.

Select an option

Save vpnry/c18f3c1299460bf064f72268d737e3c5 to your computer and use it in GitHub Desktop.
Openclaw - Get top 20 HN News and Send to your Telegram
import requests, time, html
from datetime import datetime
from zoneinfo import ZoneInfo
from urllib.parse import urlparse
TELEGRAM_TOKEN = "bot token"
CHAT_ID = "Enter Telegram ID"
HN = "https://hacker-news.firebaseio.com/v0"
def get_json(path):
return requests.get(f"{HN}/{path}.json", timeout=10).json()
def start_of_today_vn():
tz = ZoneInfo("Asia/Bangkok")
now = datetime.now(tz)
start = now.replace(hour=0, minute=0, second=0, microsecond=0)
return int(start.timestamp())
def time_ago(ts):
diff = int(time.time() - ts)
if diff < 3600: return f"{diff//60}m"
if diff < 86400: return f"{diff//3600}h"
return f"{diff//86400}d"
def main():
start_ts = start_of_today_vn()
ids = get_json("topstories")[:200]
stories = []
for i in ids:
item = get_json(f"item/{i}")
if not item or item.get("type")!= "story":
continue
if item.get("time", 0) < start_ts:
continue
stories.append(item)
if len(stories) >= 40:
break
top20 = sorted(stories, key=lambda x: x.get("score", 0), reverse=True)[:20]
lines = []
n = 0
for s in top20:
title = html.escape(s.get("title", ""))
url = s.get("url") or f"https://news.ycombinator.com/item?id={s['id']}"
score = s.get("score", 0)
by = s.get("by", "")
t = time_ago(s.get("time", 0))
# format: [Tiêu đề] (domain) [điểm] by [tác giả] [thời gian] - nhưng tiêu đề là link
n += 1
lines.append(
f'{n}. <a href="{url}">{html.escape(title)}</a> {t} ago. Score: {score} by {by}\n'
)
now_vn = datetime.now(ZoneInfo("Asia/Bangkok")).strftime("%d/%m %H:%M")
text = f"🔥 <b>HN Top 20 hôm nay ({now_vn} VN)</b>\n\n" + "\n".join(lines)
requests.post(
f"https://api.telegram.org/bot{TELEGRAM_TOKEN}/sendMessage",
json={
"chat_id": CHAT_ID,
"text": text,
"parse_mode": "HTML",
"disable_web_page_preview": True
}
)
if __name__ == "__main__":
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment