Skip to content

feat(cloud): Stream all container logs to Telegram in realtime #131

@gHashTag

Description

@gHashTag

Context

Currently only status messages (AWAKENING, CODING, DONE) go to Telegram. Need all Claude Code output streamed to Telegram in realtime — every line, every file, every command.

What to do

1. deploy/agent-entrypoint.sh — Add Telegram streaming functions

Add batch streaming (every 5 seconds) to avoid Telegram rate limits:

TELEGRAM_BUFFER=""
TELEGRAM_LAST_SEND=0
TELEGRAM_STREAM=${TELEGRAM_STREAM:-"true"}
TELEGRAM_BATCH_INTERVAL=${TELEGRAM_BATCH_INTERVAL:-5}

stream_to_telegram() {
  [ "$TELEGRAM_STREAM" != "true" ] && return
  local line="$1"
  TELEGRAM_BUFFER="${TELEGRAM_BUFFER}${line}\n"
  
  local now=$(date +%s)
  local diff=$((now - TELEGRAM_LAST_SEND))
  
  if [ $diff -ge $TELEGRAM_BATCH_INTERVAL ] || [ ${#TELEGRAM_BUFFER} -gt 3000 ]; then
    if [ -n "$TELEGRAM_BUFFER" ] && [ -n "$TELEGRAM_BOT_TOKEN" ]; then
      local msg=$(echo -e "$TELEGRAM_BUFFER" | head -c 3900)
      curl -s -X POST "https://api.telegram.org/bot${TELEGRAM_BOT_TOKEN}/sendMessage" \
        -d "chat_id=${TELEGRAM_CHAT_ID}" \
        -d "parse_mode=HTML" \
        -d "text=<pre>🤖 #${ISSUE} LOG\n${msg}</pre>" \
        --max-time 5 || true
      TELEGRAM_BUFFER=""
      TELEGRAM_LAST_SEND=$now
    fi
  fi
}

flush_telegram() {
  if [ -n "$TELEGRAM_BUFFER" ] && [ -n "$TELEGRAM_BOT_TOKEN" ]; then
    local msg=$(echo -e "$TELEGRAM_BUFFER" | head -c 3900)
    curl -s -X POST "https://api.telegram.org/bot${TELEGRAM_BOT_TOKEN}/sendMessage" \
      -d "chat_id=${TELEGRAM_CHAT_ID}" \
      -d "parse_mode=HTML" \
      -d "text=<pre>🤖 #${ISSUE} LOG\n${msg}</pre>" \
      --max-time 5 || true
    TELEGRAM_BUFFER=""
  fi
}

2. Replace Claude Code launch with streaming pipe

timeout ${AGENT_TIMEOUT:-3600} claude -p "${PROMPT}" \
  --allowedTools "Bash(*)" "Read(*)" "Write(*)" "Edit(*)" 2>&1 | \
  while IFS= read -r line; do
    echo "$line"
    stream_to_telegram "$line"
    echo "{\"type\":\"log\",\"issue\":${ISSUE},\"line\":\"$(echo "$line" | sed 's/"/\\"/g' | head -c 500)\",\"ts\":\"$(date -u +%Y-%m-%dT%H:%M:%SZ)\"}" >> /tmp/agent_events.jsonl
    case "$line" in
      *"Read("*|*"cat "*) report_status "READING" "$line" ;;
      *"Write("*|*"Edit("*) report_status "CODING" "$(echo $line | head -c 100)" ;;
      *"Bash("*|*"zig build"*) report_status "TESTING" "$(echo $line | head -c 100)" ;;
      *"error"*|*"Error"*) report_status "ERROR" "$(echo $line | head -c 200)" ;;
    esac
  done
flush_telegram

3. Stream other steps too (clone, self-review, push, PR create)

All steps should pipe through stream_to_telegram so every line appears in Telegram.

4. Add TELEGRAM_STREAM env var to cloud_orchestrator.zig

In spawnAgent() add TELEGRAM_STREAM=true to the upsertVariable calls.

Rate limiting

Telegram: 20 msgs/min to private chat. Batch every 5s = max 12 msgs/min per container. 3 containers = 36 msgs/min — safe.

Verification

After deploy, every agent run should produce Telegram messages every ~5 seconds with full Claude Code output wrapped in <pre> blocks.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions