Spaces:
Running
Running
| #!/usr/bin/env python3 | |
| """ | |
| aetheris_notifier.py — Hệ thống thông báo Telegram cho Aetheris | |
| Gửi update cho sếp khi agent hoàn thành nhiệm vụ / gặp lỗi / cần chú ý | |
| Setup: | |
| 1. Tạo bot qua @BotFather → nhận BOT_TOKEN | |
| 2. Chat với bot → lấy CHAT_ID từ https://api.telegram.org/bot<TOKEN>/getUpdates | |
| 3. Ghi vào ~/.aetheris/vault/telegram.json | |
| """ | |
| import json, os, asyncio, time | |
| from pathlib import Path | |
| from datetime import datetime | |
| VAULT = Path.home() / '.aetheris' / 'vault' | |
| TELEGRAM_CFG = VAULT / 'telegram.json' | |
| def load_config(): | |
| """Load Telegram config từ vault""" | |
| if TELEGRAM_CFG.exists(): | |
| return json.loads(TELEGRAM_CFG.read_text()) | |
| return None | |
| def send_sync(message: str, parse_mode: str = "HTML") -> bool: | |
| """Send Telegram message đồng bộ (không cần async)""" | |
| cfg = load_config() | |
| if not cfg: | |
| print(f"⚠️ Telegram chưa config. Message: {message}") | |
| return False | |
| import urllib.request, urllib.parse | |
| token = cfg['bot_token'] | |
| chat_id = cfg['chat_id'] | |
| url = f"https://api.telegram.org/bot{token}/sendMessage" | |
| params = { | |
| 'chat_id': chat_id, | |
| 'text': message | |
| } | |
| if parse_mode: | |
| params['parse_mode'] = parse_mode | |
| data = urllib.parse.urlencode(params).encode() | |
| try: | |
| with urllib.request.urlopen(url, data=data, timeout=10) as r: | |
| result = json.loads(r.read()) | |
| return result.get('ok', False) | |
| except Exception as e: | |
| print(f"⚠️ Telegram error: {e}") | |
| return False | |
| def notify_task_start(task_name: str, details: str = ""): | |
| """Thông báo bắt đầu nhiệm vụ""" | |
| msg = ( | |
| f"🤖 <b>Aetheris bắt đầu làm việc</b>\n" | |
| f"📋 <b>Nhiệm vụ:</b> {task_name}\n" | |
| f"🕐 <b>Lúc:</b> {datetime.now().strftime('%H:%M:%S')}\n" | |
| + (f"📝 {details}" if details else "") | |
| ) | |
| return send_sync(msg) | |
| def notify_task_done(task_name: str, result: str = "", duration_s: float = 0): | |
| """Thông báo hoàn thành nhiệm vụ""" | |
| duration_str = f"{duration_s:.0f}s" if duration_s < 60 else f"{duration_s/60:.1f}m" | |
| msg = ( | |
| f"✅ <b>Hoàn thành!</b>\n" | |
| f"📋 <b>Nhiệm vụ:</b> {task_name}\n" | |
| f"⏱️ <b>Thời gian:</b> {duration_str}\n" | |
| f"🕐 <b>Lúc:</b> {datetime.now().strftime('%H:%M:%S')}\n" | |
| + (f"📊 <b>Kết quả:</b>\n<code>{result[:500]}</code>" if result else "") | |
| ) | |
| return send_sync(msg) | |
| def notify_error(task_name: str, error: str, auto_retry: bool = False): | |
| """Thông báo lỗi""" | |
| msg = ( | |
| f"❌ <b>Lỗi xảy ra</b>\n" | |
| f"📋 <b>Nhiệm vụ:</b> {task_name}\n" | |
| f"🕐 <b>Lúc:</b> {datetime.now().strftime('%H:%M:%S')}\n" | |
| f"🔴 <b>Lỗi:</b>\n<code>{error[:500]}</code>\n" | |
| + ("♻️ <i>Đang tự retry...</i>" if auto_retry else "⚠️ <i>Cần xem xét!</i>") | |
| ) | |
| return send_sync(msg) | |
| def notify_fleet_status(status: dict): | |
| """Thông báo fleet health""" | |
| healthy = sum(1 for v in status.values() if v == 'healthy') | |
| total = len(status) | |
| lines = [f"🏰 <b>Aetheris Fleet Status</b> ({healthy}/{total} ✅)"] | |
| for name, st in status.items(): | |
| emoji = "✅" if st == 'healthy' else "💀" if st == 'down' else "⏸️" | |
| lines.append(f" {emoji} {name}: <code>{st}</code>") | |
| return send_sync('\n'.join(lines)) | |
| def notify_theory_discovery(theory_id: str, sharpe: float, win_rate: float): | |
| """Thông báo tìm thấy theory mới tốt""" | |
| msg = ( | |
| f"🧠 <b>Theory mới tốt!</b>\n" | |
| f"📌 <b>ID:</b> <code>{theory_id}</code>\n" | |
| f"📈 <b>Sharpe:</b> {sharpe:+.2f}\n" | |
| f"🎯 <b>Win Rate:</b> {win_rate:.0%}\n" | |
| f"💡 <i>Đã thêm vào registry tự động</i>" | |
| ) | |
| return send_sync(msg) | |
| def setup_telegram(): | |
| """Setup wizard cho Telegram bot""" | |
| print("=== Aetheris Telegram Setup ===") | |
| print("\n1. Mở Telegram, tìm @BotFather") | |
| print("2. Gửi /newbot → đặt tên → nhận BOT_TOKEN") | |
| print("3. Chat với bot bất kỳ gì") | |
| print("4. Mở: https://api.telegram.org/bot<TOKEN>/getUpdates") | |
| print(" Tìm 'id' trong 'chat' → đó là CHAT_ID\n") | |
| token = input("Nhập BOT_TOKEN: ").strip() | |
| chat_id = input("Nhập CHAT_ID: ").strip() | |
| # Unlock vault | |
| os.system(f"chflags nouchg {VAULT}") | |
| cfg = {'bot_token': token, 'chat_id': chat_id} | |
| TELEGRAM_CFG.write_text(json.dumps(cfg, indent=2)) | |
| # Re-lock | |
| os.system(f"chflags uchg {TELEGRAM_CFG}") | |
| # Test | |
| if send_sync("🤖 Aetheris Telegram đã được kết nối!\nSếp sẽ nhận thông báo từ agent từ giờ."): | |
| print("✅ Setup thành công!") | |
| else: | |
| print("❌ Thất bại — kiểm tra token và chat_id") | |
| if __name__ == '__main__': | |
| import sys | |
| if '--setup' in sys.argv: | |
| setup_telegram() | |
| elif '--test' in sys.argv: | |
| notify_task_start("Test Notification", "Đây là test message từ Aetheris") | |
| time.sleep(1) | |
| notify_task_done("Test Notification", "Telegram hoạt động tốt!", 2.5) | |
| else: | |
| print("Usage: python3 aetheris_notifier.py --setup | --test") | |