{
  "name": "Patient Intake Form Processor for Healthcare",
  "nodes": [
    {
      "parameters": {
        "content": "## \ud83c\udfe5 Patient Intake Processor\n\n### HIPAA Compliance Note\nThis workflow processes PHI. Ensure:\n- n8n is self-hosted securely\n- All connections use encryption\n- Access is restricted\n- Audit logs are enabled\n\n### What this workflow does\n1. Watches folder for intake forms\n2. Extracts patient information\n3. Creates patient record\n4. Checks for critical allergies\n5. Alerts medical staff via Slack\n\n### Setup steps\n1. Create \"Intake Forms\" folder in Drive\n2. Get PDF Vector API key from pdfvector.com/api-keys\n3. Create Google Sheet with columns below\n4. Connect Slack (2 channels: alerts + front desk)\n5. Update folder ID, Sheet ID, channel IDs\n\n### Sheet columns\nPatient ID, Name, DOB, Age, Gender, Phone, Email, Insurance, Conditions, Medications, Allergies, Reason for Visit, Emergency Contact, Intake Date\n\n### Perfect for\n- Medical clinics\n- Urgent care centers\n- Healthcare practices",
        "height": 560,
        "width": 340,
        "color": 5
      },
      "id": "sticky-main",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        60,
        60
      ]
    },
    {
      "parameters": {
        "content": "## \ud83d\udea8 Critical Allergy Detection\n\nAuto-alerts for these allergens:\n- Penicillin\n- Sulfa\n- Latex\n- Iodine\n\nEdit the Code node to add more.",
        "height": 180,
        "width": 240
      },
      "id": "sticky-allergy",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        720,
        60
      ]
    },
    {
      "parameters": {
        "pollTimes": {
          "item": [
            {
              "mode": "everyMinute"
            }
          ]
        },
        "triggerOn": "specificFolder",
        "folderToWatch": {
          "__rl": true,
          "value": "YOUR_FOLDER_ID",
          "mode": "list"
        },
        "event": "fileCreated",
        "options": {}
      },
      "id": "gdrive-trigger",
      "name": "Google Drive Trigger",
      "type": "n8n-nodes-base.googleDriveTrigger",
      "typeVersion": 1,
      "position": [
        140,
        360
      ],
      "credentials": {
        "googleDriveOAuth2Api": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "operation": "download",
        "fileId": {
          "__rl": true,
          "value": "={{ $json.id }}",
          "mode": "id"
        },
        "options": {}
      },
      "id": "gdrive-download",
      "name": "Download File",
      "type": "n8n-nodes-base.googleDrive",
      "typeVersion": 3,
      "position": [
        340,
        360
      ],
      "credentials": {
        "googleDriveOAuth2Api": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "operation": "extract",
        "inputType": "file",
        "prompt": "Extract patient intake form data as flat fields. firstName, lastName, dateOfBirth (YYYY-MM-DD), gender, ssnLast4, phone, email, address, insuranceProvider, policyNumber, groupNumber, subscriberName, subscriberRelation, medicalConditions (semicolon-separated list), pastSurgeries (semicolon-separated list), familyHistory (semicolon-separated list), currentMedications (semicolon-separated list formatted as: name dosage frequency), allergiesList (semicolon-separated list formatted as: allergen reaction), emergencyContactName, emergencyContactRelation, emergencyContactPhone, reasonForVisit.",
        "schema": "{\"type\": \"object\", \"properties\": {\"firstName\": {\"type\": \"string\"}, \"lastName\": {\"type\": \"string\"}, \"dateOfBirth\": {\"type\": \"string\"}, \"gender\": {\"type\": \"string\"}, \"ssnLast4\": {\"type\": \"string\"}, \"phone\": {\"type\": \"string\"}, \"email\": {\"type\": \"string\"}, \"address\": {\"type\": \"string\"}, \"insuranceProvider\": {\"type\": \"string\"}, \"policyNumber\": {\"type\": \"string\"}, \"groupNumber\": {\"type\": \"string\"}, \"subscriberName\": {\"type\": \"string\"}, \"subscriberRelation\": {\"type\": \"string\"}, \"medicalConditions\": {\"type\": \"string\"}, \"pastSurgeries\": {\"type\": \"string\"}, \"familyHistory\": {\"type\": \"string\"}, \"currentMedications\": {\"type\": \"string\"}, \"allergiesList\": {\"type\": \"string\"}, \"emergencyContactName\": {\"type\": \"string\"}, \"emergencyContactRelation\": {\"type\": \"string\"}, \"emergencyContactPhone\": {\"type\": \"string\"}, \"reasonForVisit\": {\"type\": \"string\"}}, \"additionalProperties\": false}"
      },
      "id": "pdfvector-extract",
      "name": "PDF Vector - Extract Intake",
      "type": "n8n-nodes-pdfvector.pdfVector",
      "typeVersion": 2,
      "position": [
        540,
        360
      ],
      "credentials": {
        "pdfVectorApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "jsCode": "const data = ($input.first().json?.data || $input.first().json) || {};\n\nconst patientId = `PT-${Date.now().toString(36).toUpperCase()}`;\n\nlet age = 'N/A';\nif (data.dateOfBirth) {\n  const dob = new Date(data.dateOfBirth);\n  const today = new Date();\n  age = Math.floor((today - dob) / (365.25 * 24 * 60 * 60 * 1000));\n}\n\nconst criticalAllergens = ['penicillin', 'sulfa', 'latex', 'iodine', 'aspirin', 'nsaid'];\nconst allergiesStr = (data.allergiesList || '').toLowerCase();\nconst hasCriticalAllergy = criticalAllergens.some(c => allergiesStr.includes(c));\n\nconst insuranceSummary = data.insuranceProvider\n  ? `${data.insuranceProvider} - ${data.policyNumber || 'N/A'}`\n  : 'Self-Pay';\n\nreturn [{ json: {\n  patientId,\n  fullName:             `${data.firstName || ''} ${data.lastName || ''}`.trim() || 'Unknown',\n  dateOfBirth:          data.dateOfBirth          || 'N/A',\n  gender:               data.gender               || 'N/A',\n  phone:                data.phone                || 'N/A',\n  email:                data.email                || 'N/A',\n  address:              data.address              || 'N/A',\n  age,\n  insuranceSummary,\n  medicalConditions:    data.medicalConditions    || 'None reported',\n  currentMedications:   data.currentMedications   || 'None reported',\n  allergiesList:        data.allergiesList         || 'NKDA',\n  emergencyContactName: data.emergencyContactName || 'N/A',\n  emergencyContactPhone: data.emergencyContactPhone || 'N/A',\n  reasonForVisit:       data.reasonForVisit       || 'Not specified',\n  hasCriticalAllergy,\n  processedAt: new Date().toISOString()\n}}];"
      },
      "id": "process-intake",
      "name": "Process Intake Data",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        740,
        360
      ]
    },
    {
      "parameters": {
        "operation": "append",
        "documentId": {
          "__rl": true,
          "value": "YOUR_SPREADSHEET_ID",
          "mode": "list"
        },
        "sheetName": {
          "__rl": true,
          "value": "gid=0",
          "mode": "list"
        },
        "columns": {
          "mappingMode": "defineBelow",
          "value": {
            "Patient ID": "={{ $json.patientId }}",
            "Name": "={{ $json.fullName }}",
            "DOB": "={{ $json.dateOfBirth }}",
            "Age": "={{ $json.age }}",
            "Gender": "={{ $json.gender || 'N/A' }}",
            "Phone": "={{ $json.phone || 'N/A' }}",
            "Email": "={{ $json.email || 'N/A' }}",
            "Insurance": "={{ $json.insuranceSummary }}",
            "Conditions": "={{ $json.medicalConditions }}",
            "Medications": "={{ $json.currentMedications }}",
            "Allergies": "={{ $json.allergiesList }}",
            "Reason for Visit": "={{ $json.reasonForVisit }}",
            "Emergency Contact": "={{ $json.emergencyContact ? $json.emergencyContact.name + ' (' + $json.emergencyContact.phone + ')' : 'N/A' }}",
            "Intake Date": "={{ $json.processedAt.split('T')[0] }}"
          }
        },
        "options": {}
      },
      "id": "sheets-log",
      "name": "Create Patient Record",
      "type": "n8n-nodes-base.googleSheets",
      "typeVersion": 4.4,
      "position": [
        940,
        360
      ],
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "strict"
          },
          "conditions": [
            {
              "id": "critical-allergy-check",
              "leftValue": "={{ $('Process Intake Data').item.json.hasCriticalAllergy }}",
              "rightValue": true,
              "operator": {
                "type": "boolean",
                "operation": "equals"
              }
            }
          ],
          "combinator": "and"
        },
        "options": {}
      },
      "id": "if-critical",
      "name": "Critical Allergy?",
      "type": "n8n-nodes-base.if",
      "typeVersion": 2.2,
      "position": [
        1140,
        360
      ]
    },
    {
      "parameters": {
        "authentication": "oAuth2",
        "select": "channel",
        "channelId": {
          "__rl": true,
          "value": "YOUR_ALERTS_CHANNEL_ID",
          "mode": "list"
        },
        "text": "=\ud83d\udea8 *CRITICAL ALLERGY ALERT*\n\n*Patient:* {{ $('Process Intake Data').item.json.fullName }}\n*Patient ID:* {{ $('Process Intake Data').item.json.patientId }}\n*DOB:* {{ $('Process Intake Data').item.json.dateOfBirth }}\n\n\u26a0\ufe0f *ALLERGIES:* {{ $json.Allergies }}\n\n*Reason for Visit:* {{ $('Process Intake Data').item.json.reasonForVisit }}",
        "otherOptions": {}
      },
      "id": "slack-alert",
      "name": "Critical Alert",
      "type": "n8n-nodes-base.slack",
      "typeVersion": 2.2,
      "position": [
        1340,
        260
      ],
      "credentials": {
        "slackOAuth2Api": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "authentication": "oAuth2",
        "select": "channel",
        "channelId": {
          "__rl": true,
          "value": "YOUR_INTAKE_CHANNEL_ID",
          "mode": "list"
        },
        "text": "=\u2705 *New Patient Intake*\n\n*Patient:* {{ $('Process Intake Data').item.json.fullName }}\n*Patient ID:* {{ $('Process Intake Data').item.json.patientId }}\n*Age:* {{ $('Process Intake Data').item.json.age }}\n*Insurance:* {{ $('Process Intake Data').item.json.insuranceSummary }}\n*Reason:* {{ $('Process Intake Data').item.json.reasonForVisit }}",
        "otherOptions": {}
      },
      "id": "slack-notify",
      "name": "Notify Front Desk",
      "type": "n8n-nodes-base.slack",
      "typeVersion": 2.2,
      "position": [
        1340,
        460
      ],
      "credentials": {
        "slackOAuth2Api": {
          "name": "<your credential>"
        }
      }
    }
  ],
  "connections": {
    "Google Drive Trigger": {
      "main": [
        [
          {
            "node": "Download File",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Download File": {
      "main": [
        [
          {
            "node": "PDF Vector - Extract Intake",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "PDF Vector - Extract Intake": {
      "main": [
        [
          {
            "node": "Process Intake Data",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Process Intake Data": {
      "main": [
        [
          {
            "node": "Create Patient Record",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Create Patient Record": {
      "main": [
        [
          {
            "node": "Critical Allergy?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Critical Allergy?": {
      "main": [
        [
          {
            "node": "Critical Alert",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Notify Front Desk",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "settings": {
    "executionOrder": "v1"
  },
  "tags": [
    {
      "name": "PDF Vector"
    },
    {
      "name": "Healthcare"
    },
    {
      "name": "HIPAA"
    },
    {
      "name": "Patient Intake"
    },
    {
      "name": "Medical"
    }
  ],
  "meta": {
    "templateCredsSetupCompleted": false
  }
}