From 75fa95752feac42d05dc635c450027c69aa6ae17 Mon Sep 17 00:00:00 2001 From: banteg <4562643+banteg@users.noreply.github.com> Date: Sun, 28 Dec 2025 18:48:20 +0400 Subject: [PATCH] feat: add telegram notifier --- codex/notify_telegram/README.md | 38 +++++++++++++ codex/notify_telegram/config.toml.example | 1 + codex/notify_telegram/notify_telegram.py | 62 +++++++++++++++++++++ codex/notify_telegram/telegram.json.example | 4 ++ readme.md | 3 + 5 files changed, 108 insertions(+) create mode 100644 codex/notify_telegram/README.md create mode 100644 codex/notify_telegram/config.toml.example create mode 100644 codex/notify_telegram/notify_telegram.py create mode 100644 codex/notify_telegram/telegram.json.example create mode 100644 readme.md diff --git a/codex/notify_telegram/README.md b/codex/notify_telegram/README.md new file mode 100644 index 0000000..73e6371 --- /dev/null +++ b/codex/notify_telegram/README.md @@ -0,0 +1,38 @@ +# Notify Telegram (Codex) + +Send Codex completion summaries to Telegram with safe Markdown rendering and stable list bullets. + +## Install + +1. Ensure `uv` is installed. +2. Copy the script into your repo (already in this folder). +3. Create your Telegram creds file at `~/.codex/telegram.json`. + +Example: + +```json +{ + "bot_token": "123456:ABCDEF...", + "chat_id": "462722" +} +``` + +## Configure + +Add a `notify` entry to `~/.codex/config.toml`: + +```toml +notify = ["uv", "run", "/absolute/path/to/agents/codex/notify_telegram/notify_telegram.py"] +``` + +## Notes + +- The script reads `last-assistant-message` and treats it as Markdown. +- Markdown is rendered to HTML, converted to Telegram text/entities via `sulguk`, then posted with `requests`. +- List bullets are normalized from `•` to `-` to keep Telegram output consistent. + +## Files + +- `notify_telegram.py`: the notifier script +- `telegram.json.example`: sample credentials file +- `config.toml.example`: sample Codex `notify` config line diff --git a/codex/notify_telegram/config.toml.example b/codex/notify_telegram/config.toml.example new file mode 100644 index 0000000..93afa85 --- /dev/null +++ b/codex/notify_telegram/config.toml.example @@ -0,0 +1 @@ +notify = ["uv", "run", "/Users/YOU/path/to/agents/codex/notify_telegram/notify_telegram.py"] diff --git a/codex/notify_telegram/notify_telegram.py b/codex/notify_telegram/notify_telegram.py new file mode 100644 index 0000000..2b9d3cc --- /dev/null +++ b/codex/notify_telegram/notify_telegram.py @@ -0,0 +1,62 @@ +#!/usr/bin/env python3 +# /// script +# requires-python = ">=3.10" +# dependencies = ["requests", "markdown-it-py", "sulguk"] +# /// +import json +import re +import sys +from pathlib import Path + +import requests +from markdown_it import MarkdownIt +from sulguk import transform_html + +CREDS_PATH = Path.home() / ".codex" / "telegram.json" + + +def main() -> None: + creds = json.loads(CREDS_PATH.read_text(encoding="utf-8")) + bot_token = creds["bot_token"] + chat_id = str(creds["chat_id"]) + + payload = json.loads(sys.argv[1]) + + md = payload["last-assistant-message"].rstrip() + thread_id = payload.get("thread-id") + cwd = payload.get("cwd") + prompt = (payload.get("input-messages") or [""])[-1].rstrip() + + footer = "\n".join( + line + for line in [ + "---", + f"- cwd: `{cwd}`" if cwd else "", + f"- thread: `{thread_id}`" if thread_id else "", + f"- prompt: `{prompt}`" if prompt else "", + ] + if line + ) + + md_full = md if not footer else f"{md}\n\n{footer}" + + html = MarkdownIt("commonmark", {"html": False}).render(md_full) + result = transform_html(html) + + # Use "-" instead of "•" for list markers (keep offsets stable: 1 char -> 1 char) + text = re.sub(r"(?m)^(\s*)• ", r"\1- ", result.text) + + requests.post( + f"https://api.telegram.org/bot{bot_token}/sendMessage", + json={ + "chat_id": chat_id, + "text": text, + "entities": result.entities, + "disable_web_page_preview": True, + }, + timeout=15, + ).raise_for_status() + + +if __name__ == "__main__": + main() diff --git a/codex/notify_telegram/telegram.json.example b/codex/notify_telegram/telegram.json.example new file mode 100644 index 0000000..dd76afd --- /dev/null +++ b/codex/notify_telegram/telegram.json.example @@ -0,0 +1,4 @@ +{ + "bot_token": "123456:ABCDEF...", + "chat_id": "462722" +} diff --git a/readme.md b/readme.md new file mode 100644 index 0000000..a7c615b --- /dev/null +++ b/readme.md @@ -0,0 +1,3 @@ +# Scripts + +- [Notify Telegram](codex/notify_telegram/README.md) — Send Codex completion summaries to Telegram with safe Markdown rendering.