#!/usr/bin/env bash # PreToolUse hook for Claude Code — redirect plain telegram reply tool calls # through tg-stream so streaming behavior is enforced infrastructurally. # # Install in ~/.claude/settings.json under hooks.PreToolUse, matching tools: # mcp__plugin_telegram_telegram__reply # # Behavior: # - If the call has no `files` attachment, BLOCK it and emit a stderr # message telling Claude to use /host/root/openclaw/tg-stream instead. # - If the call HAS `files`, PASS THROUGH (tg-stream doesn't do attachments). # # Input: JSON on stdin {"tool_name":"...", "tool_input": {...}} # Output: exit 0 = allow, exit 2 = block (stderr surfaced to Claude). # # Uses node (always present in this container) instead of jq (not installed). set -u INPUT=$(cat) DECISION=$(node -e ' let raw = ""; process.stdin.on("data", c => raw += c); process.stdin.on("end", () => { try { const j = JSON.parse(raw); const tool = j.tool_name || ""; if (tool !== "mcp__plugin_telegram_telegram__reply") { console.log("ALLOW"); return; } const files = (j.tool_input && j.tool_input.files) || []; if (Array.isArray(files) && files.length > 0) { console.log("ALLOW"); return; } console.log("BLOCK"); } catch (e) { console.log("ALLOW"); // fail open on parse error } }); ' <<<"$INPUT") if [[ "$DECISION" != "BLOCK" ]]; then exit 0 fi cat >&2 <<'EOF' BLOCKED by /host/root/openclaw/hooks/redirect-telegram-reply.sh Plain telegram reply is disabled for substantive messages. Use the streaming tool instead so the user gets a typing animation rather than a wall of text: /host/root/openclaw/tg-stream "your message" /host/root/openclaw/tg-stream --header "🔧 working" "body text" /host/root/openclaw/tg-stream --no-stream "short ack" echo "from stdin" | /host/root/openclaw/tg-stream For long-running tasks, wrap them so heartbeats are sent automatically: /host/root/openclaw/tg-task "label" -- If you genuinely need to send a file attachment (image/document), call the mcp__plugin_telegram_telegram__reply tool again with the `files` parameter set — the hook passes attachment-bearing calls through. EOF exit 2