8
n8n 한국어amn8n.com

Google Drive에서 의료 보고서 추출하여 AI 건강 권장 사항 생성

고급

이것은자동화 워크플로우로, 21개의 노드를 포함합니다.주로 If, Code, MistralAi, GoogleDrive, GoogleSheets 등의 노드를 사용하며. Mistral AI와 GPT-4를 사용하여 의료 보고서를 추출하고 AI 건강 조언을 생성합니다

사전 요구사항
  • Google Drive API 인증 정보
  • Google Sheets API 인증 정보
  • OpenAI API Key

카테고리

-
워크플로우 미리보기
노드 연결 관계를 시각적으로 표시하며, 확대/축소 및 이동을 지원합니다
워크플로우 내보내기
다음 JSON 구성을 복사하여 n8n에 가져오면 이 워크플로우를 사용할 수 있습니다
{
  "id": "tUEm5XYFpv149YVQ",
  "name": "Extract Medical reports from Google Drive with AI health advice",
  "tags": [],
  "nodes": [
    {
      "id": "a6a3e84a-be97-4579-ae73-8e3f1f26f4cf",
      "name": "파일 다운로드",
      "type": "n8n-nodes-base.googleDrive",
      "position": [
        1024,
        464
      ],
      "parameters": {
        "fileId": {
          "__rl": true,
          "mode": "id",
          "value": "={{ $json.id }}"
        },
        "options": {},
        "operation": "download"
      },
      "typeVersion": 3
    },
    {
      "id": "057e8d68-e51d-45fb-96c3-6aa45e2a2690",
      "name": "페이지 Markdown 결합",
      "type": "n8n-nodes-base.code",
      "position": [
        1840,
        304
      ],
      "parameters": {
        "jsCode": "// Merge markdown from all pages (works for any number of pages)\nconst pages = $json.pages;\nlet combinedMarkdown = \"\";\n\nfor (let i = 0; i < pages.length; i++) {\n  if (pages[i]?.markdown) {\n    combinedMarkdown += pages[i].markdown + \"\\n\";\n  }\n}\n\nreturn [{ json: { combined_markdown: combinedMarkdown } }];\n"
      },
      "typeVersion": 2
    },
    {
      "id": "d6af767c-c86e-4778-b604-122b48e91231",
      "name": "AI 출력을 행별로 파싱",
      "type": "n8n-nodes-base.code",
      "position": [
        2192,
        288
      ],
      "parameters": {
        "jsCode": "const input = $input.first();\nlet data = input.json.message.content || input.json.content || input.json;\n\n// Remove markdown ``` or ```\nif (typeof data === 'string') {\n  data = data.replace(/```+[\\w]*\\s*/g, '').trim();\n}\n\n// Parse JSON\ntry {\n  data = JSON.parse(data);\n} catch (err) {\n  return [{\n    json: {\n      error: \"Failed to parse JSON\",\n      message: err.message,\n      raw: typeof data === 'string' ? data.substring(0, 500) : ''\n    }\n  }];\n}\n\n// Validate array\nif (!Array.isArray(data)) {\n  return [{\n    json: {\n      error: \"Parsed data is not an array\",\n      data\n    }\n  }];\n}\n\n// Map each array entry into a separate n8n item\nreturn data.map(item => {\n  // Clean reference interval: keep only numbers, hyphens, dots, spaces\n  let ref = item.reference_range || 'N/A';\n  if (ref && ref !== 'N/A') {\n    ref = ref.replace(/[^0-9.\\- ]/g, '').replace(/\\s*-\\s*/g, ' - ').replace(/\\s+/g, ' ').trim();\n  }\n  return {\n    json: {\n      'Diagnostic Centre': item.diagnostic_centre || 'N/A',\n      'Name': item.patient_name || 'N/A',\n      'Age': item.age || 'N/A',\n      'Gender': item.gender || 'N/A',\n      'Registered on': item.registration_date || 'N/A',\n      'Sample Type': item.sample_type || 'N/A',\n      'Test Name': item.test_name || 'N/A',\n      'Result': item.result_value !== undefined ? String(item.result_value) : 'N/A',\n      'Unit': item.unit || 'N/A',\n      'Biological reference Interval': ref\n    }\n  };\n});\n"
      },
      "typeVersion": 2
    },
    {
      "id": "280f592d-9b76-4653-8a5c-2292004bda36",
      "name": "정상 범위 초과 감지 및 조언 필드",
      "type": "n8n-nodes-base.code",
      "position": [
        2416,
        288
      ],
      "parameters": {
        "jsCode": "function isOutOfRange(result, ref) {\n  if (!result || !ref) return false;\n  // strip units, trim spaces\n  let val = parseFloat((result + '').replace(/[^0-9.\\-]/g, ''));\n  let match = ref.match(/^\\s*(\\d+\\.?\\d*)\\s*-\\s*(\\d+\\.?\\d*)/); // \"0.3-1.2\" etc.\n  if (match) {\n    let low = parseFloat(match[1]);\n    let high = parseFloat(match[2]);\n    return (val < low || val > high);\n  }\n  if (ref.match(/^<\\s*(\\d+)/)) {\n    let high = parseFloat(ref.match(/^<\\s*(\\d+)/)[1]);\n    return (val >= high);\n  }\n  if (ref.match(/^>\\s*(\\d+)/)) {\n    let low = parseFloat(ref.match(/^>\\s*(\\d+)/)[1]);\n    return (val <= low);\n  }\n  return false; // fallback\n}\n\nlet outOfRangeItems = [];\nfor (let item of items) {\n  item.json['Dietary advice'] = '';\n  item.json['Lifestyle advice'] = '';\n  item.json['Exercise advice'] = '';\n  if (isOutOfRange(item.json['Result'], item.json['Biological reference Interval'])) {\n    outOfRangeItems.push(item);\n  }\n}\nreturn outOfRangeItems; // This will go to the AI node for advice\n"
      },
      "typeVersion": 2
    },
    {
      "id": "3e152598-d727-482a-99ca-a38d658dee9c",
      "name": "AI 응답 병합",
      "type": "n8n-nodes-base.code",
      "position": [
        2768,
        288
      ],
      "parameters": {
        "jsCode": "// Merge AI Response Back - SIMPLE VERSION\n// Assumes AI responses are in the same order as out-of-range items\n\nconsole.log('=== SIMPLE MERGE START ===');\n\nconst aiItems = items; // AI advice responses\nconst allRows = $('Out-of-Range Detection & Advice Fields').all();\n\nconsole.log('AI items:', aiItems.length);\nconsole.log('Medical rows:', allRows.length);\n\n// Process each row\nfor (let i = 0; i < allRows.length; i++) {\n  const row = allRows[i];\n  \n  let dietary = '';\n  let lifestyle = '';\n  let exercise = '';\n  \n  // If we have AI advice for this index\n  if (i < aiItems.length) {\n    const ai = aiItems[i];\n    \n    // Get content from various possible locations\n    let content = ai.json.content || ai.json.message?.content || ai.json.text || '';\n    \n    if (content) {\n      try {\n        // Remove code fences\n        content = content.replace(/```(?:json)?\\s*/g, '').replace(/```/g, '').trim();\n        \n        // Parse JSON\n        const obj = JSON.parse(content);\n        \n        dietary = obj[\"Dietary advice\"] || obj[\"dietary_advice\"] || '';\n        lifestyle = obj[\"Lifestyle advice\"] || obj[\"lifestyle_advice\"] || '';\n        exercise = obj[\"Exercise advice\"] || obj[\"exercise_advice\"] || '';\n        \n        console.log(`Row ${i}: Successfully extracted advice`);\n        \n      } catch (err) {\n        console.error(`Row ${i}: Parse error -`, err.message);\n      }\n    }\n  }\n  \n  row.json['Dietary advice'] = dietary;\n  row.json['Lifestyle advice'] = lifestyle;\n  row.json['Exercise advice'] = exercise;\n}\n\nconsole.log('=== SIMPLE MERGE COMPLETE ===');\nreturn allRows;"
      },
      "typeVersion": 2
    },
    {
      "id": "a62dfcf0-a9b0-443d-bf87-51c58e34662b",
      "name": "pdf/jpeg 파일을 Google 드라이브에 업로드",
      "type": "n8n-nodes-base.googleDriveTrigger",
      "notes": "Folder ID is referenced from the 'Workflow User Configuration'\nFolder ID is read from workflow variable `GOOGLE_DRIVE_FOLDER_ID` (set via Workflow → Settings → Variables). You can also replace the expression directly in this field.",
      "position": [
        1008,
        176
      ],
      "parameters": {
        "event": "fileCreated",
        "options": {},
        "pollTimes": {
          "item": [
            {
              "mode": "everyMinute"
            }
          ]
        },
        "triggerOn": "specificFolder",
        "folderToWatch": {
          "__rl": true,
          "mode": "list",
          "value": {
            "mode": "list",
            "value": "1mPJiZ...<your-folder-id-here>"
          }
        }
      },
      "typeVersion": 1
    },
    {
      "id": "31350988-e198-493d-83c6-4cb3e6a832f7",
      "name": "이미지에서 추출",
      "type": "n8n-nodes-base.mistralAi",
      "position": [
        1584,
        368
      ],
      "parameters": {
        "options": {},
        "documentType": "image_url"
      },
      "typeVersion": 1
    },
    {
      "id": "1addfa9f-7104-4da5-a78b-a4dd98e40843",
      "name": "PDF 또는 이미지 확인",
      "type": "n8n-nodes-base.if",
      "position": [
        1296,
        272
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "aad49b11-5871-422b-818f-431e53e9844f",
              "operator": {
                "name": "filter.operator.equals",
                "type": "string",
                "operation": "equals"
              },
              "leftValue": "={{ $('Upload pdf/jpeg file to Google drive').item.json.mimeType }}",
              "rightValue": "application/pdf"
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "8fa34cb4-3775-49a7-9276-497c11988a6c",
      "name": "PDF에서 추출",
      "type": "n8n-nodes-base.mistralAi",
      "position": [
        1584,
        176
      ],
      "parameters": {
        "options": {}
      },
      "typeVersion": 1
    },
    {
      "id": "39376374-069f-4566-b06d-683154afe334",
      "name": "의료 데이터 추출(AI)",
      "type": "@n8n/n8n-nodes-langchain.openAi",
      "position": [
        1952,
        64
      ],
      "parameters": {
        "modelId": {
          "__rl": true,
          "mode": "list",
          "value": "gpt-4o"
        },
        "options": {},
        "messages": {
          "values": [
            {
              "role": "system",
              "content": "=You are an expert medical data extraction assistant specializing in diagnostic reports. Your role is to accurately identify and extract EVERY measurable test result (including all sub-parameters of multi-test panels like LFT, Haemogram, Lipid Profile, etc.) in a granular and structured fashion, for each page of the provided document.\nReturn only pure, valid JSON and ensure your output is reliable for direct ingestion by downstream data pipelines.\n"
            },
            {
              "role": "user",
              "content": "=Extract ALL individual test results (including every sub-parameter of multi-panel tests such as Liver Function Test, Haemogram, etc.) from the ENTIRE provided document. \n\nOutput instructions:\n- For EACH test or parameter, create a JSON object with these fields: \n  - diagnostic_centre: Name of the diagnostic center\n  - patient_name: Full patient name\n  - age: age of the patient in Years\n  - gender: gender of the patient\n  - registration_date: Registration date (DD-MMM-YYYY)\n  - sample_type: Type of sample (e.g., Serum, Plasma, Urine)\n  - test_name: Name of the specific test/parameter (e.g., 'Total Bilirubin', 'SGPT', 'Hemoglobin', etc.)\n  - result_value: Result value (only the numeric or string value, no additional text)\n  - unit: Unit of measurement, if present (e.g., mg/dL, g/L, etc.)\n  - reference_range: Normal reference range, if present\n\n- Return ONLY a valid JSON array of all detected test results/parameters. \n- Do not include any markdown, formatting, or code blocks—just the raw JSON array.\n- If a field is missing for a parameter, output an empty string (\"\").\n\nExample:\n[\n  {\n    \"diagnostic_centre\": \"VIJAYA DIAGNOSTIC CENTRE\",\n    \"patient_name\": \"Mr.XYZ\",\n    \"age\": \"58 Years\",\n    \"gender\": \"Male\",\n    \"registration_date\": \"26-Jan-2024\",\n    \"sample_type\": \"Fluoride Plasma\",\n    \"test_name\": \"Post Lunch Glucose\",\n    \"result_value\": \"236\",\n    \"unit\": \"mg/dL\",\n    \"reference_range\": \"100-140\"\n  },\n  {\n    \"diagnostic_centre\": \"VIJAYA DIAGNOSTIC CENTRE\",\n    \"patient_name\": \"Mr.XYZ\",\n    \"age\": \"58 Years\",\n    \"gender\": \"Male\",\n    \"registration_date\": \"26-Jan-2024\",\n    \"sample_type\": \"Serum\",\n    \"test_name\": \"Total Bilirubin\",\n    \"result_value\": \"0.8\",\n    \"unit\": \"mg/dL\",\n    \"reference_range\": \"0.3-1.2\"\n  }\n]\n\nReference {{ $json.combined_markdown }} to provide the full multi-page text as input.\n\n\nExtract every possible test entry into a single JSON array, without markdown, code fences, or comments. Every result/parameter from every page must be present as a separate object.\n"
            }
          ]
        }
      },
      "typeVersion": 1.8
    },
    {
      "id": "395f545b-2c39-4fe5-824c-56196d5c5b19",
      "name": "일반 건강 조언(AI)",
      "type": "@n8n/n8n-nodes-langchain.openAi",
      "position": [
        2528,
        80
      ],
      "parameters": {
        "modelId": {
          "__rl": true,
          "mode": "list",
          "value": "gpt-4o"
        },
        "options": {},
        "messages": {
          "values": [
            {
              "role": "system",
              "content": "You are a physician-reviewed expert assistant specializing in actionable, personalized wellness guidance based on lab test results."
            },
            {
              "content": "=For this out-of-range medical lab result:\n\nPatient: {{ $json.Name }}\nAge :{{ $json.Age }}\nGender:{{ $json.Gender }}\nTest Name: {{ $json['Test Name'] }}\nResult: {{ $json.Result }} {{ $json.Unit }}\nReference Range: {{ $json['Biological reference Interval'] }}\n\nPlease provide:\n- A two-sentence dietary/nutritional advice\n- A two-sentence lifestyle change suggestion\n- A two-sentence exercise recommendation\n\nReturn your answer ONLY as the following JSON object:\n{\n  \"Dietary advice\": \"...\",\n  \"Lifestyle advice\": \"...\",\n  \"Exercise advice\": \"...\"\n}\nDo not add any additional commentary."
            }
          ]
        }
      },
      "typeVersion": 1.8
    },
    {
      "id": "2e4e4a02-0492-4a27-bcd5-d22090a7e210",
      "name": "스티커 노트",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        912,
        -80
      ],
      "parameters": {
        "color": 3,
        "width": 288,
        "height": 448,
        "content": "## Google Drive Trigger\n\n## Upload file (Pdf/Image)\n\nMonitors a specific Google Drive folder for newly uploaded medical reports (PDF/image files). Triggers the workflow when a new file is detected (checks every minute)."
      },
      "typeVersion": 1
    },
    {
      "id": "7077505f-39be-426e-bb8c-f39235900794",
      "name": "스티커 노트1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        944,
        384
      ],
      "parameters": {
        "color": 3,
        "height": 448,
        "content": "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n## Download File\n\nDownloads the detected medical report file from Google Drive for processing."
      },
      "typeVersion": 1
    },
    {
      "id": "713f9373-6461-4a1d-838a-e94b90e72e97",
      "name": "스티커 노트2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1216,
        48
      ],
      "parameters": {
        "color": 5,
        "width": 256,
        "height": 544,
        "content": "## Check if PDF/Image\n\nDetermines whether the uploaded file is a PDF or an image, routing to the appropriate extraction node."
      },
      "typeVersion": 1
    },
    {
      "id": "79fb1da0-1c7a-4e9e-8588-a606227b02b7",
      "name": "스티커 노트3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1488,
        -80
      ],
      "parameters": {
        "color": 6,
        "width": 288,
        "height": 896,
        "content": "## Extract from PDF\n\nUses Mistral AI to extract text and structure from PDF medical reports using OCR capabilities.\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n## Extract from Image\n\nUses Mistral AI to extract text from image-based medical reports (JPG, PNG, etc.) using vision capabilities."
      },
      "typeVersion": 1
    },
    {
      "id": "c53123e0-f5a3-4e8e-af19-0838a3393c0a",
      "name": "스티커 노트6",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1792,
        -80
      ],
      "parameters": {
        "color": 4,
        "width": 560,
        "height": 896,
        "content": "## Extract Medical Data (AI)\n\nUses GPT-4 to intelligently extract structured data from the medical report: patient details, test names, results, units, and reference ranges. Outputs pure JSON.\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n## Combine page Markdown\n Merges markdown text from all pages of multi-page reports into a single combined text for unified processing.\n\n\n\n## Parse AI output to one-per-row\n Transforms the AI-generated JSON array into individual n8n items  (one per test result), cleans reference intervals, and standardizes field names for Google Sheets compatibility.\n"
      },
      "typeVersion": 1
    },
    {
      "id": "83ee4286-c175-45a0-86b4-e8b997c72f6a",
      "name": "정상 범위 초과 결과 저장",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        3024,
        288
      ],
      "parameters": {
        "sheet": {
          "mode": "name",
          "value": {
            "mode": "name",
            "value": "Out of Range Values"
          }
        },
        "columns": {
          "value": {
            "Age": "={{ $json.Age }}",
            "Name": "={{ $json.Name }}",
            "Unit": "={{ $json.Unit }}",
            "Gender": "={{ $json.Gender }}",
            "Result": "={{ $json.Result }}",
            "Test Name": "={{ $json['Test Name'] }}",
            "Sample Type": "={{ $json['Sample Type'] }}",
            "Dietary advice": "={{ $json['Dietary advice'] }}",
            "Registered \non": "={{ $json['Registered on'] }}",
            "Exercise advice": "={{ $json['Exercise advice'] }}",
            "Lifestyle advice": "={{ $json['Lifestyle advice'] }}",
            "Diagnostic Centre": "={{ $json['Diagnostic Centre'] }}",
            "Biological \nreference Interval": "={{ $json['Biological reference Interval'] }}"
          },
          "schema": [
            {
              "id": "Diagnostic Centre",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Diagnostic Centre",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Name",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Name",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Age",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Age",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Gender",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Gender",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Registered \non",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Registered \non",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Sample Type",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Sample Type",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Test Name",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Test Name",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Result",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Result",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Unit",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Unit",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Biological \nreference Interval",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Biological \nreference Interval",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Dietary advice",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Dietary advice",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Lifestyle advice",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Lifestyle advice",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Exercise advice",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Exercise advice",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "operation": "append",
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": ""
        },
        "documentId": ""
      },
      "typeVersion": 4.7
    },
    {
      "id": "50454400-4968-4e6e-adb5-4afe3cea01ec",
      "name": "스티커 노트10",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2368,
        -80
      ],
      "parameters": {
        "color": 4,
        "width": 560,
        "height": 896,
        "content": "## Generate Health Advice (AI) \n\nUses GPT-4 to generate personalized dietary, lifestyle, and exercise recommendations for each out-of-range test result, considering patient age and gender.\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n## Out-of-Range Detection & Advice Fields\nAnalyzes each test result against its reference range. Identifies abnormal values and routes them for personalized health advice generation.\n\n\n\n\n                                                                                                                                                                                                     \n## Merge AI Response Back\nCombines the AI-generated health advice with the corresponding medical test data, preparing complete records for final storage.\n\n\n\n"
      },
      "typeVersion": 1
    },
    {
      "id": "edbfa3ba-e4de-41d0-8e73-3026a882033f",
      "name": "스티커 노트5",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2944,
        -80
      ],
      "parameters": {
        "color": 2,
        "width": 288,
        "height": 928,
        "content": "\n\n\n## Save Out-of-Range Results\n\nSaves abnormal test results along with personalized health advice to the \"Out of Range Values\" sheet in Google Sheets for priority review.\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n ## Save All Test Results\n\nSaves every extracted test result to the \"All Values\" sheet in Google Sheets for comprehensive record-keeping.\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n"
      },
      "typeVersion": 1
    },
    {
      "id": "49a1f385-e91e-4047-808d-5b9134050339",
      "name": "모든 검사 결과 저장",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        3040,
        512
      ],
      "parameters": {
        "sheet": {
          "mode": "name",
          "value": {
            "mode": "name",
            "value": "All Values"
          }
        },
        "columns": {
          "value": {
            "Age": "={{ $json.Age }}",
            "Name": "={{ $json.Name }}",
            "Unit": "={{ $json.Unit }}",
            "Result": "={{ $json.Result }}",
            "Test Name": "={{ $json['Test Name'] }}",
            "Sample Type": "={{ $json['Sample Type'] }}"
          },
          "schema": [
            {
              "id": "Name",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Name",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Age",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Age",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Sample Type",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Sample Type",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Test Name",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Test Name",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Result",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Result",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Unit",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Unit",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Biological \nreference Interval",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Biological \nreference Interval",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "operation": "append",
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": ""
        },
        "documentId": ""
      },
      "typeVersion": 4.7
    },
    {
      "id": "e7472172-098d-4a68-811b-89c593545003",
      "name": "스티커 노트4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        256,
        -80
      ],
      "parameters": {
        "width": 640,
        "height": 912,
        "content": "## Try It Out!\n\nUse n8n to extract medical test data from diagnostic reports uploaded to Google Drive, automatically detect abnormal values, and generate personalized health advice.\n\n### How it works\n\n1. Upload a medical report (PDF or image) to a monitored Google Drive folder\n2. Mistral AI extracts text using OCR while preserving document structure\n3. GPT-4 parses the extracted text into structured JSON (patient info, test names, results, units, reference ranges)\n4. All test results are saved to the \"All Values\" sheet in Google Sheets\n5. JavaScript code compares each result against its reference range to detect abnormalities\n6. For out-of-range values, GPT-4 generates personalized dietary, lifestyle, and exercise advice based on patient age and gender\n7. Abnormal results with recommendations are saved to the \"Out of Range Values\" sheet\n\n### How to use\n\n1. Set up Google Drive folder monitoring and Google Sheets with two tabs: \"All Values\" and \"Out of Range Values\"\n2. Configure API credentials for Google Drive, Mistral AI, and OpenAI (GPT-4)\n3. Upload medical reports to your monitored folder\n4. Review extracted data and personalized health advice in Google Sheets\n\n### Requirements\n\n* Google Drive and Sheets with OAuth2 authentication\n* Mistral AI API key for OCR\n* OpenAI API key (GPT-4 access required) for intelligent extraction and advice generation\n\n### Need Help?\n\n* See the detailed setup guide for step-by-step credential configuration\n* Join the n8n community forum for support"
      },
      "typeVersion": 1
    }
  ],
  "active": false,
  "pinData": {},
  "settings": {
    "executionOrder": "v1"
  },
  "connections": {
    "a6a3e84a-be97-4579-ae73-8e3f1f26f4cf": {
      "main": [
        [
          {
            "node": "1addfa9f-7104-4da5-a78b-a4dd98e40843",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "8fa34cb4-3775-49a7-9276-497c11988a6c": {
      "main": [
        [
          {
            "node": "057e8d68-e51d-45fb-96c3-6aa45e2a2690",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "31350988-e198-493d-83c6-4cb3e6a832f7": {
      "main": [
        [
          {
            "node": "057e8d68-e51d-45fb-96c3-6aa45e2a2690",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "1addfa9f-7104-4da5-a78b-a4dd98e40843": {
      "main": [
        [
          {
            "node": "8fa34cb4-3775-49a7-9276-497c11988a6c",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "31350988-e198-493d-83c6-4cb3e6a832f7",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "057e8d68-e51d-45fb-96c3-6aa45e2a2690": {
      "main": [
        [
          {
            "node": "39376374-069f-4566-b06d-683154afe334",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "3e152598-d727-482a-99ca-a38d658dee9c": {
      "main": [
        [
          {
            "node": "83ee4286-c175-45a0-86b4-e8b997c72f6a",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "39376374-069f-4566-b06d-683154afe334": {
      "main": [
        [
          {
            "node": "d6af767c-c86e-4778-b604-122b48e91231",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "395f545b-2c39-4fe5-824c-56196d5c5b19": {
      "main": [
        [
          {
            "node": "3e152598-d727-482a-99ca-a38d658dee9c",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "d6af767c-c86e-4778-b604-122b48e91231": {
      "main": [
        [
          {
            "node": "280f592d-9b76-4653-8a5c-2292004bda36",
            "type": "main",
            "index": 0
          },
          {
            "node": "49a1f385-e91e-4047-808d-5b9134050339",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "a62dfcf0-a9b0-443d-bf87-51c58e34662b": {
      "main": [
        [
          {
            "node": "a6a3e84a-be97-4579-ae73-8e3f1f26f4cf",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "280f592d-9b76-4653-8a5c-2292004bda36": {
      "main": [
        [
          {
            "node": "395f545b-2c39-4fe5-824c-56196d5c5b19",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}
자주 묻는 질문

이 워크플로우를 어떻게 사용하나요?

위의 JSON 구성 코드를 복사하여 n8n 인스턴스에서 새 워크플로우를 생성하고 "JSON에서 가져오기"를 선택한 후, 구성을 붙여넣고 필요에 따라 인증 설정을 수정하세요.

이 워크플로우는 어떤 시나리오에 적합한가요?

고급

유료인가요?

이 워크플로우는 완전히 무료이며 직접 가져와 사용할 수 있습니다. 다만, 워크플로우에서 사용하는 타사 서비스(예: OpenAI API)는 사용자 직접 비용을 지불해야 할 수 있습니다.

워크플로우 정보
난이도
고급
노드 수21
카테고리-
노드 유형8
난이도 설명

고급 사용자를 위한 16+개 노드의 복잡한 워크플로우

저자
Sridevi Edupuganti

Sridevi Edupuganti

@edupuganti

I help customers experience 10x faster ROI through AI Automation. AI Generalist | Pursuing Generative AI & ML(IIT-G) | Google Certified Prompt Engineer | Ex-VP | Ex-Microsoft | ISB Certified CTO & AI Leader | Azure & AI Strategist | 5X Azure | n8n level2 | Wellness Advocate & Cult Ninja

외부 링크
n8n.io에서 보기

이 워크플로우 공유

카테고리

카테고리: 34