394 lines
10 KiB
Bash
Executable File
394 lines
10 KiB
Bash
Executable File
#!/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] <command>
|
|
|
|
Options:
|
|
--host <host> API host (default: 127.0.0.1, or EU_HOST env var)
|
|
--port <port> API port (default: 8080, or EU_PORT env var)
|
|
--api-key <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 <title> <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 "$@" |