mirror of
https://github.com/kossakovsky/n8n-install.git
synced 2026-03-07 14:23:08 +00:00
165 lines
5.4 KiB
Bash
Executable File
165 lines
5.4 KiB
Bash
Executable File
#!/bin/bash
|
|
# =============================================================================
|
|
# download_top_workflows.sh - Download popular n8n workflow templates
|
|
# =============================================================================
|
|
# Downloads the most popular workflow templates from n8n's public API,
|
|
# sorted by total views. Useful for seeding a fresh n8n installation with
|
|
# community-vetted examples.
|
|
#
|
|
# Features:
|
|
# - Fetches workflow metadata from n8n API (paginated)
|
|
# - Sorts by totalViews (most popular first)
|
|
# - Removes duplicates by workflow ID
|
|
# - Downloads full workflow JSON ready for n8n import
|
|
# - Configurable count and output directory
|
|
#
|
|
# Usage: bash scripts/download_top_workflows.sh [count] [output_dir]
|
|
# count - Number of workflows to download (default: 500)
|
|
# output_dir - Directory to save workflows (default: workflows)
|
|
#
|
|
# Examples:
|
|
# bash scripts/download_top_workflows.sh # Download top 500
|
|
# bash scripts/download_top_workflows.sh 100 # Download top 100
|
|
# bash scripts/download_top_workflows.sh 200 /tmp # Download 200 to /tmp
|
|
# =============================================================================
|
|
|
|
set -e
|
|
|
|
# Source the utilities file
|
|
source "$(dirname "$0")/utils.sh"
|
|
|
|
# --- Configuration ---
|
|
COUNT=${1:-500}
|
|
OUTPUT_DIR=${2:-workflows}
|
|
API_BASE="https://api.n8n.io/api/templates"
|
|
ROWS_PER_PAGE=100
|
|
MAX_PAGES=80
|
|
|
|
# --- Require dependencies ---
|
|
require_command "curl" "Please install curl to use this script."
|
|
require_command "jq" "Please install jq to use this script."
|
|
|
|
# --- Helper functions ---
|
|
|
|
# Generate a random 16-character base62 ID (like n8n workflow IDs)
|
|
generate_workflow_id() {
|
|
cat /dev/urandom | LC_ALL=C tr -dc 'a-zA-Z0-9' | head -c 16
|
|
}
|
|
|
|
# Generate a UUID v4 (for versionId)
|
|
generate_version_id() {
|
|
if command -v uuidgen &> /dev/null; then
|
|
uuidgen | tr '[:upper:]' '[:lower:]'
|
|
else
|
|
# Fallback for systems without uuidgen
|
|
cat /proc/sys/kernel/random/uuid 2>/dev/null || \
|
|
printf '%04x%04x-%04x-%04x-%04x-%04x%04x%04x' \
|
|
$RANDOM $RANDOM $RANDOM $(($RANDOM & 0x0fff | 0x4000)) \
|
|
$(($RANDOM & 0x3fff | 0x8000)) $RANDOM $RANDOM $RANDOM
|
|
fi
|
|
}
|
|
|
|
# Convert filename slug to readable name
|
|
# "ai-agent-chat" -> "Ai agent chat"
|
|
slug_to_name() {
|
|
local slug="$1"
|
|
# Replace dashes with spaces, capitalize first letter only
|
|
local with_spaces=$(echo "$slug" | sed 's/-/ /g')
|
|
# Capitalize first character
|
|
echo "$(echo "${with_spaces:0:1}" | tr '[:lower:]' '[:upper:]')${with_spaces:1}"
|
|
}
|
|
|
|
# --- Main ---
|
|
log_header "n8n Workflow Downloader"
|
|
log_info "Target: $COUNT most popular workflows"
|
|
log_info "Output: $OUTPUT_DIR/"
|
|
|
|
mkdir -p "$OUTPUT_DIR"
|
|
|
|
# Temporary file for metadata
|
|
TEMP_FILE=$(mktemp)
|
|
trap "rm -f $TEMP_FILE" EXIT
|
|
|
|
# Step 1: Fetch all workflow metadata
|
|
log_subheader "Fetching workflow metadata"
|
|
|
|
for page in $(seq 1 $MAX_PAGES); do
|
|
result=$(curl -s "${API_BASE}/search?rows=${ROWS_PER_PAGE}&page=${page}")
|
|
count=$(echo "$result" | jq '.workflows | length' 2>/dev/null || echo "0")
|
|
|
|
if [ "$count" -eq 0 ] 2>/dev/null; then
|
|
log_info "Completed at page $page (no more data)"
|
|
break
|
|
fi
|
|
|
|
echo "$result" | jq -c '.workflows[] | {id, name, totalViews}' 2>/dev/null >> "$TEMP_FILE"
|
|
|
|
if [ $((page % 10)) -eq 0 ]; then
|
|
log_info "Fetched page $page..."
|
|
fi
|
|
done
|
|
|
|
# Step 2: Sort by totalViews, remove duplicates, take top N
|
|
log_subheader "Selecting top $COUNT workflows"
|
|
|
|
TOP_IDS=$(cat "$TEMP_FILE" | jq -s "unique_by(.id) | sort_by(-.totalViews) | .[0:${COUNT}] | .[].id")
|
|
TOTAL=$(echo "$TOP_IDS" | wc -l | tr -d ' ')
|
|
|
|
log_info "Found $TOTAL unique workflows to download"
|
|
|
|
# Step 3: Download each workflow
|
|
log_subheader "Downloading workflows"
|
|
|
|
downloaded=0
|
|
failed=0
|
|
|
|
for id in $TOP_IDS; do
|
|
downloaded=$((downloaded + 1))
|
|
|
|
# Get workflow data
|
|
workflow_data=$(curl -s "${API_BASE}/workflows/${id}")
|
|
|
|
if echo "$workflow_data" | jq -e '.workflow' > /dev/null 2>&1; then
|
|
# Extract name for filename (sanitize: lowercase, replace non-alphanum with dash)
|
|
name=$(echo "$workflow_data" | jq -r '.workflow.name // "unnamed"' | \
|
|
tr '[:upper:]' '[:lower:]' | \
|
|
sed 's/[^a-z0-9]/-/g' | \
|
|
sed 's/--*/-/g' | \
|
|
sed 's/^-//;s/-$//' | \
|
|
cut -c1-50)
|
|
|
|
filename="${id}_${name}.json"
|
|
|
|
# Generate n8n-compatible metadata
|
|
workflow_name=$(slug_to_name "$name")
|
|
workflow_id=$(generate_workflow_id)
|
|
version_id=$(generate_version_id)
|
|
|
|
# Extract workflow and add required metadata (name, active, id, versionId)
|
|
echo "$workflow_data" | jq --arg name "$workflow_name" \
|
|
--arg id "$workflow_id" \
|
|
--arg versionId "$version_id" \
|
|
'.workflow.workflow + {name: $name, active: false, id: $id, versionId: $versionId}' \
|
|
> "$OUTPUT_DIR/$filename"
|
|
|
|
if [ $((downloaded % 50)) -eq 0 ]; then
|
|
log_info "Downloaded $downloaded/$TOTAL..."
|
|
fi
|
|
else
|
|
log_warning "Failed to download workflow $id"
|
|
failed=$((failed + 1))
|
|
fi
|
|
|
|
# Small delay to be nice to the API
|
|
sleep 0.1
|
|
done
|
|
|
|
# Summary
|
|
log_divider
|
|
log_success "Download complete!"
|
|
log_info "Downloaded: $((downloaded - failed))/$TOTAL workflows"
|
|
if [ $failed -gt 0 ]; then
|
|
log_warning "Failed: $failed"
|
|
fi
|
|
log_info "Location: $OUTPUT_DIR/"
|