Uname:Linux antigravity-cli 6.8.0-31-generic #31-Ubuntu SMP PREEMPT_DYNAMIC Sat Apr 20 00:40:06 UTC 2024 x86_64

Base Dir : /var/www/moonbloom

User : wp-moonbloom


403WebShell
403Webshell
Server IP : 85.155.190.233  /  Your IP : 216.73.216.103
Web Server : nginx/1.24.0
System : Linux antigravity-cli 6.8.0-31-generic #31-Ubuntu SMP PREEMPT_DYNAMIC Sat Apr 20 00:40:06 UTC 2024 x86_64
User : wp-moonbloom ( 1001)
PHP Version : 8.3.6
Disable Function : NONE
MySQL : OFF  |  cURL : ON  |  WGET : ON  |  Perl : ON  |  Python : OFF  |  Sudo : ON  |  Pkexec : OFF
Directory :  /proc/2398464/root/opt/Gemini_Swarm_Core/scripts/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Command :


[ Back ]     

Current File : /proc/2398464/root/opt/Gemini_Swarm_Core/scripts/notify_telegram.py
#!/usr/bin/env python3
"""
PostInvocation hook for agy schedule — sends agent output to Telegram
and logs the run to sessions.db (swarm_run_sessions table).

Works in two modes:
  - Hook mode: agy pipes JSON to stdin after task completes
  - Pipe mode: shell script pipes agy stdout as plain text (crontab)
"""
import json
import os
import sqlite3
import sys
import urllib.request
import re
from datetime import datetime, timezone

DB_PATH = os.path.join(os.path.dirname(os.path.abspath(__file__)), "..", "sessions.db")
TASK_NAME = os.environ.get("TREND_SCOUT_TASK", "trend_scout")


def clean_plain_text(text: str) -> str:
    ansi_escape = re.compile(r'\x1b\[[0-9;]*[a-zA-Z]')
    lines = text.splitlines()
    cleaned_lines = []
    
    skip_prefixes = (
        "warning:", "ripgrep", "mcp", "using a terminal", 
        "fallback", "falling back", "256-color", "calling tool",
        "tool response", "[system]", "[error]", "[info]", "[warning]", "[debug]"
    )
    
    for line in lines:
        clean_line = ansi_escape.sub("", line).strip()
        clean_line_lower = clean_line.lower()
        
        if not clean_line:
            cleaned_lines.append("")
            continue
            
        if clean_line_lower.startswith("i will "):
            continue
            
        if any(clean_line_lower.startswith(prefix) for prefix in skip_prefixes):
            continue
            
        if re.match(r'^\s*\w+\([^)]*\)\s*$', clean_line):
            continue
            
        cleaned_lines.append(line)
        
    result = "\n".join(cleaned_lines).strip()
    result = re.sub(r'\n{3,}', '\n\n', result)
    return result


def load_env(env_path: str):
    if not os.path.exists(env_path):
        return
    with open(env_path) as f:
        for line in f:
            line = line.strip()
            if line and not line.startswith("#") and "=" in line:
                k, v = line.split("=", 1)
                os.environ.setdefault(k.strip(), v.strip().strip('"').strip("'"))


def fix_html(text: str) -> str:
    """Fix common HTML issues that cause Telegram to reject parse_mode=HTML."""
    # Collapse newlines inside HTML tags (agy may wrap long tags across lines)
    text = re.sub(r'<([^>]*?)\n([^>]*?)>', lambda m: '<' + m.group(1).rstrip() + ' ' + m.group(2).lstrip() + '>', text)
    # Escape bare & not already part of an HTML entity
    text = re.sub(r'&(?!amp;|lt;|gt;|quot;|apos;|#\d+;|#x[0-9a-fA-F]+;)', '&amp;', text)
    return text


