#!/bin/bash # EU-Utility External API Test Client (curl) # =========================================== # # Example curl commands for testing EU-Utility external API. # Supports REST API and webhook integrations. # # Usage: # chmod +x api_client_test.sh # ./api_client_test.sh --help # ./api_client_test.sh health # ./api_client_test.sh status # ./api_client_test.sh notify "Test Title" "Test Message" # ./api_client_test.sh search "ArMatrix" # # Configuration HOST="${EU_HOST:-127.0.0.1}" PORT="${EU_PORT:-8080}" API_KEY="${EU_API_KEY:-}" BASE_URL="http://${HOST}:${PORT}" # Colors for output RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' NC='\033[0m' # No Color # Print usage print_help() { cat << EOF EU-Utility External API Test Client (curl) Usage: ./api_client_test.sh [options] Options: --host API host (default: 127.0.0.1, or EU_HOST env var) --port API port (default: 8080, or EU_PORT env var) --api-key API key (or EU_API_KEY env var) --help Show this help message Commands: health Check API health status Get EU-Utility status notify <msg> Send notification search <query> Search Nexus loot <value> <mob> Record loot event global <value> <mob> Record global/HOF webhook <url> [msg] Send Discord webhook test Run all tests validate <payload> Validate webhook payload Examples: ./api_client_test.sh health ./api_client_test.sh notify "Test" "Hello World" ./api_client_test.sh search "ArMatrix" ./api_client_test.sh webhook "https://discord.com/api/webhooks/..." "Hello" Environment Variables: EU_HOST API host EU_PORT API port EU_API_KEY API key DISCORD_WEBHOOK Default Discord webhook URL EOF } # Build curl headers build_headers() { local headers="-H 'Content-Type: application/json'" if [ -n "$API_KEY" ]; then headers="$headers -H 'X-API-Key: $API_KEY'" fi echo "$headers" } # Make HTTP request api_request() { local method=$1 local endpoint=$2 local data=$3 local url="${BASE_URL}${endpoint}" local headers=$(build_headers) if [ -n "$data" ]; then curl -s -X "$method" "$url" $headers -d "$data" else curl -s -X "$method" "$url" $headers fi } # Health check cmd_health() { echo "Checking API health..." local response=$(api_request "GET" "/health") echo "$response" | jq . 2>/dev/null || echo "$response" } # Get status cmd_status() { echo "Getting EU-Utility status..." local response=$(api_request "GET" "/api/v1/status") echo "$response" | jq . 2>/dev/null || echo "$response" } # Send notification cmd_notify() { if [ $# -lt 2 ]; then echo -e "${RED}Error: notify requires title and message${NC}" echo "Usage: notify <title> <message>" return 1 fi local title="$1" local message="$2" local type="${3:-info}" echo "Sending notification..." local data="{\"title\": \"$title\", \"message\": \"$message\", \"type\": \"$type\"}" local response=$(api_request "POST" "/api/v1/notify" "$data") echo "$response" | jq . 2>/dev/null || echo "$response" } # Search Nexus cmd_search() { if [ $# -lt 1 ]; then echo -e "${RED}Error: search requires query${NC}" echo "Usage: search <query>" return 1 fi local query="$1" local entity_type="${2:-items}" echo "Searching Nexus for '$query'..." local response=$(api_request "GET" "/api/v1/search?q=$(echo "$query" | jq -sRr @uri)&type=$entity_type") echo "$response" | jq . 2>/dev/null || echo "$response" } # Record loot cmd_loot() { if [ $# -lt 2 ]; then echo -e "${RED}Error: loot requires value and mob${NC}" echo "Usage: loot <value> <mob>" return 1 fi local value="$1" local mob="$2" local timestamp=$(date +%s) echo "Recording loot..." local data="{\"value\": $value, \"mob\": \"$mob\", \"items\": [], \"timestamp\": $timestamp}" local response=$(api_request "POST" "/api/v1/loot" "$data") echo "$response" | jq . 2>/dev/null || echo "$response" } # Record global cmd_global() { if [ $# -lt 2 ]; then echo -e "${RED}Error: global requires value and mob${NC}" echo "Usage: global <value> <mob>" return 1 fi local value="$1" local mob="$2" local player="${3:-}" local timestamp=$(date +%s) echo "Recording global..." local data="{\"value\": $value, \"mob\": \"$mob\", \"player\": \"$player\", \"timestamp\": $timestamp}" local response=$(api_request "POST" "/api/v1/global" "$data") echo "$response" | jq . 2>/dev/null || echo "$response" } # Send Discord webhook cmd_webhook() { local url="${1:-$DISCORD_WEBHOOK}" local content="${2:-Test message from EU-Utility}" if [ -z "$url" ]; then echo -e "${RED}Error: webhook URL required${NC}" echo "Usage: webhook <url> [message]" echo "Or set DISCORD_WEBHOOK environment variable" return 1 fi echo "Sending Discord webhook..." local data="{\"content\": \"$content\"}" local response=$(curl -s -X POST "$url" \ -H "Content-Type: application/json" \ -d "$data" \ -w "\nHTTP Status: %{http_code}\n") echo "$response" } # Validate webhook payload cmd_validate() { if [ $# -lt 1 ]; then echo -e "${RED}Error: validate requires JSON payload${NC}" echo "Usage: validate '<json_payload>'" return 1 fi local payload="$1" # Basic validation using jq if echo "$payload" | jq empty 2>/dev/null; then echo -e "${GREEN}✅ Valid JSON${NC}" # Check for required fields local has_content=$(echo "$payload" | jq 'has("content")') local has_embeds=$(echo "$payload" | jq 'has("embeds")') if [ "$has_content" = "true" ] || [ "$has_embeds" = "true" ]; then echo -e "${GREEN}✅ Has required field (content or embeds)${NC}" # Check content length if [ "$has_content" = "true" ]; then local content_len=$(echo "$payload" | jq -r '.content // "" | length') if [ "$content_len" -gt 2000 ]; then echo -e "${RED}❌ Content exceeds 2000 character limit ($content_len)${NC}" else echo -e "${GREEN}✅ Content length OK ($content_len)${NC}" fi fi # Check embeds count if [ "$has_embeds" = "true" ]; then local embeds_len=$(echo "$payload" | jq '.embeds | length') if [ "$embeds_len" -gt 10 ]; then echo -e "${RED}❌ Too many embeds (max 10, found $embeds_len)${NC}" else echo -e "${GREEN}✅ Embeds count OK ($embeds_len)${NC}" fi fi else echo -e "${RED}❌ Missing required field: content or embeds${NC}" fi else echo -e "${RED}❌ Invalid JSON${NC}" return 1 fi } # Run all tests cmd_test() { echo "Running all EU-Utility API tests..." echo "======================================" echo "" local tests_passed=0 local tests_failed=0 # Health check echo "Test 1: Health Check" if cmd_health > /dev/null 2>&1; then echo -e "${GREEN}✅ PASSED${NC}" ((tests_passed++)) else echo -e "${RED}❌ FAILED${NC}" ((tests_failed++)) fi # Status echo "" echo "Test 2: Get Status" if cmd_status > /dev/null 2>&1; then echo -e "${GREEN}✅ PASSED${NC}" ((tests_passed++)) else echo -e "${RED}❌ FAILED${NC}" ((tests_failed++)) fi # Notification echo "" echo "Test 3: Send Notification" if cmd_notify "Test" "API Test" > /dev/null 2>&1; then echo -e "${GREEN}✅ PASSED${NC}" ((tests_passed++)) else echo -e "${RED}❌ FAILED${NC}" ((tests_failed++)) fi # Search echo "" echo "Test 4: Search Nexus" if cmd_search "ArMatrix" > /dev/null 2>&1; then echo -e "${GREEN}✅ PASSED${NC}" ((tests_passed++)) else echo -e "${RED}❌ FAILED${NC}" ((tests_failed++)) fi echo "" echo "======================================" echo "Tests completed: $tests_passed passed, $tests_failed failed" } # Main main() { # Parse options while [[ $# -gt 0 ]]; do case $1 in --host) HOST="$2" BASE_URL="http://${HOST}:${PORT}" shift 2 ;; --port) PORT="$2" BASE_URL="http://${HOST}:${PORT}" shift 2 ;; --api-key) API_KEY="$2" shift 2 ;; --help|-h) print_help exit 0 ;; -*) echo -e "${RED}Unknown option: $1${NC}" print_help exit 1 ;; *) break ;; esac done # Check for command if [ $# -eq 0 ]; then print_help exit 1 fi local command=$1 shift # Execute command case $command in health) cmd_health ;; status) cmd_status ;; notify) cmd_notify "$@" ;; search) cmd_search "$@" ;; loot) cmd_loot "$@" ;; global) cmd_global "$@" ;; webhook) cmd_webhook "$@" ;; validate) cmd_validate "$@" ;; test) cmd_test ;; *) echo -e "${RED}Unknown command: $command${NC}" print_help exit 1 ;; esac } # Check for jq if ! command -v jq &> /dev/null; then echo -e "${YELLOW}Warning: jq not found. JSON formatting will be limited.${NC}" echo "Install jq for better JSON output: https://stedolan.github.io/jq/" fi # Run main main "$@"