#!/bin/bash # class-watcher.sh — Watches /mnt/data/class-recordings for new .wav files # and POSTs them to the n8n class/upload webhook. # Saves the transcript + notes response as a .md file alongside the recording. # # Install: # 1. Copy to PD: scp class-watcher.sh truenas_admin@10.5.1.6:/tmp/class-watcher.sh # 2. sudo mv /tmp/class-watcher.sh /mnt/data/class-watcher.sh # 3. sudo chmod +x /mnt/data/class-watcher.sh # 4. sudo crontab -e # * * * * * /mnt/data/class-watcher.sh >> /var/log/class-watcher.log 2>&1 # # Folder structure after processing: # /mnt/data/class-recordings/ # └── CS101-Java/ # ├── new-lecture.wav ← waiting to be processed # └── done/ # ├── lecture-01-intro.wav ← already processed # └── lecture-01-intro.md ← transcript + notes WATCH_DIR="/mnt/data/class-recordings" WEBHOOK_URL="http://10.5.1.6:5678/webhook/class/upload" # Find all .wav files directly inside class subfolders (not in done/) find "$WATCH_DIR" -mindepth 2 -maxdepth 2 -name '*.wav' -type f | while read -r filepath; do # Skip files in 'done' directories if echo "$filepath" | grep -q '/done/'; then continue fi # Extract class name from parent folder class_dir=$(dirname "$filepath") class_name=$(basename "$class_dir") file_name=$(basename "$filepath") lecture_title="${file_name%.wav}" echo "[$(date)] Processing: $filepath (class: $class_name)" # Create done folder mkdir -p "$class_dir/done" # POST the file to n8n webhook and capture the response response=$(curl -s -X POST "$WEBHOOK_URL" \ -H "X-Class-Name: $class_name" \ -H "X-Lecture-Title: $lecture_title" \ -F "data=@$filepath" \ -F "class_name=$class_name" \ -F "lecture_title=$lecture_title" \ -F "filename=$file_name" \ -w "\n%{http_code}" 2>/dev/null) http_code=$(echo "$response" | tail -1) body=$(echo "$response" | sed '$d') echo "[$(date)] HTTP $http_code" # Save the transcript + notes as markdown md_file="$class_dir/done/${lecture_title}.md" # Try to parse JSON response and format as markdown if command -v python3 &>/dev/null; then echo "$body" | python3 -c " import json, sys try: data = json.load(sys.stdin) # Handle array response from n8n if isinstance(data, list): data = data[0] if data else {} cn = data.get('className', '$class_name') lt = data.get('lectureTitle', '$lecture_title') dm = data.get('durationMinutes', '?') notes = data.get('notes', {}) summary = notes.get('summary', 'No summary available') concepts = notes.get('key_concepts', []) defs = notes.get('definitions', []) assignments = notes.get('assignments', []) transcript = data.get('timestampedText', data.get('fullText', 'No transcript')) print(f'# {cn} — {lt}') print(f'**Duration:** {dm} minutes') print() print('## Summary') print(summary) print() if concepts: print('## Key Concepts') for c in concepts: print(f'- {c}') print() if defs: print('## Definitions') for d in defs: if isinstance(d, dict): print(f'- **{d.get(\"term\", \"\")}**: {d.get(\"definition\", \"\")}') else: print(f'- {d}') print() if assignments: print('## Assignments') for a in assignments: print(f'- {a}') print() print('## Full Transcript') print(transcript) except Exception as e: print(f'# {\"$class_name\"} — {\"$lecture_title\"}') print() print('## Raw Response') print(sys.stdin.read() if not data else json.dumps(data, indent=2)) " > "$md_file" 2>/dev/null else # Fallback: save raw JSON echo "$body" > "$md_file" fi echo "[$(date)] Saved notes to: $md_file" # Move wav to done folder mv "$filepath" "$class_dir/done/$file_name" echo "[$(date)] Moved to: $class_dir/done/$file_name" done