#!/bin/bash # # ClawdTalk - Setup Script (v1.1) # # Interactive setup for voice calling integration. # Asks for API key, auto-detects names, and configures the gateway. # Uses jq for all JSON manipulation (no python3 dependency). # # Usage: ./setup.sh # # Env vars: none directly # Endpoints: none # Reads: ~/.openclaw/openclaw.json, ~/.clawdbot/clawdbot.json, USER.md, IDENTITY.md # Writes: skill-config.json, gateway config set -e SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" CONFIG_FILE="$SCRIPT_DIR/skill-config.json" echo "" echo "📞 ClawdTalk Setup" echo "===================" echo "" echo "This will set up voice calling for your Clawdbot/OpenClaw instance." echo "" # Check for required tools echo "📋 Checking requirements..." for tool in node jq; do if ! command -v "$tool" &> /dev/null; then echo "❌ Required tool '$tool' is not installed." exit 1 fi done echo " ✓ All required tools found" # Check if already configured if [ -f "$CONFIG_FILE" ]; then echo "" echo "⚠️ Configuration already exists!" echo "" echo "Current config: $CONFIG_FILE" echo "" read -p "Do you want to reconfigure? (y/N): " reconfigure if [[ ! "$reconfigure" =~ ^[Yy]$ ]]; then echo "" echo "Setup cancelled. Run './status.sh' to see current configuration." exit 0 fi echo "" fi # Ask for API key echo "🔑 API Key" echo "===========" echo "" echo "You need an API key from ClawdTalk." echo "" echo " 1. Go to https://clawdtalk.com and sign in with Google" echo " 2. Set up your phone number in Settings" echo " 3. Generate an API key from the Dashboard" echo "" read -s -p "Enter your API key (or press Enter to skip for now): " api_key echo "" if [ -n "$api_key" ]; then echo " ✓ API key saved" else echo " ⚠️ No API key entered — you can add it to skill-config.json later" fi # Auto-detect gateway config (support both clawdbot and openclaw) echo "" echo "🔧 Configuring voice agent..." GATEWAY_CONFIG="" CLI_NAME="" if [ -f "${HOME}/.clawdbot/clawdbot.json" ]; then GATEWAY_CONFIG="${HOME}/.clawdbot/clawdbot.json" CLI_NAME="clawdbot" elif [ -f "${HOME}/.openclaw/openclaw.json" ]; then GATEWAY_CONFIG="${HOME}/.openclaw/openclaw.json" CLI_NAME="openclaw" fi # Auto-detect CLI name if [ -z "$CLI_NAME" ]; then if command -v clawdbot &> /dev/null; then CLI_NAME="clawdbot" elif command -v openclaw &> /dev/null; then CLI_NAME="openclaw" else CLI_NAME="clawdbot" fi fi voice_agent_added=false main_agent_workspace="" if [ -n "$GATEWAY_CONFIG" ] && [ -f "$GATEWAY_CONFIG" ]; then # Check if voice agent already exists (using jq) has_voice=$(jq -r '[.agents.list[]? | select(.id == "voice")] | length > 0' "$GATEWAY_CONFIG" 2>/dev/null || echo "false") # Read the main agent's name and workspace using jq main_agent_name=$(jq -r '(.agents.list[]? | select(.default == true or .id == "main") | .name) // "Assistant"' "$GATEWAY_CONFIG" 2>/dev/null || echo "Assistant") main_agent_workspace=$(jq -r '(.agents.list[]? | select(.default == true or .id == "main") | .workspace) // .agents.defaults.workspace // "/home/node/clawd"' "$GATEWAY_CONFIG" 2>/dev/null || echo "/home/node/clawd") # Extract gateway connection details for skill-config.json (so ws-client doesn't need to read gateway config at runtime) gateway_port=$(jq -r '.gateway.port // 18789' "$GATEWAY_CONFIG" 2>/dev/null || echo "18789") gateway_token=$(jq -r '.gateway.auth.token // ""' "$GATEWAY_CONFIG" 2>/dev/null || echo "") gateway_url="http://127.0.0.1:${gateway_port}" main_agent_id=$(jq -r '(.agents.list[]? | select(.default == true) | .id) // (.agents.list[0]?.id) // "main"' "$GATEWAY_CONFIG" 2>/dev/null || echo "main") if [ "$has_voice" = "true" ]; then echo " ✓ Voice agent already configured in gateway" voice_agent_added=true else # Build the voice agent object (no systemPrompt — injected by ws-client via messages) voice_agent=$(jq -n \ --arg name "${main_agent_name} Voice" \ --arg workspace "$main_agent_workspace" \ '{ id: "voice", name: $name, workspace: $workspace }') # Add voice agent to agents.list tmp_config=$(mktemp) if jq --argjson agent "$voice_agent" ' .agents.list = (.agents.list // []) + [$agent] ' "$GATEWAY_CONFIG" > "$tmp_config" 2>/dev/null; then mv "$tmp_config" "$GATEWAY_CONFIG" echo " ✓ Added '${main_agent_name} Voice' agent to gateway config" voice_agent_added=true # Tell user to restart gateway (skill shouldn't restart the gateway itself) echo " ⚠️ Run '$CLI_NAME gateway restart' to apply the new agent config" else rm -f "$tmp_config" echo " ⚠️ Could not auto-configure — see manual steps below" fi fi else echo " ⚠️ Gateway config not found — see manual steps below" echo " Checked: ~/.clawdbot/clawdbot.json and ~/.openclaw/openclaw.json" fi # Install Node dependencies echo "" echo "📦 Installing dependencies..." if [ -f "$SCRIPT_DIR/package.json" ]; then (cd "$SCRIPT_DIR" && npm install --production 2>/dev/null) && echo " ✓ Dependencies installed" || echo " ⚠️ npm install failed — run 'npm install' manually in the skill directory" else echo " ⚠️ No package.json found" fi # Detect user and agent names echo "" echo "👤 Setting up names..." WORKSPACE="${main_agent_workspace:-$HOME/.openclaw/workspace}" owner_name="" agent_name="" # Offer to auto-detect from workspace files (opt-in to address security scanner flag) auto_detect="y" if [ -f "$WORKSPACE/USER.md" ] || [ -f "$WORKSPACE/IDENTITY.md" ]; then read -p " Auto-detect names from workspace? (Y/n): " auto_detect auto_detect="${auto_detect:-y}" fi if [[ "$auto_detect" =~ ^[Yy]$ ]]; then # Try to get owner name from USER.md ("What to call them:" or "Name:") if [ -f "$WORKSPACE/USER.md" ]; then owner_name=$(grep -i "what to call them:" "$WORKSPACE/USER.md" 2>/dev/null | head -1 | sed 's/.*:\s*//' | tr -d '*' | xargs) if [ -z "$owner_name" ]; then owner_name=$(grep -i "^- \*\*Name:" "$WORKSPACE/USER.md" 2>/dev/null | head -1 | sed 's/.*:\s*//' | tr -d '*' | xargs) owner_name=$(echo "$owner_name" | awk '{print $1}') fi fi # Try to get agent name from IDENTITY.md if [ -f "$WORKSPACE/IDENTITY.md" ]; then agent_name=$(grep -i "^- \*\*Name:" "$WORKSPACE/IDENTITY.md" 2>/dev/null | head -1 | sed 's/.*:\s*//' | tr -d '*' | xargs) fi fi # If auto-detect didn't find names (or was skipped), ask manually if [ -z "$owner_name" ]; then read -p " Your name (for greeting): " owner_name fi if [ -z "$agent_name" ]; then read -p " Agent name (optional, press Enter to skip): " agent_name fi if [ -n "$owner_name" ]; then echo " ✓ Owner name: $owner_name" fi if [ -n "$agent_name" ]; then echo " ✓ Agent name: $agent_name" fi # Create skill-config.json echo "" echo "💾 Creating skill configuration..." # Build values if [ -n "$api_key" ]; then api_key_json="\"$api_key\"" else api_key_json="null" fi owner_name_json="null" agent_name_json="null" if [ -n "$owner_name" ]; then owner_name_json="\"$owner_name\"" fi if [ -n "$agent_name" ]; then agent_name_json="\"$agent_name\"" fi # Build greeting with name if available if [ -n "$owner_name" ]; then greeting="Hey $owner_name, what's up?" else greeting="Hey, what's up?" fi gateway_url_json="null" gateway_token_json="null" agent_id_json="null" if [ -n "$gateway_url" ]; then gateway_url_json="\"$gateway_url\"" fi if [ -n "$gateway_token" ]; then gateway_token_json="\"$gateway_token\"" fi if [ -n "$main_agent_id" ]; then agent_id_json="\"$main_agent_id\"" fi cat > "$CONFIG_FILE" << EOF { "api_key": $api_key_json, "server": "https://clawdtalk.com", "owner_name": $owner_name_json, "agent_name": $agent_name_json, "greeting": "$greeting", "gateway_url": $gateway_url_json, "gateway_token": $gateway_token_json, "agent_id": $agent_id_json } EOF echo " ✓ Configuration saved to: $CONFIG_FILE" echo " ⚠️ Note: If you change your gateway token or port later, re-run setup.sh to update." # Display next steps echo "" echo "🎉 Setup Complete!" echo "==================" echo "" if [ -z "$api_key" ]; then echo "Next steps:" echo "" echo "1. Get your API key from https://clawdtalk.com" echo " • Sign in with Google" echo " • Set up your phone number in Settings" echo " • Generate an API key from the Dashboard" echo "" echo "2. Add it to skill-config.json:" echo " Set the api_key field" echo "" echo "3. Start the connection:" echo " ./scripts/connect.sh start" else echo "Next steps:" echo "" echo "1. Make sure your phone number is set up at https://clawdtalk.com → Settings" echo "" echo "2. Start the connection:" echo " ./scripts/connect.sh start" fi echo "" # Check gateway.tools.allow for sessions_send echo "" echo "🔐 Checking gateway tools policy..." sessions_send_allowed=false if [ -n "$GATEWAY_CONFIG" ] && [ -f "$GATEWAY_CONFIG" ]; then has_allow=$(jq -r '(.gateway.tools.allow // []) | map(select(. == "sessions_send")) | length > 0' "$GATEWAY_CONFIG" 2>/dev/null || echo "false") if [ "$has_allow" = "true" ]; then echo " ✓ sessions_send is allowed on the Gateway HTTP tools API" sessions_send_allowed=true else echo "" echo " ⚠️ sessions_send is NOT allowed on the Gateway HTTP tools API" echo "" echo " Voice calls route requests to your main agent via sessions_send." echo " OpenClaw blocks this tool over HTTP by default for security." echo " Without it, voice calls connect but the AI can't process any requests —" echo " it hears you, but can't act (all tool calls silently fail with 404)." echo "" read -p " Add sessions_send to gateway.tools.allow? (Y/n): " add_allow if [[ ! "$add_allow" =~ ^[Nn]$ ]]; then tmp_config=$(mktemp) if jq '.gateway.tools.allow = ((.gateway.tools.allow // []) + ["sessions_send"] | unique)' "$GATEWAY_CONFIG" > "$tmp_config" 2>/dev/null; then mv "$tmp_config" "$GATEWAY_CONFIG" echo " ✓ Added sessions_send to gateway.tools.allow" sessions_send_allowed=true echo " ⚠️ Run '$CLI_NAME gateway restart' to apply changes" else rm -f "$tmp_config" echo " ⚠️ Could not auto-configure — add it manually (see below)" fi else echo " ⚠️ Skipped — voice call requests won't work until this is added" fi fi fi if [ "$voice_agent_added" = true ]; then echo "" echo "✅ Voice agent is configured and ready." else echo "⚠️ Voice agent not auto-configured. Add it manually:" echo "" config_path="~/.clawdbot/clawdbot.json" if [ "$CLI_NAME" = "openclaw" ]; then config_path="~/.openclaw/openclaw.json" fi echo " Edit $config_path and add to agents.list[]:" echo ' { "id": "voice", "name": "Voice" }' echo "" echo " Also ensure chatCompletions is enabled:" echo ' "gateway": { "http": { "endpoints": { "chatCompletions": { "enabled": true } } } }' echo "" echo " Then restart: $CLI_NAME gateway restart" fi if [ "$sessions_send_allowed" != true ]; then echo "" echo "⚠️ Gateway tools policy: sessions_send must be allowed for voice calls." echo "" echo " Voice calls work by routing your spoken requests to the main agent session" echo " via the Gateway HTTP tools API (/tools/invoke → sessions_send). OpenClaw" echo " blocks sessions_send over HTTP by default as a security measure. Without" echo " this, the AI connects to your call but can't do anything — all requests" echo " silently fail." echo "" config_path="~/.openclaw/openclaw.json" if [ "$CLI_NAME" = "clawdbot" ]; then config_path="~/.clawdbot/clawdbot.json" fi echo " Add to $config_path:" echo ' { "gateway": { "tools": { "allow": ["sessions_send"] } } }' echo "" echo " Or via CLI:" echo " $CLI_NAME config patch '{\"gateway\":{\"tools\":{\"allow\":[\"sessions_send\"]}}}'" fi echo "" echo "📋 Voice calls will use your main agent's full context and memory." echo " All tools available to your agent work on voice calls too." echo "" echo "To check status: ./status.sh" echo ""