def send_chunks(token: str, chat_id: str, text: str):
    url = f"https://api.telegram.org/bot{token}/sendMessage"
    fixed = fix_html(text)
    chunks = [fixed[i:i+4000] for i in range(0, len(fixed), 4000)]
    for chunk in chunks:
        payload = json.dumps({"chat_id": chat_id, "text": chunk, "parse_mode": "HTML"}).encode()
        req = urllib.request.Request(url, data=payload, headers={"Content-Type": "application/json"})
        try:
            urllib.request.urlopen(req, timeout=30)
        except Exception as e:
            print(f"notify_telegram: HTML send failed ({e}), retrying as plain text", file=sys.stderr)
            payload = json.dumps({"chat_id": chat_id, "text": chunk}).encode()
            req = urllib.request.Request(url, data=payload, headers={"Content-Type": "application/json"})
            urllib.request.urlopen(req, timeout=30)


def extract_output(payload: dict) -> str:
    output = payload.get("output") or payload.get("result") or ""
    if not output:
        transcript = payload.get("transcript", [])
        if isinstance(transcript, list) and transcript:
            last = transcript[-1]
            if isinstance(last, dict):
                output = last.get("content") or last.get("text") or str(last)
            else:
                output = str(last)
    return str(output).strip()


def log_run(task_name: str, status: str, summary: str | None, error: str | None):
    """Write run result to swarm_run_sessions in sessions.db."""
    db_path = os.path.abspath(DB_PATH)
    if not os.path.exists(db_path):
        return
    try:
        ts = int(datetime.now(timezone.utc).timestamp())
        session_id = f"sess_{task_name}_{ts}"
        now = datetime.now(timezone.utc).strftime("%Y-%m-%dT%H:%M:%SZ")
        conn = sqlite3.connect(db_path)
        # get task_id
        row = conn.execute(
            "SELECT task_id FROM swarm_tasks WHERE task_name = ?", (task_name,)
        ).fetchone()
        task_id = row[0] if row else 0
        conn.execute("""
            INSERT OR IGNORE INTO swarm_run_sessions
                (session_id, task_id, status, started_at, finished_at, digest_summary)
            VALUES (?, ?, ?, ?, ?, ?)
        """, (session_id, task_id, status, now, now, (summary or error or "")[:500]))
        # update last_run_time in swarm_tasks
        if status == "SUCCESS":
            conn.execute(
                "UPDATE swarm_tasks SET last_run_time = ? WHERE task_name = ?",
                (now, task_name)
            )
        conn.commit()
        conn.close()
    except Exception as e:
        print(f"notify_telegram: DB log failed: {e}", file=sys.stderr)


def main():
    script_dir = os.path.dirname(os.path.abspath(__file__))
    load_env(os.path.join(script_dir, "..", ".env"))

    token = os.environ.get("TELEGRAM_BOT_TOKEN", "")
    users = [u.strip() for u in os.environ.get("TELEGRAM_ALLOWED_USERS", "").split(",") if u.strip()]

    if not token or not users:
        log_run(TASK_NAME, "FAILED", None, "Missing TELEGRAM_BOT_TOKEN or TELEGRAM_ALLOWED_USERS")
        print(json.dumps({}))
        sys.exit(0)

    try:
        raw = sys.stdin.read()
    except Exception:
        raw = ""

    try:
        payload = json.loads(raw) if raw.strip() else {}
        output = extract_output(payload)
    except json.JSONDecodeError:
        # Plain text mode: piped directly from agy stdout (crontab)
        output = clean_plain_text(raw)

    if len(output) < 50:
        log_run(TASK_NAME, "FAILED", None, f"Output too short ({len(output)} chars) — agent may have failed")
        print(json.dumps({}))
        sys.exit(0)

    tg_ok = True
    for chat_id in users:
        try:
            send_chunks(token, chat_id, output)
        except Exception as e:
            print(f"notify_telegram: failed for {chat_id}: {e}", file=sys.stderr)
            tg_ok = False

    if tg_ok:
        log_run(TASK_NAME, "SUCCESS", output[:500], None)
    else:
        log_run(TASK_NAME, "FAILED", None, "Telegram delivery failed")

    print(json.dumps({}))


if __name__ == "__main__":
    main()

Youez - 2016 - github.com/yon3zu
LinuXploit