Jump to:
n8n Workflow Export & Import
Export All Workflows
BASHExport all n8n workflows to JSON files for backup/version control
# Using n8n CLI (if installed)
n8n export:workflow --all --output=./workflows/
# Or via API
curl -u "admin:password" \
"http://10.0.0.250:5678/api/v1/workflows" \
| jq '.data[] | {name: .name, id: .id}' > workflows-list.json
# Export individual workflow
curl -u "admin:password" \
"http://10.0.0.250:5678/api/v1/workflows/1" \
> workflow-scan-intake.json
Import Workflow from JSON
BASH# Via n8n CLI n8n import:workflow --input=./workflow-scan-intake.json # Via API curl -X POST "http://10.0.0.250:5678/api/v1/workflows" \ -u "admin:password" \ -H "Content-Type: application/json" \ -d @workflow-scan-intake.json
Activate/Deactivate Workflow
BASH# Activate workflow
curl -X PATCH "http://10.0.0.250:5678/api/v1/workflows/1" \
-u "admin:password" \
-H "Content-Type: application/json" \
-d '{"active": true}'
# Deactivate workflow
curl -X PATCH "http://10.0.0.250:5678/api/v1/workflows/1" \
-u "admin:password" \
-H "Content-Type: application/json" \
-d '{"active": false}'
PostgreSQL Commands
Connect to Database
BASH# Connect to PostgreSQL container on bennybeen (10.0.0.250) docker exec -it mm-postgres psql -U mm_user -d madmonkey # Or from host (if port exposed) psql -h 10.0.0.250 -U mm_user -d madmonkey # Connection string format postgresql://mm_user:PASSWORD@10.0.0.250:5432/madmonkey
Create Database and Tables
SQL-- Create database
CREATE DATABASE madmonkey;
-- Connect to database
\c madmonkey
-- Create cards table
CREATE TABLE cards (
qr_id VARCHAR(10) PRIMARY KEY,
type VARCHAR(10) NOT NULL,
status VARCHAR(20) DEFAULT 'active',
current_slug VARCHAR(50),
move_code VARCHAR(20) UNIQUE,
last_scan_ts TIMESTAMP,
last_scan_city VARCHAR(100),
total_scans INTEGER DEFAULT 0,
created_at TIMESTAMP DEFAULT NOW(),
updated_at TIMESTAMP DEFAULT NOW()
);
-- Add indexes
CREATE INDEX idx_cards_type ON cards(type);
CREATE INDEX idx_cards_status ON cards(status);
CREATE INDEX idx_cards_last_scan_ts ON cards(last_scan_ts);
Common Queries
SQL-- Get all verified entries for current month SELECT * FROM entries WHERE verified = true AND month_bucket = TO_CHAR(NOW(), 'YYYY-MM') ORDER BY created_at DESC; -- Get top 10 most scanned cards SELECT qr_id, type, total_scans, last_scan_city FROM cards ORDER BY total_scans DESC LIMIT 10; -- Find stuck cards (no scans in 10+ days) SELECT qr_id, type, last_scan_ts, last_scan_city FROM cards WHERE last_scan_ts < NOW() - INTERVAL '10 days' AND status = 'active' ORDER BY last_scan_ts ASC; -- Get monthly contest entries by city SELECT user_city, COUNT(*) as entries FROM entries WHERE verified = true AND month_bucket = '2024-12' GROUP BY user_city ORDER BY entries DESC; -- Select random winner for the month SELECT entry_id, email, name, qr_id FROM entries WHERE verified = true AND month_bucket = '2024-12' ORDER BY RANDOM() LIMIT 1;
Database Backup & Restore
BASH# Backup database docker exec mm-postgres pg_dump -U mm_user madmonkey > backup-$(date +%Y%m%d).sql # Or with compression docker exec mm-postgres pg_dump -U mm_user madmonkey | gzip > backup-$(date +%Y%m%d).sql.gz # Restore database docker exec -i mm-postgres psql -U mm_user madmonkey < backup-20241201.sql # Restore from compressed backup gunzip -c backup-20241201.sql.gz | docker exec -i mm-postgres psql -U mm_user madmonkey
Webhook Testing with cURL
Test Scan Webhook
BASH# Simple GET request (simulates QR scan) curl -L "https://hooks.mad-monkey-creations.com/scan?qr_id=T42" # With custom headers (simulate mobile device) curl -L "https://hooks.mad-monkey-creations.com/scan?qr_id=T42" \ -H "User-Agent: Mozilla/5.0 (iPhone; CPU iPhone OS 17_0 like Mac OS X) AppleWebKit/605.1.15" \ -H "X-Forwarded-For: 203.0.113.42" # Follow redirects and show headers curl -L -v "https://hooks.mad-monkey-creations.com/scan?qr_id=T42"
Test Entry Submission Webhook
BASH# Submit test entry
curl -X POST "https://hooks.mad-monkey-creations.com/entry" \
-H "Content-Type: application/json" \
-d '{
"qr_id": "T42",
"email": "test@example.com",
"name": "John Doe",
"user_city": "Chicago, IL",
"consent": true
}'
# Submit with verbose output
curl -v -X POST "https://hooks.mad-monkey-creations.com/entry" \
-H "Content-Type: application/json" \
-d @test-entry.json
Shlink API Commands
Create Short URLs
BASH# Create single short URL (Shlink on bennybeen @ 10.0.0.250:8081)
curl -X POST "http://10.0.0.250:8081/rest/v3/short-urls" \
-H "X-Api-Key: your-api-key" \
-H "Content-Type: application/json" \
-d '{
"longUrl": "https://hooks.mad-monkey-creations.com/scan?qr_id=T42",
"customSlug": "T42",
"domain": "mmlnk.us",
"tags": ["benny", "traveler"]
}'
# Bulk create short URLs (using loop)
for i in {1..10}; do
QR_ID=$(printf "T%03d" $i)
curl -X POST "http://10.0.0.250:8081/rest/v3/short-urls" \
-H "X-Api-Key: your-api-key" \
-H "Content-Type: application/json" \
-d "{
\"longUrl\": \"https://hooks.mad-monkey-creations.com/scan?qr_id=$QR_ID\",
\"customSlug\": \"$QR_ID\",
\"domain\": \"mmlnk.us\",
\"tags\": [\"benny\", \"traveler\"]
}"
echo "Created: https://mmlnk.us/$QR_ID"
done
List and Search Short URLs
BASH# List all short URLs curl "http://10.0.0.250:8081/rest/v3/short-urls" \ -H "X-Api-Key: your-api-key" # Search by tag curl "http://10.0.0.250:8081/rest/v3/short-urls?tags[]=traveler" \ -H "X-Api-Key: your-api-key" # Paginated results curl "http://10.0.0.250:8081/rest/v3/short-urls?page=1&itemsPerPage=50" \ -H "X-Api-Key: your-api-key"
Generate Shlink API Key
BASH# Generate API key using Shlink CLI in container docker exec mm-shlink shlink api-key:generate # Generate with specific permissions docker exec mm-shlink shlink api-key:generate \ --name="n8n-integration" \ --role-name="Domain" # List all API keys docker exec mm-shlink shlink api-key:list
Network & Port Scanning
Check Port Status
BASH# Check if port is open (telnet) - All services on bennybeen (10.0.0.250) telnet 10.0.0.250 5432 # Check with netcat nc -zv 10.0.0.250 5432 # Check multiple ports on Docker host for port in 5432 5678 8080 8081 9000; do nc -zv -w 2 10.0.0.250 $port done # Use nmap for comprehensive scan nmap -p 5432,5678,8080,8081,9000 10.0.0.250
Check Service Availability
BASH# Check if PostgreSQL is accepting connections (all services on 10.0.0.250)
pg_isready -h 10.0.0.250 -p 5432 -U mm_user
# Check HTTP services on bennybeen
curl -I http://10.0.0.250:8081 # Shlink
curl -I http://10.0.0.250:9000 # Listmonk
# Check with timeout
timeout 5 curl -I http://10.0.0.250:5678 || echo "n8n unavailable"
# Check all Mad Monkey services on single Docker host
for service in "10.0.0.250:5432" "10.0.0.250:5678" "10.0.0.250:8080" "10.0.0.250:8081" "10.0.0.250:9000"; do
echo "Checking $service..."
nc -zv -w 2 ${service/:/ } && echo "OK" || echo "FAILED"
done
Node.js Setup
Install Node.js via NVM
BASH# Install NVM curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.0/install.sh | bash # Load NVM export NVM_DIR="$HOME/.nvm" [ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" # Install Node.js 24.12.0 nvm install 24.12.0 nvm use 24.12.0 nvm alias default 24.12.0 # Verify installation node --version # v24.12.0 npm --version # 9.2.0 # Make available system-wide (create symlink) sudo ln -s "$NVM_DIR/versions/node/$(nvm version)/bin/node" /usr/local/bin/node sudo ln -s "$NVM_DIR/versions/node/$(nvm version)/bin/npm" /usr/local/bin/npm
Install QR Code Generator
BASH# Install mini-qr globally
npm install -g mini-qr
# Or install locally in project
mkdir qr-generator && cd qr-generator
npm init -y
npm install mini-qr
# Generate QR code
mini-qr "https://mmlnk.us/T42" -o T42.png
# Generate SVG
mini-qr "https://mmlnk.us/T42" -o T42.svg -t svg
# Generate multiple QR codes
for i in {1..10}; do
QR_ID=$(printf "T%03d" $i)
mini-qr "https://mmlnk.us/$QR_ID" -o "qr-codes/${QR_ID}.png"
echo "Generated: ${QR_ID}.png"
done
Email & DNS Verification
Check DNS Records
BASH# Check A record dig mmlnk.us A +short dig mad-monkey-creations.com A +short # Check MX record dig mad-monkey-creations.com MX +short # Check TXT records (SPF, DKIM, DMARC) dig mad-monkey-creations.com TXT +short dig _dmarc.mad-monkey-creations.com TXT +short dig default._domainkey.mad-monkey-creations.com TXT +short # Use nslookup (alternative) nslookup -type=MX mad-monkey-creations.com nslookup -type=TXT mad-monkey-creations.com # Check DNS propagation dig @8.8.8.8 mmlnk.us # Google DNS dig @1.1.1.1 mmlnk.us # Cloudflare DNS
Test SMTP Connection
BASH# Test SMTP with openssl (ForwardMail.net - ONLY email provider) openssl s_client -connect smtp.forwardemail.net:587 -starttls smtp # Send test email via command line cat > test-email.txt << EOF From: hello@mad-monkey-creations.com To: test@example.com Subject: Test Email This is a test email from Mad Monkey Creations. EOF # Send via SMTP (requires mailx or similar) cat test-email.txt | sendmail -v test@example.com
Docker Container Management
BASH# Start all Mad Monkey containers docker-compose -f docker-compose-postgres.yml up -d docker-compose -f docker-compose-shlink.yml up -d docker-compose -f docker-compose-listmonk.yml up -d # Check container status docker ps | grep mm- # View logs docker logs -f mm-postgres docker logs -f mm-shlink --tail 100 docker logs -f mm-listmonk # Restart containers docker restart mm-postgres mm-shlink mm-listmonk # Stop all containers docker stop mm-postgres mm-shlink mm-listmonk # Remove containers (data persists in volumes) docker rm mm-postgres mm-shlink mm-listmonk # View volumes docker volume ls | grep mm
Environment Variables Template
BASH# .env file for Mad Monkey project # Copy to .env and fill in actual values # All services run on single Docker host: bennybeen (10.0.0.250) # Server Configuration SERVER_HOST=10.0.0.250 EXTERNAL_IP=76.150.65.61 # DYNAMIC - can change! PROJECT_PATH=/home/bennybeen/mad-monkey/ # PostgreSQL (on 10.0.0.250:5432) POSTGRES_PASSWORD=YOUR_STRONG_PASSWORD_HERE DB_HOST=10.0.0.250 DB_PORT=5432 DB_NAME=madmonkey DB_USER=mm_user # n8n (on 10.0.0.250:5678) N8N_ENCRYPTION_KEY=GENERATE_RANDOM_KEY N8N_BASIC_AUTH_USER=admin N8N_BASIC_AUTH_PASSWORD=YOUR_PASSWORD N8N_URL=http://10.0.0.250:5678 # Listmonk (on 10.0.0.250:9000) LISTMONK_URL=http://10.0.0.250:9000 LISTMONK_API_USER=admin LISTMONK_API_PASSWORD=YOUR_PASSWORD LISTMONK_LIST_ID=1 # Shlink (on 10.0.0.250:8081) SHLINK_URL=http://10.0.0.250:8081 SHLINK_API_KEY=GENERATE_VIA_CLI DEFAULT_DOMAIN=mmlnk.us # Email (ForwardMail.net - ONLY provider) SMTP_HOST=smtp.forwardemail.net SMTP_PORT=587 SMTP_USER=hello@mad-monkey-creations.com SMTP_PASS=YOUR_SMTP_PASSWORD MM_SENDER_EMAIL=hello@mad-monkey-creations.com # Application MM_LANDING_BASE=https://www.mad-monkey-creations.com MM_REWARD_URL=https://www.mad-monkey-creations.com/reward MM_DISCOUNT_CODE=BANANAS10 # To load in shell: # export $(cat .env | xargs)