자동화된 회의 준비
고급
이것은AI Summarization, Multimodal AI분야의자동화 워크플로우로, 39개의 노드를 포함합니다.주로 If, Set, Code, Merge, Slack 등의 노드를 사용하며. GPT-5 및 Gemini 리서치를 사용한 캘린더에서 Slack까지 Attio CRM 통해 회의 자동 준비
사전 요구사항
- •Slack Bot Token 또는 Webhook URL
- •Google 계정 및 Gmail API 인증 정보
- •대상 API의 인증 정보가 필요할 수 있음
사용된 노드 (39)
워크플로우 미리보기
노드 연결 관계를 시각적으로 표시하며, 확대/축소 및 이동을 지원합니다
워크플로우 내보내기
다음 JSON 구성을 복사하여 n8n에 가져오면 이 워크플로우를 사용할 수 있습니다
{
"meta": {
"instanceId": "2b4a3d81eafa60e4b2dfa202fdf88e491b785e2a2a6ca005b137d831a6faa7c0",
"templateCredsSetupCompleted": true
},
"nodes": [
{
"id": "47c89bf1-e539-438a-a42a-fbf7a7f56a95",
"name": "메모",
"type": "n8n-nodes-base.stickyNote",
"position": [
-1248,
832
],
"parameters": {
"color": 4,
"width": 784,
"height": 896,
"content": "## AI-Powered Meeting Preparation Automation\n\nThis workflow automatically researches your daily meetings and creates comprehensive briefing documents.\n\n### How it works\n1. **Triggers daily** at 6 AM on weekdays\n2. **Fetches calendar events** for today from Google Calendar\n3. **Filters for external meetings** (meetings with attendees outside your organization)\n4. **Researches each attendee** using:\n - Attio CRM for contact history and notes\n - Gmail for email correspondence\n - Google Calendar for past meetings\n - Perplexity for company/person research when needed\n5. **Generates meeting briefs** with key context, objectives, and talking points\n6. **Sends formatted summary** to Slack channel\n\n### Requirements\n- **Google Calendar** - OAuth2 credentials\n- **Gmail** - OAuth2 credentials \n- **Slack** - Bot token with channel access\n- **Attio CRM** - API bearer token\n- **OpenRouter** - API key for AI models\n- **Perplexity** - API key for research\n\n### Setup Instructions\n1. Configure all credential connections\n2. Update calendar email in \"Fetch Today's Calendar Events\" node\n3. Set your Slack channel ID in both Slack nodes\n4. Adjust OpenRouter models in AI nodes based on your preferences\n5. Test with a day that has meetings\n\n### Important Notes\n- **OpenRouter Models**: This template uses various models (GPT-5, Gemini 2.5 Flash). Adjust model names in all OpenRouter nodes based on availability and your preferences\n- **Costs apply** for AI model usage"
},
"typeVersion": 1
},
{
"id": "3433401d-acb7-4024-82b0-a0a58cc446a3",
"name": "메모1",
"type": "n8n-nodes-base.stickyNote",
"position": [
-400,
1136
],
"parameters": {
"color": 7,
"width": 200,
"height": 120,
"content": "### Daily Schedule Trigger\n\nRuns Monday-Friday at 6:00 AM\n\nCron: `0 6 * * 1-5`"
},
"typeVersion": 1
},
{
"id": "f8946089-bb50-4c22-a478-7af2c5063746",
"name": "Daily Weekday Trigger",
"type": "n8n-nodes-base.scheduleTrigger",
"position": [
-272,
976
],
"parameters": {
"rule": {
"interval": [
{
"field": "cronExpression",
"expression": "0 6 * * 1-5"
}
]
}
},
"typeVersion": 1.2
},
{
"id": "6b95d889-9211-41f8-bcef-08ceae8b3a44",
"name": "메모2",
"type": "n8n-nodes-base.stickyNote",
"position": [
-128,
1152
],
"parameters": {
"color": 7,
"width": 236,
"height": 168,
"content": "### Calendar Integration\n\nFetches today's events and filters for external meetings\n\n**Important**: Update the calendar email to your own"
},
"typeVersion": 1
},
{
"id": "9383e71f-5295-4a7d-b77f-721b20584c73",
"name": "Fetch Today's Calendar Events",
"type": "n8n-nodes-base.googleCalendar",
"position": [
-48,
976
],
"parameters": {
"options": {},
"timeMax": "={{ $today.plus({ day: 1 }) }}",
"timeMin": "={{ $today }}",
"calendar": {
"__rl": true,
"mode": "list",
"value": "YOUR_EMAIL@example.com",
"cachedResultName": "Your Calendar"
},
"operation": "getAll",
"returnAll": true
},
"credentials": {
"googleCalendarOAuth2Api": {
"id": "6xS7duivt7JLMnVF",
"name": "Google Calendar account"
}
},
"typeVersion": 1.3
},
{
"id": "ed5d80d8-0a1a-4a95-9abb-b6c365b304ae",
"name": "필터 External Meetings Only",
"type": "n8n-nodes-base.filter",
"notes": "Keep only events with attendees (external meetings)",
"position": [
176,
976
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "loose"
},
"combinator": "and",
"conditions": [
{
"id": "filter-external",
"operator": {
"type": "array",
"operation": "exists",
"singleValue": true
},
"leftValue": "={{ $json.attendees }}",
"rightValue": ""
}
]
},
"looseTypeValidation": true
},
"typeVersion": 2.2,
"alwaysOutputData": true
},
{
"id": "19d444c5-a678-4a50-97b9-53e7750b00ee",
"name": "Check for External Meetings",
"type": "n8n-nodes-base.if",
"position": [
400,
976
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "has-meetings",
"operator": {
"type": "string",
"operation": "exists",
"singleValue": true
},
"leftValue": "={{ $json.id }}",
"rightValue": 0
}
]
}
},
"typeVersion": 2.2
},
{
"id": "d8cbaffb-b551-4cbb-bc2b-e04f86718d2f",
"name": "Send No Meetings Message",
"type": "n8n-nodes-base.slack",
"position": [
624,
1072
],
"webhookId": "7b03e845-9984-46ce-92e8-9338a54b5362",
"parameters": {
"text": "Good morning! No external meetings scheduled for today. Enjoy your focus time!",
"select": "channel",
"channelId": {
"__rl": true,
"mode": "list",
"value": "YOUR_SLACK_CHANNEL_ID",
"cachedResultName": "your-channel"
},
"otherOptions": {},
"authentication": "oAuth2"
},
"credentials": {
"slackOAuth2Api": {
"id": "I1AdBji1W6jc0rm7",
"name": "Slack account"
}
},
"typeVersion": 2.3
},
{
"id": "0461c547-f1da-4872-9141-abfb63482e99",
"name": "메모3",
"type": "n8n-nodes-base.stickyNote",
"position": [
832,
640
],
"parameters": {
"color": 7,
"width": 920,
"height": 1056,
"content": "### AI Meeting Research\n\nWhen meetings are found, this agent:\n- Searches CRM for attendee information\n- Reviews email history\n- Checks past calendar interactions\n- Uses Perplexity for external research\n- Generates comprehensive meeting briefs\n\n**Note**: Adjust OpenRouter models as needed"
},
"typeVersion": 1
},
{
"id": "ba5434a0-0365-427c-8dff-97d98db9fa70",
"name": "Split Individual Meetings",
"type": "n8n-nodes-base.splitOut",
"position": [
624,
880
],
"parameters": {
"include": "allOtherFields",
"options": {},
"fieldToSplitOut": "id"
},
"typeVersion": 1
},
{
"id": "a68d64a3-d0e2-4e29-b23f-d6ee8fca89cb",
"name": "AI Meeting Research 에이전트",
"type": "@n8n/n8n-nodes-langchain.agent",
"position": [
1104,
880
],
"parameters": {
"text": "=You are a meeting preparation assistant. Analyze this meeting and prepare comprehensive research:\n\nMeeting Details:\n- Summary: {{ $json.summary }}\n- Start: {{ $json.start.dateTime }}\n- End: {{ $json.end.dateTime }}\n- Attendees: {{ $json.attendees.filter(a => a.email !== 'YOUR_EMAIL@example.com').map(a => a.email).join(', ') }}\n\nYour tasks:\n1. Research each attendee using the available tools (Attio CRM to find people, list notes, and get their notes. And Gmail history and past calendar meetings)\n\nIf there has been no interaction in the past, you can use Perplexity to get a better sense of the organization and the person. This isn't always necessary if I have met or corresponded with them to a good extent before. If it is first time meeting or we have little comms, then use perplexity.\n\n2. Identify the company they work for and research the company\n3. Find any previous interactions or context\n4. Prepare relevant key talking points and questions, primarily based on where our last interaction left off\n5. Identify potential goals and outcomes for this meeting\n\nAnalyze the meeting preparation data and create a concise one-page dossier. Focus on:\n1. Essential attendee information only\n2. Most recent and relevant interactions\n3. 4-5 specific talking points based on where the last conversation ended\n4. Clear, actionable next steps\nKeep descriptions brief and bullet points concise.",
"options": {
"systemMessage": "=You are an expert meeting preparation assistant with access to CRM, email, calendar, and company research tools. Your goal is to help the user be fully prepared for their upcoming meetings by providing comprehensive research and context."
},
"promptType": "define",
"needsFallback": true,
"hasOutputParser": true
},
"retryOnFail": true,
"typeVersion": 2.2
},
{
"id": "e3e3d48b-a1d7-4542-89fe-fb18efb38dbb",
"name": "Search Calendar History 도구",
"type": "n8n-nodes-base.googleCalendarTool",
"position": [
960,
1232
],
"parameters": {
"options": {
"query": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Query', ``, 'string') }}"
},
"timeMax": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Before', ``, 'string') }}",
"timeMin": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('After', ``, 'string') }}",
"calendar": {
"__rl": true,
"mode": "list",
"value": "YOUR_EMAIL@example.com",
"cachedResultName": "Your Calendar"
},
"operation": "getAll",
"returnAll": true
},
"credentials": {
"googleCalendarOAuth2Api": {
"id": "6xS7duivt7JLMnVF",
"name": "Google Calendar account"
}
},
"typeVersion": 1.3
},
{
"id": "be879b39-6d7c-4857-ab64-dae2570e1e99",
"name": "Search Gmail History Tool",
"type": "n8n-nodes-base.gmailTool",
"position": [
1104,
1200
],
"webhookId": "d8202913-d1a2-44c8-aed2-e728f6275348",
"parameters": {
"limit": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Limit', ``, 'number') }}",
"simple": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Simplify', ``, 'boolean') }}",
"filters": {
"q": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Search', ``, 'string') }}"
},
"options": {},
"operation": "getAll"
},
"credentials": {
"gmailOAuth2": {
"id": "b9yf4q17pTJEgqEE",
"name": "MO Gmail"
}
},
"typeVersion": 2.1
},
{
"id": "5283bd0a-1a60-4038-aec1-4ebdf727dcb5",
"name": "Primary AI Model",
"type": "@n8n/n8n-nodes-langchain.lmChatOpenRouter",
"position": [
912,
1056
],
"parameters": {
"model": "google/gemini-2.5-flash",
"options": {
"maxRetries": 3
}
},
"credentials": {
"openRouterApi": {
"id": "bA9Ec45f0B7Bpa10",
"name": "OpenRouter"
}
},
"typeVersion": 1
},
{
"id": "c38c28bf-d2f7-405e-898e-2c46b3a4139f",
"name": "Secondary AI Model",
"type": "@n8n/n8n-nodes-langchain.lmChatOpenRouter",
"position": [
1936,
1376
],
"parameters": {
"model": "openai/gpt-5",
"options": {}
},
"credentials": {
"openRouterApi": {
"id": "bA9Ec45f0B7Bpa10",
"name": "OpenRouter"
}
},
"typeVersion": 1
},
{
"id": "0980b927-4f40-462e-a0a7-3b6bacc468f9",
"name": "Perplexity Research 도구",
"type": "n8n-nodes-base.perplexityTool",
"position": [
1248,
1248
],
"parameters": {
"model": "sonar-pro",
"options": {},
"messages": {
"message": [
{
"content": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('message0_Text', ``, 'string') }}"
}
]
},
"requestOptions": {}
},
"credentials": {
"perplexityApi": {
"id": "Lp8s8pOa5dCRCcUm",
"name": "Perplexity account"
}
},
"typeVersion": 1
},
{
"id": "68a07c67-b348-4b3d-b17e-f6c740a4fd26",
"name": "Fallback AI Model",
"type": "@n8n/n8n-nodes-langchain.lmChatOpenRouter",
"position": [
848,
1280
],
"parameters": {
"model": "openai/gpt-5",
"options": {}
},
"credentials": {
"openRouterApi": {
"id": "bA9Ec45f0B7Bpa10",
"name": "OpenRouter"
}
},
"typeVersion": 1
},
{
"id": "b1fc1ba5-37e9-4835-a9ce-7f8de724e24f",
"name": "Meeting Data Parser",
"type": "@n8n/n8n-nodes-langchain.outputParserStructured",
"position": [
1472,
1280
],
"parameters": {
"autoFix": true,
"schemaType": "manual",
"inputSchema": "{\n \"type\": \"object\",\n \"properties\": {\n \"meetingTitle\": {\n \"type\": \"string\",\n \"description\": \"Brief meeting title format: 'Person1 <> Person2/Company'\"\n },\n \"meetingDateTime\": {\n \"type\": \"object\",\n \"properties\": {\n \"date\": {\n \"type\": \"string\",\n \"description\": \"Date in format: Wednesday, August 27, 2025\"\n },\n \"time\": {\n \"type\": \"string\",\n \"description\": \"Time range with timezone: 10:00 AM - 10:30 AM PDT\"\n }\n },\n \"required\": [\"date\", \"time\"]\n },\n \"attendees\": {\n \"type\": \"array\",\n \"items\": {\n \"type\": \"object\",\n \"properties\": {\n \"name\": {\n \"type\": \"string\"\n },\n \"email\": {\n \"type\": \"string\"\n },\n \"role\": {\n \"type\": \"string\",\n \"description\": \"Their title and company\"\n },\n \"lastInteraction\": {\n \"type\": \"string\",\n \"description\": \"Date and context of last interaction, or 'First Meeting'\"\n },\n \"keyPoints\": {\n \"type\": \"array\",\n \"items\": {\n \"type\": \"string\"\n },\n \"description\": \"3-4 key background points\",\n \"maxItems\": 4\n }\n },\n \"required\": [\"name\", \"email\", \"role\"]\n }\n },\n \"companyOverview\": {\n \"type\": \"string\",\n \"description\": \"2-3 sentence company overview\"\n },\n \"relationshipContext\": {\n \"type\": \"string\",\n \"description\": \"Brief context of relationship history and how you connected\"\n },\n \"meetingObjective\": {\n \"type\": \"string\",\n \"description\": \"Primary goal for this meeting in one sentence\"\n },\n \"discussionTopics\": {\n \"type\": \"array\",\n \"items\": {\n \"type\": \"string\"\n },\n \"description\": \"4-5 key talking points based on last interaction\",\n \"minItems\": 3,\n \"maxItems\": 5\n },\n \"potentialOutcomes\": {\n \"type\": \"array\",\n \"items\": {\n \"type\": \"string\"\n },\n \"description\": \"2-3 potential next steps\",\n \"maxItems\": 3\n }\n },\n \"required\": [\n \"meetingTitle\",\n \"meetingDateTime\",\n \"attendees\",\n \"meetingObjective\",\n \"discussionTopics\"\n ]\n}"
},
"typeVersion": 1.3
},
{
"id": "ccd2cc06-14e9-46ad-9a57-ee0cefcc7217",
"name": "Parser AI Model",
"type": "@n8n/n8n-nodes-langchain.lmChatOpenRouter",
"position": [
1408,
1488
],
"parameters": {
"model": "google/gemini-2.5-flash",
"options": {}
},
"credentials": {
"openRouterApi": {
"id": "bA9Ec45f0B7Bpa10",
"name": "OpenRouter"
}
},
"typeVersion": 1
},
{
"id": "316d6a09-3cbb-465d-86f0-e5dd4ced4477",
"name": "Attio List 노트s Tool",
"type": "n8n-nodes-base.httpRequestTool",
"position": [
1056,
1520
],
"parameters": {
"url": "https://api.attio.com/v2/notes",
"options": {},
"sendQuery": true,
"authentication": "genericCredentialType",
"genericAuthType": "httpBearerAuth",
"queryParameters": {
"parameters": [
{
"name": "parent_object",
"value": "people"
},
{
"name": "parent_record_id",
"value": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('parameters1_Value', `Record ID of person found in attio_search_people`, 'string') }}"
}
]
},
"toolDescription": "Use this to list out Notes related to the records you find using attio_search_people"
},
"credentials": {
"httpBearerAuth": {
"id": "H8ybPb8fmXzKWz50",
"name": "Attio"
}
},
"typeVersion": 4.2
},
{
"id": "795dbcbf-b6c5-4347-8999-b6230ca14554",
"name": "Attio Search People 도구",
"type": "n8n-nodes-base.httpRequestTool",
"position": [
1360,
1168
],
"parameters": {
"url": "https://api.attio.com/v2/objects/people/records/query",
"method": "POST",
"options": {},
"jsonBody": "={\n \"filter\": {\n \"email_addresses\": \"{{ $fromAI(\"single_email_address\", \"Email address of individual to find in the CRM\", \"string\") }}\"\n },\n \"limit\": 1,\n \"offset\": 0\n}",
"sendBody": true,
"sendHeaders": true,
"specifyBody": "json",
"authentication": "genericCredentialType",
"genericAuthType": "httpBearerAuth",
"toolDescription": "Search my CRM for information on a single person",
"headerParameters": {
"parameters": [
{
"name": "Content-Type",
"value": "application/json"
}
]
}
},
"credentials": {
"httpBearerAuth": {
"id": "H8ybPb8fmXzKWz50",
"name": "Attio"
}
},
"typeVersion": 4.2
},
{
"id": "e425b9f4-d99d-416c-bbdd-9d37f34e870d",
"name": "Attio Read 노트s Tool",
"type": "n8n-nodes-base.httpRequestTool",
"position": [
1200,
1520
],
"parameters": {
"url": "=https://api.attio.com/v2/notes/{{ $fromAI(\"note_id\", \"the A UUID which identifies the note from attio_list_note\") }}",
"options": {},
"authentication": "genericCredentialType",
"genericAuthType": "httpBearerAuth",
"toolDescription": "Use this to get contents of a Note related to the Notes you find using attio_list_note"
},
"credentials": {
"httpBearerAuth": {
"id": "H8ybPb8fmXzKWz50",
"name": "Attio"
}
},
"typeVersion": 4.2
},
{
"id": "5fcf9176-4643-46fc-897a-24f281450699",
"name": "Format Meeting Brief",
"type": "n8n-nodes-base.code",
"position": [
1584,
880
],
"parameters": {
"mode": "runOnceForEachItem",
"jsCode": "// Format structured output into Attio markdown\nconst data = $json.output;\n\n// Helper function to format attendees\nconst formatAttendees = (attendees) => {\n return attendees.map(a => {\n let attendeeBlock = `**${a.name}** (${a.email})\\n*${a.role}*\\n`;\n if (a.lastInteraction) {\n attendeeBlock += `Last interaction: ${a.lastInteraction}\\n`;\n }\n if (a.keyPoints && a.keyPoints.length > 0) {\n attendeeBlock += a.keyPoints.map(point => `• ${point}`).join('\\n');\n }\n return attendeeBlock;\n }).join('\\n\\n');\n};\n\n// Build the markdown document\nconst markdown = `# ${data.meetingTitle}\n\n**${data.meetingDateTime.date}** \n**${data.meetingDateTime.time}**\n\n---\n\n## Attendees\n\n${formatAttendees(data.attendees)}\n\n## Context\n\n${data.companyOverview ? `**Company:** ${data.companyOverview}\\n\\n` : ''}${data.relationshipContext ? `**Relationship:** ${data.relationshipContext}` : ''}\n\n## Meeting Objective\n\n**${data.meetingObjective}**\n\n## Discussion Topics\n\n${(data.discussionTopics || []).map((topic, i) => `${i + 1}. ${topic}`).join('\\n')}\n\n## Potential Next Steps\n\n${(data.potentialOutcomes || []).map(outcome => `→ ${outcome}`).join('\\n')}`;\n\nreturn {\n markdown: markdown,\n structured: data\n};"
},
"typeVersion": 2
},
{
"id": "4d4c2ab2-f5c6-4659-ab1f-4d3570c889ae",
"name": "메모4",
"type": "n8n-nodes-base.stickyNote",
"position": [
2416,
576
],
"parameters": {
"color": 7,
"width": 1584,
"height": 468,
"content": "### CRM Integration\n\nThe workflow includes these Attio CRM integration points:\n- Search for people by email\n- Create person records if missing\n- List existing notes\n- Read note contents\n- Create new meeting prep notes\n\nRequires Attio API bearer token"
},
"typeVersion": 1
},
{
"id": "0f98c98c-15fb-4849-8459-74e2488ab563",
"name": "필터 External Attendees",
"type": "n8n-nodes-base.set",
"position": [
1920,
784
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "22f8e8d1-b14f-47f5-ab45-4cfad5d27bbc",
"name": "attendees",
"type": "array",
"value": "={{ $('Split Individual Meetings').item.json.attendees.filter(a => a.email !== 'YOUR_EMAIL@example.com') }}"
}
]
},
"includeOtherFields": true
},
"typeVersion": 3.4
},
{
"id": "f011a1fb-e804-4078-8dba-09ce75b41e01",
"name": "Split Individual Attendees",
"type": "n8n-nodes-base.splitOut",
"position": [
2208,
784
],
"parameters": {
"include": "allOtherFields",
"options": {},
"fieldToSplitOut": "attendees"
},
"typeVersion": 1
},
{
"id": "aab6d0d7-8936-42da-8515-100cc336587f",
"name": "Find Person in CRM",
"type": "n8n-nodes-base.httpRequest",
"position": [
2704,
784
],
"parameters": {
"url": "https://api.attio.com/v2/objects/people/records/query",
"method": "POST",
"options": {},
"jsonBody": "={\n \"filter\": {\n \"email_addresses\": \"{{ $json.attendees.email }}\"\n },\n \"limit\": 1,\n \"offset\": 0\n}",
"sendBody": true,
"sendHeaders": true,
"specifyBody": "json",
"authentication": "genericCredentialType",
"genericAuthType": "httpBearerAuth",
"headerParameters": {
"parameters": [
{
"name": "Content-Type",
"value": "application/json"
}
]
}
},
"credentials": {
"httpBearerAuth": {
"id": "H8ybPb8fmXzKWz50",
"name": "Attio"
}
},
"typeVersion": 4.2
},
{
"id": "b0d83ab6-d2a5-49c1-9edb-4454ed81e796",
"name": "Check if Person Exists in CRM",
"type": "n8n-nodes-base.if",
"position": [
2928,
784
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "eef23392-13a0-44e9-aa40-1d086dd245ac",
"operator": {
"type": "string",
"operation": "exists",
"singleValue": true
},
"leftValue": "={{ $json.data[0].id.record_id }}",
"rightValue": ""
}
]
}
},
"typeVersion": 2.2
},
{
"id": "c7d63acc-ef54-474e-bd16-9f1834c84dca",
"name": "Create New Person Record",
"type": "n8n-nodes-base.httpRequest",
"position": [
3152,
848
],
"parameters": {
"url": "https://api.attio.com/v2/objects/people/records",
"method": "POST",
"options": {},
"jsonBody": "={\n \"data\": {\n \"values\": {\n \"email_addresses\": [\n {\n \"email_address\": \"{{ $json.attendees.email }}\"\n }\n ]\n }\n }\n}",
"sendBody": true,
"sendHeaders": true,
"specifyBody": "json",
"authentication": "genericCredentialType",
"genericAuthType": "httpBearerAuth",
"headerParameters": {
"parameters": [
{
"name": "Content-Type",
"value": "application/json"
}
]
}
},
"credentials": {
"httpBearerAuth": {
"id": "H8ybPb8fmXzKWz50",
"name": "Attio"
}
},
"typeVersion": 4.2
},
{
"id": "8a0df435-807c-41dc-ac78-f1a7ec11163a",
"name": "Combine Person Records",
"type": "n8n-nodes-base.merge",
"position": [
3376,
784
],
"parameters": {},
"typeVersion": 3.2
},
{
"id": "3a01bc50-a7e7-4792-8654-b52087a43c1b",
"name": "Create Meeting Prep 노트",
"type": "n8n-nodes-base.httpRequest",
"position": [
3808,
784
],
"parameters": {
"url": "https://api.attio.com/v2/notes",
"method": "POST",
"options": {},
"jsonBody": "={\n \"data\": {\n \"parent_object\": \"people\",\n \"parent_record_id\": \"{{ $json.data[0].id.record_id }}\",\n \"title\": \"Meeting Prep\",\n \"content\": \"{{ JSON.stringify($('Format Meeting Brief').item.json.markdown).slice(1,-1) }}\",\n \"format\": \"markdown\"\n }\n}",
"sendBody": true,
"sendHeaders": true,
"specifyBody": "json",
"authentication": "genericCredentialType",
"genericAuthType": "httpBearerAuth",
"headerParameters": {
"parameters": [
{
"name": "Content-Type",
"value": "application/json"
}
]
}
},
"credentials": {
"httpBearerAuth": {
"id": "H8ybPb8fmXzKWz50",
"name": "Attio"
}
},
"typeVersion": 4.2
},
{
"id": "7a65b970-c858-40bf-9021-a77c7937c6ab",
"name": "Combine All Meeting Briefs",
"type": "n8n-nodes-base.aggregate",
"position": [
1920,
976
],
"parameters": {
"options": {},
"fieldsToAggregate": {
"fieldToAggregate": [
{
"fieldToAggregate": "markdown"
}
]
}
},
"typeVersion": 1
},
{
"id": "0c04c553-a2a0-4194-bef6-eafd36452a11",
"name": "메모5",
"type": "n8n-nodes-base.stickyNote",
"position": [
2688,
1440
],
"parameters": {
"color": 7,
"width": 388,
"height": 256,
"content": "### Slack Integration\n\nFinal step sends formatted meeting briefs to Slack:\n- Rich Block Kit formatting\n- Includes meeting times, objectives, and key context\n- Sends summary of all meetings for the day\n\n**Important**: Update channel ID to your own"
},
"typeVersion": 1
},
{
"id": "b5e2be4b-76fa-4df4-817e-3dbf9bfd39d0",
"name": "Meeting Brief Optimizer",
"type": "@n8n/n8n-nodes-langchain.agent",
"position": [
2144,
1104
],
"parameters": {
"text": "=You are a meeting brief optimizer. You will receive multiple meeting preparations separated by markdown headers.\n\nInput contains {{ $json.markdown.length }} meetings to process.\n\nHere are ALL the meetings:\n{{ $json.markdown.join('\\n\\n---NEXT MEETING---\\n\\n') }}\n\nCreate a brief for EACH meeting you find above. Each meeting starts with a # header containing names.\n\nFor EACH meeting, extract:\n1. Meeting title - Keep it short and professional\n2. Meeting time - Already in PST, just extract it\n3. Purpose - Why this meeting matters NOW (2-3 sentences max)\n4. Key context - The 1-2 most critical facts about this person/company\n5. Action - The ONE main goal you must accomplish\n6. Watch for - A specific signal, question to ask, or opportunity to identify\n\nNote:\n- Keep writing tone clear and concise. Focus on essential information.\n- Order your meetings in your output from earliest to latest in the day.\n\nImportant: Return an array with one brief object for each meeting found.",
"options": {},
"promptType": "define",
"needsFallback": true,
"hasOutputParser": true
},
"typeVersion": 2.2
},
{
"id": "dcd9ae8d-7a65-4c52-a41d-675fe1282b4a",
"name": "Brief Optimizer AI Model",
"type": "@n8n/n8n-nodes-langchain.lmChatOpenRouter",
"position": [
2016,
1616
],
"parameters": {
"model": "openai/gpt-5-mini",
"options": {}
},
"credentials": {
"openRouterApi": {
"id": "bA9Ec45f0B7Bpa10",
"name": "OpenRouter"
}
},
"typeVersion": 1
},
{
"id": "465e5ceb-d79f-4743-8a0c-b5fc843f6c73",
"name": "Brief Structure Parser",
"type": "@n8n/n8n-nodes-langchain.outputParserStructured",
"position": [
2272,
1360
],
"parameters": {
"autoFix": true,
"schemaType": "manual",
"inputSchema": "{\n \"type\": \"object\",\n \"properties\": {\n \"meetings\": {\n \"type\": \"array\",\n \"description\": \"Array of meeting briefs, one for each meeting\",\n \"items\": {\n \"type\": \"object\",\n \"properties\": {\n \"meetingTitle\": {\n \"type\": \"string\",\n \"description\": \"Brief professional title: 'Name (Company) - Topic' format\"\n },\n \"meetingTimePST\": {\n \"type\": \"string\",\n \"description\": \"Meeting time in PST format: 'Day, Month DD @ HH:MM AM/PM PST'\"\n },\n \"purpose\": {\n \"type\": \"string\",\n \"description\": \"2-3 sentences explaining why this meeting matters right now\"\n },\n \"keyContext\": {\n \"type\": \"string\",\n \"description\": \"1-2 most critical facts that will influence the conversation\"\n },\n \"action\": {\n \"type\": \"string\",\n \"description\": \"The single most important outcome to achieve\"\n },\n \"watchFor\": {\n \"type\": \"string\",\n \"description\": \"One specific thing to observe or ask about\"\n }\n },\n \"required\": [\n \"meetingTitle\",\n \"meetingTimePST\",\n \"purpose\",\n \"keyContext\",\n \"action\",\n \"watchFor\"\n ]\n }\n }\n },\n \"required\": [\"meetings\"]\n}"
},
"typeVersion": 1.3
},
{
"id": "bd04e88e-16a8-43f9-af73-fc8430fcbc63",
"name": "Brief Parser AI Model",
"type": "@n8n/n8n-nodes-langchain.lmChatOpenRouter",
"position": [
2352,
1584
],
"parameters": {
"model": "google/gemini-2.5-flash",
"options": {}
},
"credentials": {
"openRouterApi": {
"id": "bA9Ec45f0B7Bpa10",
"name": "OpenRouter"
}
},
"typeVersion": 1
},
{
"id": "7c9ffbe0-9905-406e-92fa-7d43cdb71ef4",
"name": "Format Slack Block Kit Message",
"type": "n8n-nodes-base.code",
"notes": "Converts AI Agent output to Slack Block Kit format",
"position": [
2608,
1232
],
"parameters": {
"mode": "runOnceForEachItem",
"jsCode": "// Format meeting summaries for Slack Block Kit\nconst data = $json.output || $json;\nconst meetings = data.meetings || data;\n\n// Helper to truncate text to avoid Slack's block limits\nconst truncateText = (text, maxLength = 3000) => {\n if (text && text.length > maxLength) {\n return text.substring(0, maxLength - 3) + '...';\n }\n return text || '';\n};\n\n// Helper function to format date nicely\nconst formatDate = () => {\n const date = new Date();\n return date.toLocaleDateString('en-US', { \n weekday: 'long', \n year: 'numeric', \n month: 'long', \n day: 'numeric' \n });\n};\n\n// Extract time from the meetingTimePST field (e.g., \"Wednesday, August 27 @ 09:00 AM PST\")\nconst extractTime = (timeString) => {\n const match = timeString.match(/@\\s*(\\d{1,2}:\\d{2}\\s*[AP]M)/i);\n return match ? match[1] : timeString;\n};\n\n// Build the blocks array\nlet blocks = [\n {\n \"type\": \"header\",\n \"text\": {\n \"type\": \"plain_text\",\n \"text\": \"Today's Meeting Brief\"\n }\n },\n {\n \"type\": \"context\",\n \"elements\": [\n {\n \"text\": formatDate(),\n \"type\": \"mrkdwn\"\n }\n ]\n },\n {\n \"type\": \"section\",\n \"text\": {\n \"type\": \"mrkdwn\",\n \"text\": `${meetings.length} meetings today. If someone watched you for a week would they think you're serious about achieving your goals?`\n }\n },\n {\n \"type\": \"divider\"\n }\n];\n\n// Add each meeting as a rich formatted section\nmeetings.forEach((meeting, index) => {\n const time = extractTime(meeting.meetingTimePST);\n \n // Meeting header section\n blocks.push({\n \"type\": \"section\",\n \"text\": {\n \"type\": \"mrkdwn\",\n \"text\": `*${time}*`\n }\n });\n \n // Build rich text elements for meeting details\n let richTextElements = [];\n \n // Who section (meeting title)\n richTextElements.push({\n \"type\": \"rich_text_section\",\n \"elements\": [\n {\n \"type\": \"text\",\n \"text\": meeting.meetingTitle,\n \"style\": {\n \"code\": true\n }\n },\n {\n \"type\": \"text\",\n \"text\": \"\\n\"\n }\n ]\n });\n \n // Purpose in quote block\n richTextElements.push({\n \"type\": \"rich_text_quote\",\n \"elements\": [\n {\n \"type\": \"text\",\n \"text\": \"Purpose:\",\n \"style\": {\n \"bold\": true\n }\n },\n {\n \"type\": \"text\",\n \"text\": `\\n${truncateText(meeting.purpose, 500)}`\n }\n ]\n });\n \n // Context section\n richTextElements.push({\n \"type\": \"rich_text_section\",\n \"elements\": [\n {\n \"type\": \"text\",\n \"text\": \"\\nContext: \",\n \"style\": {\n \"bold\": true\n }\n },\n {\n \"type\": \"text\",\n \"text\": truncateText(meeting.keyContext, 500),\n \"style\": {\n \"italic\": true\n }\n }\n ]\n });\n \n // Action items in list\n richTextElements.push({\n \"type\": \"rich_text_list\",\n \"style\": \"bullet\",\n \"elements\": [\n {\n \"type\": \"rich_text_section\",\n \"elements\": [\n {\n \"type\": \"text\",\n \"text\": \"Action: \",\n \"style\": {\n \"bold\": true\n }\n },\n {\n \"type\": \"text\",\n \"text\": truncateText(meeting.action, 400)\n }\n ]\n },\n {\n \"type\": \"rich_text_section\",\n \"elements\": [\n {\n \"type\": \"text\",\n \"text\": \"Watch For: \",\n \"style\": {\n \"bold\": true\n }\n },\n {\n \"type\": \"text\",\n \"text\": truncateText(meeting.watchFor, 400),\n \"style\": {\n \"italic\": true\n }\n }\n ]\n }\n ]\n });\n \n // Add empty section for spacing\n richTextElements.push({\n \"type\": \"rich_text_section\",\n \"elements\": []\n });\n \n blocks.push({\n \"type\": \"rich_text\",\n \"elements\": richTextElements\n });\n \n // Add divider between meetings (except after last)\n if (index < meetings.length - 1) {\n blocks.push({\n \"type\": \"divider\"\n });\n }\n});\n\n// Add footer\nblocks.push({\n \"type\": \"divider\"\n});\n\n// Create the full Block Kit JSON object\nconst blockKitJson = {\n \"blocks\": blocks\n};\n\n// Return the properly formatted JSON for n8n Slack node\nreturn {\n // This is the key output - the full JSON object as a string\n blocksUi: JSON.stringify(blockKitJson),\n \n // Also include for debugging/reference\n rawBlocks: blocks,\n blockKitObject: blockKitJson,\n \n // Metadata\n meetingCount: meetings.length,\n meetings: meetings,\n hasContent: meetings.length > 0\n};"
},
"typeVersion": 2
},
{
"id": "568c833a-1558-489b-b888-682a88b7e014",
"name": "Send Meeting Brief to Slack",
"type": "n8n-nodes-base.slack",
"notes": "Configure your channel ID and credentials. The 'text' field is required as fallback for notifications.",
"position": [
2928,
1264
],
"webhookId": "3d69e6d7-54ba-4142-8e78-f98321cd2e24",
"parameters": {
"text": "Daily meeting brief",
"select": "channel",
"blocksUi": "={{ $json.blocksUi }}",
"channelId": {
"__rl": true,
"mode": "list",
"value": "YOUR_SLACK_CHANNEL_ID",
"cachedResultName": "your-channel"
},
"messageType": "block",
"otherOptions": {},
"authentication": "oAuth2"
},
"credentials": {
"slackOAuth2Api": {
"id": "I1AdBji1W6jc0rm7",
"name": "Slack account"
}
},
"typeVersion": 2.3
}
],
"pinData": {
"Daily Weekday Trigger": [
{
"Hour": "06",
"Year": "2025",
"Month": "August",
"Minute": "00",
"Second": "00",
"Timezone": "America/Los_Angeles (UTC-07:00)",
"timestamp": "2025-08-29T06:00:00.006-07:00",
"Day of week": "Friday",
"Day of month": "29",
"Readable date": "August 29th 2025, 6:00:00 am",
"Readable time": "6:00:00 am"
}
]
},
"connections": {
"ccd2cc06-14e9-46ad-9a57-ee0cefcc7217": {
"ai_languageModel": [
[
{
"node": "b1fc1ba5-37e9-4835-a9ce-7f8de724e24f",
"type": "ai_languageModel",
"index": 0
}
]
]
},
"5283bd0a-1a60-4038-aec1-4ebdf727dcb5": {
"ai_languageModel": [
[
{
"node": "AI Meeting Research Agent",
"type": "ai_languageModel",
"index": 0
}
]
]
},
"68a07c67-b348-4b3d-b17e-f6c740a4fd26": {
"ai_languageModel": [
[
{
"node": "AI Meeting Research Agent",
"type": "ai_languageModel",
"index": 1
}
]
]
},
"aab6d0d7-8936-42da-8515-100cc336587f": {
"main": [
[
{
"node": "b0d83ab6-d2a5-49c1-9edb-4454ed81e796",
"type": "main",
"index": 0
}
]
]
},
"c38c28bf-d2f7-405e-898e-2c46b3a4139f": {
"ai_languageModel": [
[
{
"node": "b5e2be4b-76fa-4df4-817e-3dbf9bfd39d0",
"type": "ai_languageModel",
"index": 0
}
]
]
},
"b1fc1ba5-37e9-4835-a9ce-7f8de724e24f": {
"ai_outputParser": [
[
{
"node": "AI Meeting Research Agent",
"type": "ai_outputParser",
"index": 0
}
]
]
},
"5fcf9176-4643-46fc-897a-24f281450699": {
"main": [
[
{
"node": "Filter External Attendees",
"type": "main",
"index": 0
},
{
"node": "7a65b970-c858-40bf-9021-a77c7937c6ab",
"type": "main",
"index": 0
}
]
]
},
"Attio List Notes Tool": {
"ai_tool": [
[
{
"node": "AI Meeting Research Agent",
"type": "ai_tool",
"index": 0
}
]
]
},
"Attio Read Notes Tool": {
"ai_tool": [
[
{
"node": "AI Meeting Research Agent",
"type": "ai_tool",
"index": 0
}
]
]
},
"bd04e88e-16a8-43f9-af73-fc8430fcbc63": {
"ai_languageModel": [
[
{
"node": "465e5ceb-d79f-4743-8a0c-b5fc843f6c73",
"type": "ai_languageModel",
"index": 0
}
]
]
},
"f8946089-bb50-4c22-a478-7af2c5063746": {
"main": [
[
{
"node": "9383e71f-5295-4a7d-b77f-721b20584c73",
"type": "main",
"index": 0
}
]
]
},
"465e5ceb-d79f-4743-8a0c-b5fc843f6c73": {
"ai_outputParser": [
[
{
"node": "b5e2be4b-76fa-4df4-817e-3dbf9bfd39d0",
"type": "ai_outputParser",
"index": 0
}
]
]
},
"8a0df435-807c-41dc-ac78-f1a7ec11163a": {
"main": [
[
{
"node": "Create Meeting Prep Note",
"type": "main",
"index": 0
}
]
]
},
"b5e2be4b-76fa-4df4-817e-3dbf9bfd39d0": {
"main": [
[
{
"node": "7c9ffbe0-9905-406e-92fa-7d43cdb71ef4",
"type": "main",
"index": 0
}
]
]
},
"Attio Search People Tool": {
"ai_tool": [
[
{
"node": "AI Meeting Research Agent",
"type": "ai_tool",
"index": 0
}
]
]
},
"dcd9ae8d-7a65-4c52-a41d-675fe1282b4a": {
"ai_languageModel": [
[
{
"node": "b5e2be4b-76fa-4df4-817e-3dbf9bfd39d0",
"type": "ai_languageModel",
"index": 1
}
]
]
},
"c7d63acc-ef54-474e-bd16-9f1834c84dca": {
"main": [
[
{
"node": "8a0df435-807c-41dc-ac78-f1a7ec11163a",
"type": "main",
"index": 1
}
]
]
},
"Perplexity Research Tool": {
"ai_tool": [
[
{
"node": "AI Meeting Research Agent",
"type": "ai_tool",
"index": 0
}
]
]
},
"AI Meeting Research Agent": {
"main": [
[
{
"node": "5fcf9176-4643-46fc-897a-24f281450699",
"type": "main",
"index": 0
}
]
]
},
"Filter External Attendees": {
"main": [
[
{
"node": "f011a1fb-e804-4078-8dba-09ce75b41e01",
"type": "main",
"index": 0
}
]
]
},
"be879b39-6d7c-4857-ab64-dae2570e1e99": {
"ai_tool": [
[
{
"node": "AI Meeting Research Agent",
"type": "ai_tool",
"index": 0
}
]
]
},
"ba5434a0-0365-427c-8dff-97d98db9fa70": {
"main": [
[
{
"node": "AI Meeting Research Agent",
"type": "main",
"index": 0
}
]
]
},
"7a65b970-c858-40bf-9021-a77c7937c6ab": {
"main": [
[
{
"node": "b5e2be4b-76fa-4df4-817e-3dbf9bfd39d0",
"type": "main",
"index": 0
}
]
]
},
"f011a1fb-e804-4078-8dba-09ce75b41e01": {
"main": [
[
{
"node": "aab6d0d7-8936-42da-8515-100cc336587f",
"type": "main",
"index": 0
}
]
]
},
"19d444c5-a678-4a50-97b9-53e7750b00ee": {
"main": [
[
{
"node": "ba5434a0-0365-427c-8dff-97d98db9fa70",
"type": "main",
"index": 0
}
],
[
{
"node": "d8cbaffb-b551-4cbb-bc2b-e04f86718d2f",
"type": "main",
"index": 0
}
]
]
},
"Search Calendar History Tool": {
"ai_tool": [
[
{
"node": "AI Meeting Research Agent",
"type": "ai_tool",
"index": 0
}
]
]
},
"b0d83ab6-d2a5-49c1-9edb-4454ed81e796": {
"main": [
[
{
"node": "8a0df435-807c-41dc-ac78-f1a7ec11163a",
"type": "main",
"index": 0
}
],
[
{
"node": "c7d63acc-ef54-474e-bd16-9f1834c84dca",
"type": "main",
"index": 0
}
]
]
},
"9383e71f-5295-4a7d-b77f-721b20584c73": {
"main": [
[
{
"node": "Filter External Meetings Only",
"type": "main",
"index": 0
}
]
]
},
"Filter External Meetings Only": {
"main": [
[
{
"node": "19d444c5-a678-4a50-97b9-53e7750b00ee",
"type": "main",
"index": 0
}
]
]
},
"7c9ffbe0-9905-406e-92fa-7d43cdb71ef4": {
"main": [
[
{
"node": "568c833a-1558-489b-b888-682a88b7e014",
"type": "main",
"index": 0
}
]
]
}
}
}자주 묻는 질문
이 워크플로우를 어떻게 사용하나요?
위의 JSON 구성 코드를 복사하여 n8n 인스턴스에서 새 워크플로우를 생성하고 "JSON에서 가져오기"를 선택한 후, 구성을 붙여넣고 필요에 따라 인증 설정을 수정하세요.
이 워크플로우는 어떤 시나리오에 적합한가요?
고급 - AI 요약, 멀티모달 AI
유료인가요?
이 워크플로우는 완전히 무료이며 직접 가져와 사용할 수 있습니다. 다만, 워크플로우에서 사용하는 타사 서비스(예: OpenAI API)는 사용자 직접 비용을 지불해야 할 수 있습니다.
관련 워크플로우 추천
AI 기반 회의 연구 및 일일 아젠다 (Google 캘린더, Attio CRM 및 Slack)
AI 기반 회의 연구 및 일일 아젠다: Google 캘린더, Attio CRM 및 Slack 활용
If
Set
Code
+
If
Set
Code
30 노드Harry Siggins
AI 요약
Gemini, Slack, Notion을 사용하여 뉴스 요약에서 AI 정보 요약을 생성
Gemini, Slack, 및 Notion을 사용하여 뉴스 브리핑에서 AI 정보 요약을 생성
Set
Code
Gmail
+
Set
Code
Gmail
19 노드Harry Siggins
기타
매일 WhatsApp 그룹 지능형 분석: GPT-4.1 분석 및 음성 메시지 변환
매일 WhatsApp 그룹 지능 분석: GPT-4.1 분석 및 음성 메시지 트랜스크립션
If
Set
Code
+
If
Set
Code
52 노드Daniel Lianes
기타
시각화 참조 라이브러리에서 n8n 노드를 탐색
可视化 참조 라이브러리에서 n8n 노드를 탐색
If
Ftp
Set
+
If
Ftp
Set
113 노드I versus AI
기타
WordPress 블로그 자동화 프로페셔널 에디션(심층 연구) v2.1 마켓
GPT-4o, Perplexity AI 및 다국어 지원을 사용한 SEO 최적화 블로그 생성 자동화
If
Set
Xml
+
If
Set
Xml
125 노드Daniel Ng
콘텐츠 제작
Perplexity와 GPT를 사용하여 WordPress에 SEO 최적화 블로그 생성, 키워드와 미디어 포함
Perplexity와 GPT를 사용하여 WordPress에 SEO 최적화 블로그를 만들어 키워드와 미디어 포함
Set
Code
Limit
+
Set
Code
Limit
124 노드Paul
콘텐츠 제작
워크플로우 정보
난이도
고급
노드 수39
카테고리2
노드 유형19
저자
Harry Siggins
@harrysiggins-onetwogrowth외부 링크
n8n.io에서 보기 →
이 워크플로우 공유