openclaw_oauth_sync/scripts/trigger-claude-refresh.sh
shamid202 22731fff60 Add complete OAuth token refresh and sync solution
- Setup wizard with auto-detection of OpenClaw paths and Claude CLI
- Token sync watcher (inotifywait) for real-time credential updates
- Auto-refresh trigger timer that runs Claude CLI every 30 min
- Supports Claude CLI in Docker container or on host
- Temporary ANTHROPIC_BASE_URL override for container environments
- Anthropic model configuration for OpenClaw
- Auth profile management (fixes key vs access field)
- Systemd services and timers for both sync and trigger
- Comprehensive documentation and troubleshooting guides
- Re-authentication notification system

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-27 01:51:18 +07:00

113 lines
3.4 KiB
Bash
Executable File

#!/bin/bash
# trigger-claude-refresh.sh — Triggers Claude CLI to refresh OAuth token when near expiry
#
# Runs via systemd timer every 30 minutes.
# Checks token expiry, triggers CLI only when needed.
# The existing sync-oauth-token.sh (inotifywait) handles syncing to OpenClaw.
#
# Supports two modes:
# Container mode: Claude CLI runs inside a Docker container
# Host mode: Claude CLI is installed directly on the system
set -uo pipefail
CREDS_FILE="@@CREDS_FILE@@"
REAUTH_FLAG="@@REAUTH_FLAG@@"
CLI_MODE="@@CLI_MODE@@"
CLI_CONTAINER="@@CLI_CONTAINER@@"
CLI_BASE_URL_OVERRIDE="@@CLI_BASE_URL_OVERRIDE@@"
LOG_PREFIX="[trigger-refresh]"
THRESHOLD_HOURS=1.5
TIMEOUT_SECONDS=60
log() { echo "$LOG_PREFIX $*"; }
log_err() { echo "$LOG_PREFIX ERROR: $*" >&2; }
# Check prerequisites
if [ ! -f "$CREDS_FILE" ]; then
log_err "Credentials file not found: $CREDS_FILE"
exit 1
fi
if [ "$CLI_MODE" = "container" ]; then
if ! docker ps --filter "name=$CLI_CONTAINER" --format '{{.Names}}' | grep -q "$CLI_CONTAINER"; then
log_err "Container $CLI_CONTAINER is not running"
exit 1
fi
else
if ! command -v claude &>/dev/null; then
log_err "Claude CLI not found on system"
exit 1
fi
fi
# Read expiry and decide whether to trigger
REMAINING=$(python3 -c "
import json, time
with open('$CREDS_FILE') as f:
d = json.load(f)
expires = d.get('claudeAiOauth', {}).get('expiresAt', 0)
remaining = (expires / 1000 - time.time()) / 3600
print(f'{remaining:.2f}')
")
log "Token expires in ${REMAINING}h (threshold: ${THRESHOLD_HOURS}h)"
# Compare as integers (multiply by 100 to avoid bash float issues)
REMAINING_X100=$(python3 -c "print(int(float('$REMAINING') * 100))")
THRESHOLD_X100=$(python3 -c "print(int(float('$THRESHOLD_HOURS') * 100))")
if [ "$REMAINING_X100" -gt "$THRESHOLD_X100" ]; then
log "Token still fresh, nothing to do"
exit 0
fi
log "Token near expiry, triggering Claude CLI refresh..."
# Record mtime BEFORE
MTIME_BEFORE=$(stat -c %Y "$CREDS_FILE" 2>/dev/null || stat -f %m "$CREDS_FILE" 2>/dev/null)
# Trigger Claude CLI
if [ "$CLI_MODE" = "container" ]; then
if [ "$CLI_BASE_URL_OVERRIDE" = "true" ]; then
CLI_OUTPUT=$(timeout "$TIMEOUT_SECONDS" docker exec \
-e ANTHROPIC_BASE_URL=https://api.anthropic.com \
"$CLI_CONTAINER" claude -p "say ok" --no-session-persistence 2>&1)
else
CLI_OUTPUT=$(timeout "$TIMEOUT_SECONDS" docker exec \
"$CLI_CONTAINER" claude -p "say ok" --no-session-persistence 2>&1)
fi
else
CLI_OUTPUT=$(timeout "$TIMEOUT_SECONDS" claude -p "say ok" --no-session-persistence 2>&1)
fi
CLI_EXIT=$?
if [ "$CLI_EXIT" -eq 124 ]; then
log_err "CLI command timed out after ${TIMEOUT_SECONDS}s"
fi
log "CLI exit code: $CLI_EXIT, output: $CLI_OUTPUT"
# Record mtime AFTER
sleep 2
MTIME_AFTER=$(stat -c %Y "$CREDS_FILE" 2>/dev/null || stat -f %m "$CREDS_FILE" 2>/dev/null)
if [ "$MTIME_BEFORE" != "$MTIME_AFTER" ]; then
log "Token refreshed successfully (mtime changed: $MTIME_BEFORE -> $MTIME_AFTER)"
if [ -f "$REAUTH_FLAG" ]; then
rm -f "$REAUTH_FLAG"
log "Cleared previous REAUTH_NEEDED flag"
fi
exit 0
else
log_err "Token refresh FAILED — credentials.json was not updated"
log_err "Re-authentication may be required (refresh token expired or subscription issue)"
echo "Re-authentication needed at $(date -u '+%Y-%m-%dT%H:%M:%SZ')" > "$REAUTH_FLAG"
log_err "Wrote $REAUTH_FLAG"
exit 1
fi