개발자 채팅 질문 답변 캡처(Slack)
고급
이것은Internal Wiki, AI Summarization분야의자동화 워크플로우로, 20개의 노드를 포함합니다.주로 If, Code, Notion, Airtable, GoogleSheets 등의 노드를 사용하며. GPT-4o를 사용하여 Slack에서 개발자 문제를 Notion과 Airtable로 분류
사전 요구사항
- •Notion API Key
- •Airtable API Key
- •Google Sheets API 인증 정보
- •Slack Bot Token 또는 Webhook URL
- •OpenAI API Key
워크플로우 미리보기
노드 연결 관계를 시각적으로 표시하며, 확대/축소 및 이동을 지원합니다
워크플로우 내보내기
다음 JSON 구성을 복사하여 n8n에 가져오면 이 워크플로우를 사용할 수 있습니다
{
"id": "FVAlstK1A75QWcNY",
"meta": {
"instanceId": "8443f10082278c46aa5cf3acf8ff0f70061a2c58bce76efac814b16290845177",
"templateCredsSetupCompleted": true
},
"name": "Developer Chat Q&A Capture (Slack)",
"tags": [],
"nodes": [
{
"id": "d605b180-fd35-4ab7-9bc3-b7ac4d07382a",
"name": "Configure GPT-4o Model",
"type": "@n8n/n8n-nodes-langchain.lmChatAzureOpenAi",
"position": [
-48,
160
],
"parameters": {
"model": "gpt-4o",
"options": {}
},
"credentials": {
"azureOpenAiApi": {
"id": "C3WzT18XqF8OdVM6",
"name": "Azure Open AI account"
}
},
"typeVersion": 1
},
{
"id": "673d6f84-b6df-4ab0-b660-68e9c2f42c58",
"name": "Sticky Note",
"type": "n8n-nodes-base.stickyNote",
"position": [
-1008,
144
],
"parameters": {
"height": 416,
"content": "## Node Name: Slack Channel Trigger – Developer Q&A\n**Action**: Triggers the workflow when a new message is posted in the specified Slack channel.\n**Description**:\nThis node listens for new messages in the Slack channel. \nEach time a developer posts a question or discussion message, it captures the message content, user ID, timestamp, and channel details. \nThis initiates the automation for classifying and responding to developer Q&A.\n"
},
"typeVersion": 1
},
{
"id": "47fcda03-e6b3-4c57-9759-5ecd78e5111c",
"name": "Sticky Note1",
"type": "n8n-nodes-base.stickyNote",
"position": [
-736,
-528
],
"parameters": {
"height": 448,
"content": "## Node Name: Validate Slack Message Payload\n**Action**: Checks if the incoming Slack message includes valid user and text data.\n**Description**:\nThis node ensures that the incoming event payload contains both a valid user ID and message text before proceeding. \nIf the message payload is incomplete or malformed, the workflow redirects execution to the error logging path. \nThis step prevents unnecessary AI calls for empty or system-generated Slack messages.\n"
},
"typeVersion": 1
},
{
"id": "ca80b0ca-55db-4daa-ae54-b0bebeeaa496",
"name": "Sticky Note2",
"type": "n8n-nodes-base.stickyNote",
"position": [
-48,
-592
],
"parameters": {
"height": 496,
"content": "## Node Name: Classify Developer Question (AI)\n**Action**: Uses GPT-4o to determine whether the Slack message matches a known FAQ.\n**Description**:\nThis AI Agent compares the new Slack question against an internal FAQ knowledge base. \nIf a close match is found, GPT-4o returns structured JSON indicating “answered,” along with a canonical response and quality rating. \nIf no match exists, it flags the query as “unanswered,” prompting human follow-up. \nThis ensures that recurring developer issues are identified and reused efficiently."
},
"typeVersion": 1
},
{
"id": "3de471ba-4941-4bd4-b4c8-c0ef1ddac91d",
"name": "Sticky Note3",
"type": "n8n-nodes-base.stickyNote",
"position": [
-384,
-528
],
"parameters": {
"height": 448,
"content": "## Node Name: Extract Question Metadata (JavaScript)\n**Action**: Cleans and structures Slack message data into a standardized JSON format.\n**Description**:\nThis JavaScript node extracts key fields — message text, user ID, timestamp, and channel — and removes unwanted characters or formatting (`>`, newlines, quotes). \nIt creates a clean “question object” ready for AI classification, improving accuracy and processing consistency.\n"
},
"typeVersion": 1
},
{
"id": "4918701a-c839-4ccc-8520-68896948d3b7",
"name": "Sticky Note4",
"type": "n8n-nodes-base.stickyNote",
"position": [
-64,
320
],
"parameters": {
"height": 384,
"content": "## Node Name: Configure GPT-4o Model\n**Action**: Sets up Azure OpenAI GPT-4o as the active AI model.\n**Description**:\nThis node configures the GPT-4o model as the underlying large language model for question classification and similarity matching. \nIt enables intelligent comparison of Slack questions with internal FAQ data using semantic understanding.\n"
},
"typeVersion": 1
},
{
"id": "e49f36cf-2e1c-46cb-82b8-933828f06eee",
"name": "Sticky Note5",
"type": "n8n-nodes-base.stickyNote",
"position": [
-448,
528
],
"parameters": {
"height": 416,
"content": "## Node Name: Log Workflow Errors to Google Sheets\n**Action**: Logs missing payloads or node execution errors into a Google Sheet.\n**Description**:\nIf a Slack event, AI response, or integration call fails, this node appends an entry in the “error log sheet.” \nEach entry contains the error ID and description, enabling quick monitoring and debugging. \nThis maintains workflow transparency and ensures no silent automation failures.\n"
},
"typeVersion": 1
},
{
"id": "2579076f-312f-42a3-a4ec-28a06734d309",
"name": "Sticky Note6",
"type": "n8n-nodes-base.stickyNote",
"position": [
288,
-512
],
"parameters": {
"height": 432,
"content": "## Node Name: Parse AI JSON Output\n**Action**: Converts the AI’s string output into structured JSON for further logic.\n**Description**:\nThe GPT model returns text formatted as JSON, but downstream nodes require an actual object. \nThis code node safely parses that text into valid JSON, making keys like `status`, `answer_quality`, and `canonical_answer` accessible for conditional checks. \nActs as the bridge between the AI’s output and workflow logic.\n"
},
"typeVersion": 1
},
{
"id": "8acec43e-5345-47e6-b982-0ca2fc8bb8f6",
"name": "Sticky Note7",
"type": "n8n-nodes-base.stickyNote",
"position": [
544,
112
],
"parameters": {
"height": 448,
"content": "## Node Name: Check If Question Was Answered\n**Action**: Evaluates the AI’s response to decide if the Slack question was resolved.\n**Description**:\nThis IF node checks whether `status == \"answered\"`. \nIf true, the flow routes toward the Notion database for documentation. \nIf false, it diverts to the Airtable node for escalation and manual review. \nImplements automated decision-making between documentation and triage paths.\n"
},
"typeVersion": 1
},
{
"id": "6aca240f-06ae-4efa-81da-de358ff558c2",
"name": "Sticky Note8",
"type": "n8n-nodes-base.stickyNote",
"position": [
880,
-736
],
"parameters": {
"height": 496,
"content": "## Node Name: Save Answered Question to Notion FAQ\n**Action**: Logs answered questions and AI explanations in the Notion database.\n**Description**:\nThis node creates a Notion entry within the database. \nIt records fields like `Status`, `Answer Quality`, and the AI’s `Canonical Answer`. \nHelps maintain a living internal knowledge base automatically enriched from Slack discussions. \nEnables rapid reuse of resolved questions and promotes team self-help.\n"
},
"typeVersion": 1
},
{
"id": "5e8735d8-e19a-4022-8a88-11a5c089628d",
"name": "Sticky Note9",
"type": "n8n-nodes-base.stickyNote",
"position": [
912,
336
],
"parameters": {
"height": 464,
"content": "## Node Name: Log Unanswered Question to Airtable\n**Action**: Records new or unrecognized questions into Airtable for review.\n**Description**:\nThis Airtable node creates a record containing the Slack question text, user ID, message ID, and AI classification results. \nUsed for tracking unresolved or novel issues that should be reviewed by developers or support engineers. \nOver time, these entries feed back into the internal FAQ training loop.\n"
},
"typeVersion": 1
},
{
"id": "0f0577a1-998f-4d2a-bcc8-bdad6ce83712",
"name": "Slack Channel Trigger – Developer Q&A",
"type": "n8n-nodes-base.slackTrigger",
"position": [
-944,
-32
],
"webhookId": "56e594a0-b975-429c-9a8a-52c768c1589e",
"parameters": {
"options": {},
"trigger": [
"message"
],
"channelId": {
"__rl": true,
"mode": "list",
"value": "C09CVLMSF3R",
"cachedResultName": "issue-smarteremr"
}
},
"credentials": {
"slackApi": {
"id": "rNqvWj9TfChPVRYY",
"name": "Slack account vivek"
}
},
"typeVersion": 1
},
{
"id": "4ae060d6-e45c-4186-8ca4-fc6254b937df",
"name": "Validate Slack Message Payload",
"type": "n8n-nodes-base.if",
"position": [
-672,
-32
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "e2adb005-2b3c-4d1e-8445-442df1fe925a",
"operator": {
"type": "string",
"operation": "notEmpty",
"singleValue": true
},
"leftValue": "={{ $json.user }}",
"rightValue": ""
}
]
}
},
"typeVersion": 2.2
},
{
"id": "e7aea1a1-c5d6-4036-b964-f7261b82f5a4",
"name": "질문 메타데이터 추출 (JavaScript)",
"type": "n8n-nodes-base.code",
"position": [
-320,
-48
],
"parameters": {
"jsCode": "return [{\n question: $json.text.replace(/>|[\\n\"]/g, '').trim(),\n user: $json.user,\n timestamp: $json.ts,\n channel: $json.channel\n}];\n"
},
"typeVersion": 2
},
{
"id": "582017af-c1ee-4670-87a8-b3fd5baf3199",
"name": "개발자 질문 분류 (AI)",
"type": "@n8n/n8n-nodes-langchain.agent",
"position": [
-16,
-48
],
"parameters": {
"text": "=You are a Slack Q&A classifier for developer discussions. \nYou have the following internal FAQ knowledge:\n\n1. Q: How to connect local API server to staging database? \n A: Update the `.env` file with staging DB credentials and restart the service.\n\n2. Q: How to restart the backend server? \n A: Run `pm2 restart backend` or `npm run serve` depending on environment.\n\n3. Q: How to fix 401 error on /auth/login endpoint? \n A: Ensure the auth token is refreshed using the /refresh-token route before login.\n\n---\n\nYour job:\nWhen a new developer question comes in, check if it matches (or is similar) to one of the questions above. \nIf yes, output JSON like this:\n{\n \"status\": \"answered\",\n \"answer_quality\": \"strong\",\n \"canonical_answer\": \"(matching answer from above)\"\n}\n\nIf no match found, output:\n{\n \"status\": \"unanswered\",\n \"answer_quality\": \"weak\",\n \"canonical_answer\": \"\"\n}\nAlways respond with clean JSON only.\n",
"options": {
"systemMessage": "=Question: {{$json.question}}\n"
},
"promptType": "define"
},
"typeVersion": 2.1
},
{
"id": "fd788ab2-46df-498d-a8df-b4d45161ffd5",
"name": "Parse AI JSON Output",
"type": "n8n-nodes-base.code",
"position": [
368,
-48
],
"parameters": {
"jsCode": "return [JSON.parse($json.output)];\n"
},
"typeVersion": 2
},
{
"id": "53a743a3-1b56-419b-a8f6-1a5c8af21ec1",
"name": "질문 답변 여부 확인",
"type": "n8n-nodes-base.if",
"position": [
656,
-48
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "b082c89c-ddea-4183-ad99-04b76ffb9bdb",
"operator": {
"name": "filter.operator.equals",
"type": "string",
"operation": "equals"
},
"leftValue": "={{ $json.status }}",
"rightValue": "answered"
}
]
}
},
"typeVersion": 2.2
},
{
"id": "050dfc42-d32a-48cc-ab95-f47ba238d719",
"name": "답변된 질문을 Notion FAQ에 저장",
"type": "n8n-nodes-base.notion",
"position": [
944,
-208
],
"parameters": {
"title": "={{ $('Slack Channel Trigger – Developer Q&A').item.json.text }}",
"simple": false,
"options": {},
"resource": "databasePage",
"databaseId": {
"__rl": true,
"mode": "list",
"value": "29a802b9-1fa0-804a-b406-e078961e0659",
"cachedResultUrl": "https://www.notion.so/29a802b91fa0804ab406e078961e0659",
"cachedResultName": "Release Notes"
},
"propertiesUi": {
"propertyValues": [
{
"key": "Status|rich_text",
"textContent": "={{ $json.status }}"
},
{
"key": "Priority|rich_text",
"textContent": "={{ $json.answer_quality }}"
},
{
"key": "FAQ Content|rich_text",
"textContent": "={{ $json.canonical_answer }}"
}
]
}
},
"credentials": {
"notionApi": {
"id": "iDjtgSTYG9ECVBtT",
"name": "Notion account 2"
}
},
"typeVersion": 2.2
},
{
"id": "9c8a1797-2cc1-415c-839c-88dd8b4aa1b5",
"name": "미답변 질문을 Airtable에 기록",
"type": "n8n-nodes-base.airtable",
"position": [
944,
160
],
"parameters": {
"base": {
"__rl": true,
"mode": "list",
"value": "appsZ3Uuh5PnD215s",
"cachedResultUrl": "https://airtable.com/appsZ3Uuh5PnD215s",
"cachedResultName": "Github Issue"
},
"table": {
"__rl": true,
"mode": "list",
"value": "tblZvyR7J8hndLlUZ",
"cachedResultUrl": "https://airtable.com/appsZ3Uuh5PnD215s/tblZvyR7J8hndLlUZ",
"cachedResultName": "Table 1"
},
"columns": {
"value": {
"Name": "={{ $('Slack Channel Trigger – Developer Q&A').item.json.text }}",
"Status": "Todo",
"FAQ Match": "={{ $json.answer_quality }}",
"Error Code": "={{ $json.status }}",
"Issue Number": "={{ $('Slack Channel Trigger – Developer Q&A').item.json.client_msg_id }}"
},
"schema": [
{
"id": "Name",
"type": "string",
"display": true,
"removed": false,
"readOnly": false,
"required": false,
"displayName": "Name",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Status",
"type": "options",
"display": true,
"options": [
{
"name": "Todo",
"value": "Todo"
},
{
"name": "In progress",
"value": "In progress"
},
{
"name": "Done",
"value": "Done"
}
],
"removed": false,
"readOnly": false,
"required": false,
"displayName": "Status",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Error Code",
"type": "string",
"display": true,
"removed": false,
"readOnly": false,
"required": false,
"displayName": "Error Code",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Error Category",
"type": "string",
"display": true,
"removed": true,
"readOnly": false,
"required": false,
"displayName": "Error Category",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "FAQ Match",
"type": "string",
"display": true,
"removed": false,
"readOnly": false,
"required": false,
"displayName": "FAQ Match",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Root Cause",
"type": "string",
"display": true,
"removed": true,
"readOnly": false,
"required": false,
"displayName": "Root Cause",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Suggested Action",
"type": "string",
"display": true,
"removed": true,
"readOnly": false,
"required": false,
"displayName": "Suggested Action",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Confidence",
"type": "string",
"display": true,
"removed": true,
"readOnly": false,
"required": false,
"displayName": "Confidence",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Severity",
"type": "string",
"display": true,
"removed": true,
"readOnly": false,
"required": false,
"displayName": "Severity",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Affected Endpoint",
"type": "string",
"display": true,
"removed": true,
"readOnly": false,
"required": false,
"displayName": "Affected Endpoint",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Source URL",
"type": "string",
"display": true,
"removed": true,
"readOnly": false,
"required": false,
"displayName": "Source URL",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Repository",
"type": "string",
"display": true,
"removed": true,
"readOnly": false,
"required": false,
"displayName": "Repository",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Issue Number",
"type": "string",
"display": true,
"removed": false,
"readOnly": false,
"required": false,
"displayName": "Issue Number",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Created At",
"type": "string",
"display": true,
"removed": true,
"readOnly": true,
"required": false,
"displayName": "Created At",
"defaultMatch": false,
"canBeUsedToMatch": true
}
],
"mappingMode": "defineBelow",
"matchingColumns": [],
"attemptToConvertTypes": false,
"convertFieldsToString": false
},
"options": {},
"operation": "create"
},
"credentials": {
"airtableTokenApi": {
"id": "nWc9JHR6t25WPWVV",
"name": "Airtable Personal Access Token account"
}
},
"typeVersion": 2.1
},
{
"id": "9a40948e-659c-42ef-8817-985eab6191d6",
"name": "워크플로 오류를 Google Sheets에 기록",
"type": "n8n-nodes-base.googleSheets",
"position": [
-384,
336
],
"parameters": {
"columns": {
"value": {},
"schema": [
{
"id": "error_id",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "error_id",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "error",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "error",
"defaultMatch": false,
"canBeUsedToMatch": true
}
],
"mappingMode": "defineBelow",
"matchingColumns": [
"error_id"
],
"attemptToConvertTypes": false,
"convertFieldsToString": false
},
"options": {},
"operation": "append",
"sheetName": {
"__rl": true,
"mode": "list",
"value": 1338537721,
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1Uldk_4BxWbdZTDZxFUeohIfeBmGHHqVEl9Ogb0l6R8Y/edit#gid=1338537721",
"cachedResultName": "error log sheet"
},
"documentId": {
"__rl": true,
"mode": "list",
"value": "1Uldk_4BxWbdZTDZxFUeohIfeBmGHHqVEl9Ogb0l6R8Y",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1Uldk_4BxWbdZTDZxFUeohIfeBmGHHqVEl9Ogb0l6R8Y/edit?usp=drivesdk",
"cachedResultName": "Interviewer Brief Pack "
}
},
"credentials": {
"googleSheetsOAuth2Api": {
"id": "kpPEOLCGn963qpoh",
"name": "automations@techdome.ai"
}
},
"typeVersion": 4.6
}
],
"active": false,
"pinData": {},
"settings": {
"executionOrder": "v1"
},
"versionId": "5d86bdfd-9f04-44c3-b043-b573e72cfe3b",
"connections": {
"fd788ab2-46df-498d-a8df-b4d45161ffd5": {
"main": [
[
{
"node": "53a743a3-1b56-419b-a8f6-1a5c8af21ec1",
"type": "main",
"index": 0
}
]
]
},
"d605b180-fd35-4ab7-9bc3-b7ac4d07382a": {
"ai_languageModel": [
[
{
"node": "582017af-c1ee-4670-87a8-b3fd5baf3199",
"type": "ai_languageModel",
"index": 0
}
]
]
},
"53a743a3-1b56-419b-a8f6-1a5c8af21ec1": {
"main": [
[
{
"node": "050dfc42-d32a-48cc-ab95-f47ba238d719",
"type": "main",
"index": 0
}
],
[
{
"node": "9c8a1797-2cc1-415c-839c-88dd8b4aa1b5",
"type": "main",
"index": 0
}
]
]
},
"4ae060d6-e45c-4186-8ca4-fc6254b937df": {
"main": [
[
{
"node": "e7aea1a1-c5d6-4036-b964-f7261b82f5a4",
"type": "main",
"index": 0
}
],
[
{
"node": "9a40948e-659c-42ef-8817-985eab6191d6",
"type": "main",
"index": 0
}
]
]
},
"582017af-c1ee-4670-87a8-b3fd5baf3199": {
"main": [
[
{
"node": "fd788ab2-46df-498d-a8df-b4d45161ffd5",
"type": "main",
"index": 0
}
]
]
},
"e7aea1a1-c5d6-4036-b964-f7261b82f5a4": {
"main": [
[
{
"node": "582017af-c1ee-4670-87a8-b3fd5baf3199",
"type": "main",
"index": 0
}
]
]
},
"0f0577a1-998f-4d2a-bcc8-bdad6ce83712": {
"main": [
[
{
"node": "4ae060d6-e45c-4186-8ca4-fc6254b937df",
"type": "main",
"index": 0
}
]
]
}
}
}자주 묻는 질문
이 워크플로우를 어떻게 사용하나요?
위의 JSON 구성 코드를 복사하여 n8n 인스턴스에서 새 워크플로우를 생성하고 "JSON에서 가져오기"를 선택한 후, 구성을 붙여넣고 필요에 따라 인증 설정을 수정하세요.
이 워크플로우는 어떤 시나리오에 적합한가요?
고급 - 내부 위키, AI 요약
유료인가요?
이 워크플로우는 완전히 무료이며 직접 가져와 사용할 수 있습니다. 다만, 워크플로우에서 사용하는 타사 서비스(예: OpenAI API)는 사용자 직접 비용을 지불해야 할 수 있습니다.
관련 워크플로우 추천
API 속도 제한 및 인증 FAQ 테스트
GPT-4o-mini, Google 시트 및 Slack 알림을 사용한 API FAQ 품질 테스트 자동화
If
Set
Code
+
If
Set
Code
19 노드Rahul Joshi
문서 추출
AI 기반 API 오류 디렉토리 구축: GitHub에서 Airtable, Notion, Slack으로
GPT-4o를 사용하여 GitHub API 오류를 Airtable, Notion, Slack에 자동 감지 및 분류
If
Set
Code
+
If
Set
Code
30 노드Rahul Joshi
티켓 관리
자동화 의존성 업데이트 추적
GPT-4o, Slack, Jira, Google Sheets를 사용하여 의존성 업데이트 위험 분석
If
Set
Code
+
If
Set
Code
23 노드Rahul Joshi
데브옵스
코드 주석을 FAQ로 동기화 (GitHub)
GPT-4o, Notion 및 Slack을 사용한 개발 팀을 위한 GitHub PR 질문 자동 답변
If
Code
Slack
+
If
Code
Slack
18 노드Rahul Joshi
엔지니어링
신입 개발자 온보딩 자동화
GPT-4o를 사용한 직원 온보딩 자동화: Jira, Notion, Gmail 통합
If
Set
Code
+
If
Set
Code
21 노드Rahul Joshi
인사
릴리스 노트를 FAQ 스텁으로 변환(Jira/ClickUp)
GPT-4o를 사용한 ClickUp에서 Notion 및 Slack으로 릴리스 노트 자동 생성
If
Code
Gmail
+
If
Code
Gmail
20 노드Rahul Joshi
엔지니어링
워크플로우 정보
난이도
고급
노드 수20
카테고리2
노드 유형9
저자
Rahul Joshi
@rahul08Rahul Joshi is a seasoned technology leader specializing in the n8n automation tool and AI-driven workflow automation. With deep expertise in building open-source workflow automation and self-hosted automation platforms, he helps organizations eliminate manual processes through intelligent n8n ai agent automation solutions.
외부 링크
n8n.io에서 보기 →
이 워크플로우 공유