Files
swarm-zap/skills/n8n-webhook/scripts/call-webhook.sh

160 lines
3.3 KiB
Bash
Executable File

#!/usr/bin/env bash
set -euo pipefail
usage() {
cat <<'EOF'
Usage:
scripts/call-webhook.sh <path-or-url> [--data '{"k":"v"}'] [--data-file payload.json] [--test] [--pretty] [--dry-run]
Environment:
N8N_BASE_URL Base n8n URL (default: http://192.168.153.113:18808)
N8N_WEBHOOK_SECRET Shared secret value for header auth (required unless --dry-run)
N8N_SECRET_HEADER Header name for shared secret (default: x-openclaw-secret)
Examples:
scripts/call-webhook.sh openclaw-ping --data '{"message":"hello"}'
scripts/call-webhook.sh openclaw-ping --test --data-file payload.json
echo '{"message":"hello"}' | scripts/call-webhook.sh openclaw-ping --pretty
EOF
}
BASE_URL="${N8N_BASE_URL:-http://192.168.153.113:18808}"
SECRET_HEADER="${N8N_SECRET_HEADER:-x-openclaw-secret}"
SECRET_VALUE="${N8N_WEBHOOK_SECRET:-}"
MODE="prod"
PRETTY=0
DRY_RUN=0
PATH_OR_URL=""
DATA=""
DATA_FILE=""
while [[ $# -gt 0 ]]; do
case "$1" in
--help|-h)
usage
exit 0
;;
--test)
MODE="test"
shift
;;
--prod)
MODE="prod"
shift
;;
--pretty)
PRETTY=1
shift
;;
--dry-run)
DRY_RUN=1
shift
;;
--data)
DATA="${2:?missing value for --data}"
shift 2
;;
--data-file)
DATA_FILE="${2:?missing value for --data-file}"
shift 2
;;
--*)
echo "Unknown option: $1" >&2
usage >&2
exit 2
;;
*)
if [[ -z "$PATH_OR_URL" ]]; then
PATH_OR_URL="$1"
else
echo "Unexpected extra argument: $1" >&2
usage >&2
exit 2
fi
shift
;;
esac
done
if [[ -z "$PATH_OR_URL" ]]; then
usage >&2
exit 2
fi
if [[ -n "$DATA" && -n "$DATA_FILE" ]]; then
echo "Use either --data or --data-file, not both." >&2
exit 2
fi
if [[ -n "$DATA_FILE" ]]; then
DATA="$(cat "$DATA_FILE")"
elif [[ -n "$DATA" ]]; then
:
elif ! [[ -t 0 ]]; then
DATA="$(cat)"
else
DATA='{}'
fi
python3 - <<'PY' "$DATA"
import json, sys
json.loads(sys.argv[1])
PY
if [[ "$PATH_OR_URL" =~ ^https?:// ]]; then
URL="$PATH_OR_URL"
else
PREFIX="webhook"
[[ "$MODE" == "test" ]] && PREFIX="webhook-test"
URL="${BASE_URL%/}/${PREFIX}/${PATH_OR_URL#/}"
fi
if [[ "$DRY_RUN" -eq 1 ]]; then
printf 'POST %s\n' "$URL"
printf 'Header: Content-Type: application/json\n'
if [[ -n "$SECRET_VALUE" ]]; then
printf 'Header: %s: [set]\n' "$SECRET_HEADER"
else
printf 'Header: %s: [missing]\n' "$SECRET_HEADER"
fi
printf 'Body: %s\n' "$DATA"
exit 0
fi
if [[ -z "$SECRET_VALUE" ]]; then
echo "N8N_WEBHOOK_SECRET is required for non-dry-run calls." >&2
exit 2
fi
BODY_FILE="$(mktemp)"
trap 'rm -f "$BODY_FILE"' EXIT
HTTP_CODE="$({
curl -sS \
-o "$BODY_FILE" \
-w '%{http_code}' \
-X POST "$URL" \
-H 'Content-Type: application/json' \
-H "$SECRET_HEADER: $SECRET_VALUE" \
--data "$DATA"
} || true)"
if [[ -z "$HTTP_CODE" ]]; then
echo "Request failed before receiving an HTTP status." >&2
cat "$BODY_FILE" >&2 || true
exit 1
fi
if [[ "$HTTP_CODE" =~ ^2[0-9][0-9]$ ]]; then
if [[ "$PRETTY" -eq 1 ]]; then
python3 -m json.tool "$BODY_FILE" 2>/dev/null || cat "$BODY_FILE"
else
cat "$BODY_FILE"
fi
exit 0
fi
echo "n8n webhook call failed with HTTP $HTTP_CODE" >&2
cat "$BODY_FILE" >&2 || true
exit 1