{
  "name": "W11 - Meeting Notes & Action Item Extractor",
  "nodes": [
    {
      "parameters": {
        "content": "## \ud83d\udcdd Meeting Notes & Action Item Extractor\n\n### What this workflow does\n1. Watches Google Drive folder for meeting notes\n2. Downloads and reads the document\n3. Extracts attendees, decisions, and action items\n4. Logs summary to Google Sheets\n5. Posts formatted summary to Slack with task assignments\n\n### Setup steps\n1. Connect Google Drive account (OAuth2)\n2. Get PDF Vector API key from pdfvector.com/api-keys\n3. Create Google Sheet with columns: Meeting Title, Date, Duration, Attendees, Attendee Count, Decisions Made, Action Items, High Priority, Follow-up Date, Notes Link, Processed\n4. Update folder ID and spreadsheet ID in the nodes\n5. Connect Slack and select your team channel\n\n### Perfect for\n- Project managers tracking action items\n- Team leads distributing meeting summaries\n- Executive assistants organizing follow-ups",
        "height": 480,
        "width": 340,
        "color": 5
      },
      "id": "sticky-main",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        60,
        60
      ]
    },
    {
      "parameters": {
        "content": "## \u2705 Extracted Fields\n\n- Meeting title & date\n- Attendees (names, roles, emails)\n- Key discussion points\n- Decisions made + rationale\n- Action items + owners + due dates\n- Priority levels (High/Medium/Low)\n- Follow-up meeting details\n- Parking lot items",
        "height": 240,
        "width": 240
      },
      "id": "sticky-fields",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        420,
        60
      ]
    },
    {
      "parameters": {
        "content": "## \ud83d\udcca Google Sheets Columns\n\nMeeting Title | Date | Duration | Attendees | Attendee Count | Decisions Made | Action Items | High Priority | Follow-up Date | Notes Link | Processed",
        "height": 100,
        "width": 520
      },
      "id": "sticky-sheets",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        60,
        560
      ]
    },
    {
      "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": [
        180,
        340
      ],
      "credentials": {
        "googleDriveOAuth2Api": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "operation": "download",
        "fileId": "={{ $json.id }}",
        "options": {}
      },
      "id": "gdrive-download",
      "name": "Download Notes",
      "type": "n8n-nodes-base.googleDrive",
      "typeVersion": 3,
      "position": [
        380,
        340
      ],
      "credentials": {
        "googleDriveOAuth2Api": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "operation": "extract",
        "inputType": "file",
        "prompt": "Extract meeting notes data as flat fields. meetingTitle, meetingDate (YYYY-MM-DD), meetingDuration, attendeesList (comma-separated names as single string), agendaList (semicolon-separated agenda items), discussionSummary (semicolon-separated key points formatted as topic: summary), decisionsList (semicolon-separated decisions made), actionItemsList (semicolon-separated action items formatted as: task | owner | dueDate | priority), followUpDate (YYYY-MM-DD), followUpPurpose, parkingLotList (semicolon-separated parked items).",
        "schema": "{\"type\": \"object\", \"properties\": {\"meetingTitle\": {\"type\": \"string\"}, \"meetingDate\": {\"type\": \"string\"}, \"meetingDuration\": {\"type\": \"string\"}, \"attendeesList\": {\"type\": \"string\"}, \"agendaList\": {\"type\": \"string\"}, \"discussionSummary\": {\"type\": \"string\"}, \"decisionsList\": {\"type\": \"string\"}, \"actionItemsList\": {\"type\": \"string\"}, \"followUpDate\": {\"type\": \"string\"}, \"followUpPurpose\": {\"type\": \"string\"}, \"parkingLotList\": {\"type\": \"string\"}}, \"additionalProperties\": false}"
      },
      "id": "pdfvector-extract",
      "name": "PDF Vector - Extract Meeting Info",
      "type": "n8n-nodes-pdfvector.pdfVector",
      "typeVersion": 2,
      "position": [
        580,
        340
      ],
      "credentials": {
        "pdfVectorApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "jsCode": "const data = ($input.first().json?.data || $input.first().json) || {};\nconst fileName = $('Google Drive Trigger')?.item?.json?.name || 'Unknown';\nconst fileId   = $('Google Drive Trigger')?.item?.json?.id   || '';\n\nconst attendeeList  = data.attendeesList || 'Not specified';\nconst attendeeCount = attendeeList !== 'Not specified'\n  ? attendeeList.split(',').filter(a => a.trim()).length : 0;\n\nconst decisions = (data.decisionsList || '').split(';').map(d => d.trim()).filter(Boolean);\nconst decisionList  = decisions.map(d => `\u2713 ${d}`).join('\\n') || 'None recorded';\nconst decisionCount = decisions.length;\n\nconst actions = (data.actionItemsList || '').split(';').map(a => a.trim()).filter(Boolean);\nconst actionList = actions.map(a => {\n  const parts = a.split('|').map(p => p.trim());\n  return `\u25ab ${parts[0] || a} \u2192 ${parts[1] || 'TBD'} (Due: ${parts[2] || 'TBD'}) [${parts[3] || 'Medium'}]`;\n}).join('\\n') || 'None assigned';\nconst actionCount = actions.length;\nconst highPriorityCount = actions.filter(a => a.toLowerCase().includes('high')).length;\n\nreturn [{ json: {\n  meetingTitle:      data.meetingTitle      || 'Unknown Meeting',\n  meetingDate:       data.meetingDate       || 'N/A',\n  meetingDuration:   data.meetingDuration   || 'N/A',\n  attendeeList,\n  attendeeCount,\n  discussionSummary: data.discussionSummary || 'N/A',\n  decisionList,\n  decisionCount,\n  actionList,\n  actionCount,\n  highPriorityCount,\n  followUpDate:    data.followUpDate    || 'N/A',\n  followUpPurpose: data.followUpPurpose || 'N/A',\n  parkingLotList:  data.parkingLotList  || 'None',\n  fileName,\n  fileId,\n  processedAt: new Date().toISOString()\n}}];"
      },
      "id": "format-meeting",
      "name": "Format Meeting Data",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        780,
        340
      ]
    },
    {
      "parameters": {
        "operation": "append",
        "documentId": {
          "__rl": true,
          "value": "YOUR_SPREADSHEET_ID",
          "mode": "list"
        },
        "sheetName": {
          "__rl": true,
          "value": "gid=0",
          "mode": "list"
        },
        "columns": {
          "mappingMode": "defineBelow",
          "value": {
            "Meeting Title": "={{ $json.meetingTitle }}",
            "Date": "={{ $json.meetingDate || 'N/A' }}",
            "Duration": "={{ $json.meetingDuration || 'N/A' }}",
            "Attendees": "={{ $json.attendeeList }}",
            "Attendee Count": "={{ $json.attendeeCount }}",
            "Decisions Made": "={{ $json.decisionCount }}",
            "Action Items": "={{ $json.actionCount }}",
            "High Priority": "={{ $json.highPriorityCount }}",
            "Follow-up Date": "={{ $json.followUpDate }}",
            "Notes Link": "=https://drive.google.com/file/d/{{ $json.fileId }}/view",
            "Processed": "={{ $json.processedAt.split('T')[0] }}"
          }
        },
        "options": {}
      },
      "id": "sheets-log",
      "name": "Log Meeting Summary",
      "type": "n8n-nodes-base.googleSheets",
      "typeVersion": 4.4,
      "position": [
        980,
        340
      ],
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "authentication": "oAuth2",
        "select": "channel",
        "channelId": {
          "__rl": true,
          "value": "YOUR_SLACK_CHANNEL_ID",
          "mode": "list"
        },
        "text": "=\ud83d\udccb *Meeting Summary: {{ $('Format Meeting Data').item.json.meetingTitle }}*\n\n\ud83d\udcc5 *Date:* {{ $('Format Meeting Data').item.json.meetingDate }}\n\u23f1 *Duration:* {{ $('Format Meeting Data').item.json.meetingDuration }}\n\ud83d\udc65 *Attendees:* {{ $('Format Meeting Data').item.json.attendeeList }}\n\n---\n\n\u2705 *Decisions Made ({{ $('Format Meeting Data').item.json.decisionCount }}):*\n{{ $('Format Meeting Data').item.json.decisionList }}\n\n---\n\n\ud83d\udccc *Action Items ({{ $('Format Meeting Data').item.json.actionCount }}):*\n{{ $('Format Meeting Data').item.json.actionList }}\n\n---\n\n{{ $('Format Meeting Data').item.json.followUpDate !== 'N/A' ? '\ud83d\udcc6 *Next Meeting:* ' + $('Format Meeting Data').item.json.followUpDate + ' \u2014 ' + $('Format Meeting Data').item.json.followUpPurpose : '' }}\n\n<https://drive.google.com/file/d/{{ $('Format Meeting Data').item.json.fileId }}/view|\ud83d\udcc4 View Full Notes>",
        "otherOptions": {}
      },
      "id": "slack-summary",
      "name": "Post Summary to Slack",
      "type": "n8n-nodes-base.slack",
      "typeVersion": 2.2,
      "position": [
        1180,
        340
      ],
      "credentials": {
        "slackOAuth2Api": {
          "name": "<your credential>"
        }
      }
    }
  ],
  "connections": {
    "Google Drive Trigger": {
      "main": [
        [
          {
            "node": "Download Notes",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Download Notes": {
      "main": [
        [
          {
            "node": "PDF Vector - Extract Meeting Info",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "PDF Vector - Extract Meeting Info": {
      "main": [
        [
          {
            "node": "Format Meeting Data",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Format Meeting Data": {
      "main": [
        [
          {
            "node": "Log Meeting Summary",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Log Meeting Summary": {
      "main": [
        [
          {
            "node": "Post Summary to Slack",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "active": false,
  "settings": {
    "executionOrder": "v1"
  },
  "tags": [
    {
      "name": "PDF Vector"
    },
    {
      "name": "Meetings"
    },
    {
      "name": "Productivity"
    }
  ],
  "meta": {
    "templateCredsSetupCompleted": false
  }
}