Files

542 lines
14 KiB
JSON

{
"name": "77 Live helpdesk (provided)",
"nodes": [
{
"name": "Question webhook",
"type": "n8n-nodes-base.webhook",
"typeVersion": 2,
"parameters": {
"httpMethod": "POST",
"path": "my-helpdesk",
"responseMode": "responseNode",
"options": {}
},
"webhookId": "de518e93-ed19-541f-a6fc-687a4efaf1b2",
"position": [
0,
300
],
"id": "c92ed07d-21e3-5441-bf1f-7547c58d0804"
},
{
"name": "Topic",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"parameters": {
"jsCode": "const q = String($json.body.question ?? '');\nconst table = [['접수 현황', /T-?\\d{4}/i], ['와이파이', /와이파이|wi-?fi/i], ['VPN', /vpn|원격|재택/i], ['비밀번호', /비밀번호|패스워드/i],\n ['프린터', /프린터|인쇄/i], ['메일', /메일|첨부/i], ['설치', /설치|라이선스|프로그램/i]];\nconst hit = table.find(([, re]) => re.test(q));\nreturn [{ json: { topic: hit ? hit[0] : '기타', t0: Date.now() } }];"
},
"position": [
220,
300
],
"id": "88961978-e8ec-5726-a23d-67ca6574360c"
},
{
"name": "Search FAQ",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"parameters": {
"url": "http://data-api:8800/faq",
"options": {
"timeout": 1000
},
"sendQuery": true,
"queryParameters": {
"parameters": [
{
"name": "q",
"value": "={{ $('Question webhook').first().json.body.question }}"
}
]
}
},
"onError": "continueErrorOutput",
"position": [
440,
300
],
"id": "23b65ea5-d9d2-5781-a93c-aa1d5e0ad959"
},
{
"name": "FAQ done",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"parameters": {
"jsCode": "return [{ json: { ...$json, faq_ms: Date.now() - $('Topic').first().json.t0 } }];"
},
"position": [
550,
180
]
},
{
"name": "Found?",
"type": "n8n-nodes-base.if",
"typeVersion": 2.2,
"parameters": {
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "loose",
"version": 2
},
"conditions": [
{
"id": "c1",
"leftValue": "={{ ($json.results ?? []).length > 0 }}",
"rightValue": "",
"operator": {
"type": "boolean",
"operation": "true",
"singleValue": true
}
}
],
"combinator": "and"
},
"options": {}
},
"position": [
660,
300
],
"id": "ebc6810e-e76b-5221-89bb-4c0eb9fad932"
},
{
"name": "Answer",
"type": "@n8n/n8n-nodes-langchain.agent",
"typeVersion": 3.1,
"parameters": {
"promptType": "define",
"text": "=질문: {{ $('Question webhook').first().json.body.question }}\nFAQ: {{ JSON.stringify($('Search FAQ').first().json.results) }}",
"options": {
"systemMessage": "You are the company IT help desk. Answer in Korean in at most 3 sentences using only the FAQ entries given. Never invent steps. Use 합니다체.",
"maxIterations": 1
}
},
"position": [
880,
200
],
"id": "2ee0f4ec-9cdf-507b-aa32-64e9c8f475ef"
},
{
"name": "Answer model",
"type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
"typeVersion": 1.2,
"parameters": {
"model": {
"__rl": true,
"mode": "id",
"value": "gpt-4.1-mini"
},
"options": {
"temperature": 0
}
},
"credentials": {
"openAiApi": {
"id": "openAiCourse0001",
"name": "OpenAI (.env)"
}
},
"position": [
880,
420
],
"id": "1cf57665-a16a-5f55-94b1-732f34b30d91"
},
{
"name": "Answered",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"parameters": {
"jsCode": "const body = $('Question webhook').first().json.body;\nconst t = $('Topic').first().json;\nconst base = { execution_id: Number($execution.id), workflow: 'helpdesk', user: body.user ?? '', topic: t.topic, question: body.question ?? '', release: '1.1.0',\n channel: 'stable', repeat: false, tag: body.tag ?? '', duration_ms: Date.now() - t.t0, cost_usd: 0 };\nconst faq_ms = $('FAQ done').first().json.faq_ms;\nbase.steps = { faq_ms, answer_ms: Math.max(0, base.duration_ms - faq_ms) };\nreturn [{ json: { ...base, status: 'success', error_node: null, error_message: null, route: '자동 답변', llm_calls: 1, answer: String($json.output ?? '').trim() } }];"
},
"position": [
1100,
200
],
"id": "6db09299-84d1-50b1-800f-c074ccb0d3ed"
},
{
"name": "Not found",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"parameters": {
"jsCode": "const body = $('Question webhook').first().json.body;\nconst t = $('Topic').first().json;\nconst base = { execution_id: Number($execution.id), workflow: 'helpdesk', user: body.user ?? '', topic: t.topic, question: body.question ?? '', release: '1.1.0',\n channel: 'stable', repeat: false, tag: body.tag ?? '', duration_ms: Date.now() - t.t0, cost_usd: 0 };\nconst faq_ms = $('FAQ done').first().json.faq_ms;\nbase.steps = { faq_ms, answer_ms: 0 };\nreturn [{ json: { ...base, status: 'success', error_node: null, error_message: null, route: '담당자 연결', llm_calls: 0, answer: 'FAQ에서 찾지 못해 담당자에게 연결합니다.' } }];"
},
"position": [
1100,
400
],
"id": "33f61379-1764-55c7-aff5-3521b1cf451b"
},
{
"name": "Failed",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"parameters": {
"jsCode": "const body = $('Question webhook').first().json.body;\nconst t = $('Topic').first().json;\nconst base = { execution_id: Number($execution.id), workflow: 'helpdesk', user: body.user ?? '', topic: t.topic, question: body.question ?? '', release: '1.1.0',\n channel: 'stable', repeat: false, tag: body.tag ?? '', duration_ms: Date.now() - t.t0, cost_usd: 0 };\nbase.steps = { faq_ms: base.duration_ms, answer_ms: 0 };\nconst message = String($json.error?.message ?? $json.error ?? 'error').slice(0, 120);\nreturn [{ json: { ...base, status: 'error', error_node: 'Search FAQ', error_message: message, route: null, llm_calls: 0, answer: '지금은 답할 수 없어 담당자에게 연결합니다.' } }];"
},
"position": [
1100,
600
],
"id": "6a62a108-4c6c-57fa-b444-3c0b72f85597"
},
{
"name": "Log Answered",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"parameters": {
"url": "http://data-api:8800/logs",
"options": {
"response": {
"response": {
"neverError": true
}
}
},
"method": "POST",
"sendBody": true,
"specifyBody": "json",
"jsonBody": "={{ JSON.stringify({ items: [(({ answer, ...rest }) => rest)($json)] }) }}"
},
"position": [
1320,
200
],
"id": "cc12c3ab-8643-571d-83f4-d27c09dd8e5a"
},
{
"name": "Reply Answered",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"parameters": {
"jsCode": "const r = $('Answered').first().json;\nreturn [{ json: { route: r.route ?? '담당자 연결', status: r.status, topic: r.topic, answer: r.answer, error: r.error_message } }];"
},
"position": [
1540,
200
],
"id": "5c5ffce6-1941-59af-bc8a-5071809d0656"
},
{
"name": "Send Answered",
"type": "n8n-nodes-base.respondToWebhook",
"typeVersion": 1.1,
"parameters": {
"respondWith": "json",
"responseBody": "={{ $json }}",
"options": {}
},
"position": [
1760,
200
],
"id": "1c9e1737-ae60-5754-abbb-2bfab0c7e9b7"
},
{
"name": "Log Not found",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"parameters": {
"url": "http://data-api:8800/logs",
"options": {
"response": {
"response": {
"neverError": true
}
}
},
"method": "POST",
"sendBody": true,
"specifyBody": "json",
"jsonBody": "={{ JSON.stringify({ items: [(({ answer, ...rest }) => rest)($json)] }) }}"
},
"position": [
1320,
400
],
"id": "055e9419-007c-5f4d-b4a6-e70b34ff2a24"
},
{
"name": "Reply Not found",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"parameters": {
"jsCode": "const r = $('Not found').first().json;\nreturn [{ json: { route: r.route ?? '담당자 연결', status: r.status, topic: r.topic, answer: r.answer, error: r.error_message } }];"
},
"position": [
1540,
400
],
"id": "dc79daf9-8f4d-506b-a68b-00f3fd4d44c9"
},
{
"name": "Send Not found",
"type": "n8n-nodes-base.respondToWebhook",
"typeVersion": 1.1,
"parameters": {
"respondWith": "json",
"responseBody": "={{ $json }}",
"options": {}
},
"position": [
1760,
400
],
"id": "df1457bb-ec41-5c08-b3ff-f2284a6e1401"
},
{
"name": "Log Failed",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"parameters": {
"url": "http://data-api:8800/logs",
"options": {
"response": {
"response": {
"neverError": true
}
}
},
"method": "POST",
"sendBody": true,
"specifyBody": "json",
"jsonBody": "={{ JSON.stringify({ items: [(({ answer, ...rest }) => rest)($json)] }) }}"
},
"position": [
1320,
600
],
"id": "760aaaca-e80d-5fe4-9e01-c3772483123d"
},
{
"name": "Reply Failed",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"parameters": {
"jsCode": "const r = $('Failed').first().json;\nreturn [{ json: { route: r.route ?? '담당자 연결', status: r.status, topic: r.topic, answer: r.answer, error: r.error_message } }];"
},
"position": [
1540,
600
],
"id": "addce3eb-ad29-54ac-95c4-87fd3aafb3fc"
},
{
"name": "Send Failed",
"type": "n8n-nodes-base.respondToWebhook",
"typeVersion": 1.1,
"parameters": {
"respondWith": "json",
"responseBody": "={{ $json }}",
"options": {}
},
"position": [
1760,
600
],
"id": "3a330204-2c41-5c6c-93f1-f39b0b04dc0d"
}
],
"connections": {
"Question webhook": {
"main": [
[
{
"node": "Topic",
"type": "main",
"index": 0
}
]
]
},
"Topic": {
"main": [
[
{
"node": "Search FAQ",
"type": "main",
"index": 0
}
]
]
},
"Search FAQ": {
"main": [
[
{
"node": "FAQ done",
"type": "main",
"index": 0
}
],
[
{
"node": "Failed",
"type": "main",
"index": 0
}
]
]
},
"Found?": {
"main": [
[
{
"node": "Answer",
"type": "main",
"index": 0
}
],
[
{
"node": "Not found",
"type": "main",
"index": 0
}
]
]
},
"Answer model": {
"ai_languageModel": [
[
{
"node": "Answer",
"type": "ai_languageModel",
"index": 0
}
]
]
},
"Answer": {
"main": [
[
{
"node": "Answered",
"type": "main",
"index": 0
}
]
]
},
"Answered": {
"main": [
[
{
"node": "Log Answered",
"type": "main",
"index": 0
}
]
]
},
"Log Answered": {
"main": [
[
{
"node": "Reply Answered",
"type": "main",
"index": 0
}
]
]
},
"Reply Answered": {
"main": [
[
{
"node": "Send Answered",
"type": "main",
"index": 0
}
]
]
},
"Not found": {
"main": [
[
{
"node": "Log Not found",
"type": "main",
"index": 0
}
]
]
},
"Log Not found": {
"main": [
[
{
"node": "Reply Not found",
"type": "main",
"index": 0
}
]
]
},
"Reply Not found": {
"main": [
[
{
"node": "Send Not found",
"type": "main",
"index": 0
}
]
]
},
"Failed": {
"main": [
[
{
"node": "Log Failed",
"type": "main",
"index": 0
}
]
]
},
"Log Failed": {
"main": [
[
{
"node": "Reply Failed",
"type": "main",
"index": 0
}
]
]
},
"Reply Failed": {
"main": [
[
{
"node": "Send Failed",
"type": "main",
"index": 0
}
]
]
},
"FAQ done": {
"main": [
[
{
"node": "Found?",
"type": "main",
"index": 0
}
]
]
}
},
"settings": {
"executionOrder": "v1"
}
}