Skip to content

Commit 6e41309

Browse files
feat: add Telegram notification for Vietnamese digest
1 parent 6ec2ac3 commit 6e41309

File tree

2 files changed

+124
-0
lines changed

2 files changed

+124
-0
lines changed

.github/workflows/translate-digest.yml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,3 +108,11 @@ jobs:
108108
git pull --rebase
109109
git push
110110
fi
111+
112+
- name: Send Telegram notification
113+
if: steps.check.outputs.has_source == 'true'
114+
env:
115+
TELEGRAM_BOT_TOKEN: ${{ secrets.TELEGRAM_BOT_TOKEN }}
116+
TELEGRAM_CHAT_ID: ${{ secrets.TELEGRAM_CHAT_ID }}
117+
PAGES_URL: ${{ vars.PAGES_URL }}
118+
run: npx tsx src/notify-vi.ts ${{ steps.date.outputs.target }}

src/notify-vi.ts

Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
/**
2+
* Telegram notification for Vietnamese translated digests.
3+
*
4+
* Self-contained — does not import upstream source files.
5+
* Scans digests/{date}/ for *-vi.md files and sends links.
6+
*
7+
* Required env vars:
8+
* TELEGRAM_BOT_TOKEN — bot token from @BotFather
9+
* TELEGRAM_CHAT_ID — channel/group/user chat ID
10+
* Optional:
11+
* PAGES_URL — GitHub Pages base URL
12+
*/
13+
14+
import fs from "node:fs";
15+
import path from "node:path";
16+
17+
const DIGESTS_DIR = "digests";
18+
const PAGES_URL_DEFAULT = "https://compasify.github.io/agents-radar";
19+
20+
const LABELS: Record<string, string> = {
21+
"ai-cli-vi": "AI CLI Tools",
22+
"ai-agents-vi": "AI Agents Ecosystem",
23+
"ai-web-vi": "Official AI Content",
24+
"ai-trending-vi": "GitHub AI Trends",
25+
"ai-hn-vi": "HN Community Digest",
26+
"ai-weekly-vi": "AI Tools Weekly",
27+
"ai-monthly-vi": "AI Tools Monthly",
28+
};
29+
30+
async function sendTelegram(text: string): Promise<void> {
31+
const BOT_TOKEN = process.env["TELEGRAM_BOT_TOKEN"] ?? "";
32+
const CHAT_ID = process.env["TELEGRAM_CHAT_ID"] ?? "";
33+
const url = `https://api.telegram.org/bot${BOT_TOKEN}/sendMessage`;
34+
const res = await fetch(url, {
35+
method: "POST",
36+
headers: { "Content-Type": "application/json" },
37+
body: JSON.stringify({
38+
chat_id: CHAT_ID,
39+
text,
40+
parse_mode: "HTML",
41+
disable_web_page_preview: true,
42+
}),
43+
});
44+
if (!res.ok) {
45+
const body = await res.text();
46+
throw new Error(`Telegram API ${res.status}: ${body}`);
47+
}
48+
}
49+
50+
function findViReports(date: string): string[] {
51+
const dir = path.join(DIGESTS_DIR, date);
52+
if (!fs.existsSync(dir)) return [];
53+
return fs
54+
.readdirSync(dir)
55+
.filter((f) => f.endsWith("-vi.md"))
56+
.map((f) => f.replace(/\.md$/, ""))
57+
.sort();
58+
}
59+
60+
function buildMessage(date: string, reports: string[]): string {
61+
const PAGES_URL = (process.env["PAGES_URL"] ?? PAGES_URL_DEFAULT).replace(/\/$/, "");
62+
const isWeekly = reports.includes("ai-weekly-vi");
63+
const isMonthly = reports.includes("ai-monthly-vi");
64+
65+
const icon = isMonthly ? "📆" : isWeekly ? "📅" : "📡";
66+
const suffix = isMonthly ? " Monthly" : isWeekly ? " Weekly" : "";
67+
const lines: string[] = [`${icon} <b>agents-radar${suffix} (Vietnamese) · ${date}</b>`];
68+
69+
const daily = reports.filter((r) => !r.includes("weekly") && !r.includes("monthly"));
70+
const rollup = reports.filter((r) => r.includes("weekly") || r.includes("monthly"));
71+
72+
for (const r of [...daily, ...rollup]) {
73+
const label = LABELS[r] ?? r;
74+
const url = `${PAGES_URL}/#${date}/${r}`;
75+
lines.push("");
76+
lines.push(`• <a href="${url}">${label}</a>`);
77+
}
78+
79+
lines.push(`\n<a href="${PAGES_URL}">🌐 Web UI</a> · <a href="${PAGES_URL}/feed.xml">⊕ RSS</a>`);
80+
return lines.join("\n");
81+
}
82+
83+
function todayUTC(): string {
84+
return new Date().toISOString().slice(0, 10);
85+
}
86+
87+
async function main(): Promise<void> {
88+
const BOT_TOKEN = process.env["TELEGRAM_BOT_TOKEN"] ?? "";
89+
if (!BOT_TOKEN) {
90+
console.log("[notify-vi] TELEGRAM_BOT_TOKEN not set — skipping.");
91+
return;
92+
}
93+
const CHAT_ID = process.env["TELEGRAM_CHAT_ID"] ?? "";
94+
if (!CHAT_ID) {
95+
console.log("[notify-vi] TELEGRAM_CHAT_ID not set — skipping.");
96+
return;
97+
}
98+
99+
const date = process.argv[2] ?? todayUTC();
100+
const reports = findViReports(date);
101+
102+
if (reports.length === 0) {
103+
console.log(`[notify-vi] No Vietnamese reports found for ${date} — skipping.`);
104+
return;
105+
}
106+
107+
const text = buildMessage(date, reports);
108+
console.log(`[notify-vi] Sending Telegram for ${date} (${reports.length} reports)…`);
109+
await sendTelegram(text);
110+
console.log("[notify-vi] Done!");
111+
}
112+
113+
main().catch((e: unknown) => {
114+
console.error("[notify-vi]", e instanceof Error ? e.message : e);
115+
process.exit(1);
116+
});

0 commit comments

Comments
 (0)