160 lines
3.3 KiB
Bash
Executable File
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
|