workflow: n8n 워크플로우 분리 (conversation/skills/rag/scheduler)
Made-with: Cursor
This commit is contained in:
parent
3b13bdcc87
commit
d16124b499
108
workflow/01_conversation/slack_action_extractor_request.json
Normal file
108
workflow/01_conversation/slack_action_extractor_request.json
Normal file
@ -0,0 +1,108 @@
|
||||
{
|
||||
"name": "robeing-slack-action-extractor-request",
|
||||
"nodes": [
|
||||
{
|
||||
"parameters": {
|
||||
"channelId": {
|
||||
"__rl": true,
|
||||
"mode": "list",
|
||||
"value": ""
|
||||
},
|
||||
"options": {}
|
||||
},
|
||||
"id": "conv-act-001",
|
||||
"name": "Slack Trigger",
|
||||
"type": "n8n-nodes-base.slackTrigger",
|
||||
"typeVersion": 1,
|
||||
"position": [220, 220]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"jsCode": "const event = $json.event || {};\nconst text = (event.text || '').replace(/<@[^>]+>/g, '').trim();\nconst wantsActions = /할 일|액션|todo|action/i.test(text);\nreturn {\n should_process: wantsActions && Boolean(event.channel) && Boolean(event.user),\n channel_id: event.channel || '',\n thread_ts: event.thread_ts || event.ts || '',\n company_id: event.team || event.team_id || '',\n user_id: event.user || ''\n};"
|
||||
},
|
||||
"id": "conv-act-002",
|
||||
"name": "Detect Action Intent",
|
||||
"type": "n8n-nodes-base.code",
|
||||
"typeVersion": 2,
|
||||
"position": [460, 220]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"conditions": {
|
||||
"boolean": [
|
||||
{
|
||||
"value1": "={{ $json.should_process }}",
|
||||
"value2": true
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"id": "conv-act-003",
|
||||
"name": "Action Request?",
|
||||
"type": "n8n-nodes-base.if",
|
||||
"typeVersion": 2,
|
||||
"position": [700, 220]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"method": "POST",
|
||||
"url": "=http://192.168.219.52:8502/api/v1/extract-actions",
|
||||
"sendBody": true,
|
||||
"specifyBody": "json",
|
||||
"jsonBody": "={\"company_id\":\"{{$json.company_id}}\",\"user_id\":\"{{$json.user_id}}\",\"skill_level\":1,\"channel_id\":\"{{$json.channel_id}}\",\"time_range\":\"24h\",\"auto_assign\":true,\"priority_detection\":true}",
|
||||
"options": {
|
||||
"response": {
|
||||
"response": {
|
||||
"fullResponse": true
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"id": "conv-act-004",
|
||||
"name": "Call skill-slack Extract Actions",
|
||||
"type": "n8n-nodes-base.httpRequest",
|
||||
"typeVersion": 4.2,
|
||||
"position": [970, 160]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"jsCode": "const body = $json.body || {};\nconst req = $('Detect Action Intent').item.json;\nconst items = body.action_items || [];\nconst lines = items.length ? items.map((item, index) => `${index + 1}. ${item.task}${item.assignee ? ' / 담당: ' + item.assignee : ''}${item.priority ? ' / 우선순위: ' + item.priority : ''}`).join('\\n') : '추출된 액션 아이템이 없습니다.';\nreturn { channel: req.channel_id, thread_ts: req.thread_ts, text: lines };"
|
||||
},
|
||||
"id": "conv-act-005",
|
||||
"name": "Build Action Reply",
|
||||
"type": "n8n-nodes-base.code",
|
||||
"typeVersion": 2,
|
||||
"position": [1230, 160]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"resource": "message",
|
||||
"operation": "post",
|
||||
"channel": "={{ $json.channel }}",
|
||||
"text": "={{ $json.text }}",
|
||||
"otherOptions": {
|
||||
"threadTs": "={{ $json.thread_ts }}"
|
||||
}
|
||||
},
|
||||
"id": "conv-act-006",
|
||||
"name": "Reply to Slack",
|
||||
"type": "n8n-nodes-base.slack",
|
||||
"typeVersion": 2,
|
||||
"position": [1480, 160]
|
||||
}
|
||||
],
|
||||
"connections": {
|
||||
"Slack Trigger": { "main": [[{ "node": "Detect Action Intent", "type": "main", "index": 0 }]] },
|
||||
"Detect Action Intent": { "main": [[{ "node": "Action Request?", "type": "main", "index": 0 }]] },
|
||||
"Action Request?": {
|
||||
"main": [
|
||||
[{ "node": "Call skill-slack Extract Actions", "type": "main", "index": 0 }],
|
||||
[]
|
||||
]
|
||||
},
|
||||
"Call skill-slack Extract Actions": { "main": [[{ "node": "Build Action Reply", "type": "main", "index": 0 }]] },
|
||||
"Build Action Reply": { "main": [[{ "node": "Reply to Slack", "type": "main", "index": 0 }]] }
|
||||
},
|
||||
"pinData": {},
|
||||
"meta": { "templateCredsSetupCompleted": true, "instanceId": "robeing-conversation" }
|
||||
}
|
||||
167
workflow/01_conversation/slack_basic_dialogue.json
Normal file
167
workflow/01_conversation/slack_basic_dialogue.json
Normal file
@ -0,0 +1,167 @@
|
||||
{
|
||||
"name": "robeing-slack-basic-dialogue",
|
||||
"nodes": [
|
||||
{
|
||||
"parameters": {
|
||||
"channelId": {
|
||||
"__rl": true,
|
||||
"mode": "list",
|
||||
"value": ""
|
||||
},
|
||||
"options": {}
|
||||
},
|
||||
"id": "conv-001",
|
||||
"name": "Slack Trigger",
|
||||
"type": "n8n-nodes-base.slackTrigger",
|
||||
"typeVersion": 1,
|
||||
"position": [240, 260]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"jsCode": "const event = $json.event || {};\nconst text = event.text || '';\nconst question = text.replace(/<@[^>]+>/g, '').trim();\nconst skip = !event.user || !event.channel || !question || Boolean(event.bot_id) || event.subtype === 'bot_message';\nreturn {\n should_process: !skip,\n team_id: event.team || event.team_id || '',\n channel: event.channel || '',\n user_id: event.user || '',\n thread_ts: event.thread_ts || event.ts || '',\n question,\n robeing_id: 'rb8001'\n};"
|
||||
},
|
||||
"id": "conv-002",
|
||||
"name": "Normalize Event",
|
||||
"type": "n8n-nodes-base.code",
|
||||
"typeVersion": 2,
|
||||
"position": [500, 260]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"conditions": {
|
||||
"boolean": [
|
||||
{
|
||||
"value1": "={{ $json.should_process }}",
|
||||
"value2": true
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"id": "conv-003",
|
||||
"name": "Should Process?",
|
||||
"type": "n8n-nodes-base.if",
|
||||
"typeVersion": 2,
|
||||
"position": [740, 260]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"method": "GET",
|
||||
"url": "=http://192.168.219.45:9000/api/slack/mapping/{{$json.user_id}}",
|
||||
"options": {
|
||||
"response": {
|
||||
"response": {
|
||||
"fullResponse": true
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"id": "conv-004",
|
||||
"name": "Get User Mapping",
|
||||
"type": "n8n-nodes-base.httpRequest",
|
||||
"typeVersion": 4.2,
|
||||
"position": [980, 180]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"jsCode": "const mapping = $json.body || {};\nconst base = $('Normalize Event').item.json;\nreturn {\n channel: base.channel,\n thread_ts: base.thread_ts,\n user_uuid: mapping.user_id || mapping.id || mapping.uuid || '',\n request_body: {\n message: base.question,\n source: 'slack',\n context: {\n slack: {\n team_id: base.team_id,\n channel: base.channel,\n user_id: base.user_id,\n thread_ts: base.thread_ts\n },\n robeing: {\n robeing_id: base.robeing_id\n }\n }\n }\n};"
|
||||
},
|
||||
"id": "conv-005",
|
||||
"name": "Build Gateway Request",
|
||||
"type": "n8n-nodes-base.code",
|
||||
"typeVersion": 2,
|
||||
"position": [1220, 180]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"method": "POST",
|
||||
"url": "=http://192.168.219.45:8100/api/chat",
|
||||
"sendHeaders": true,
|
||||
"headerParameters": {
|
||||
"parameters": [
|
||||
{
|
||||
"name": "Content-Type",
|
||||
"value": "application/json"
|
||||
},
|
||||
{
|
||||
"name": "X-User-Id",
|
||||
"value": "={{ $json.user_uuid }}"
|
||||
}
|
||||
]
|
||||
},
|
||||
"sendBody": true,
|
||||
"specifyBody": "json",
|
||||
"jsonBody": "={{ $json.request_body }}",
|
||||
"options": {
|
||||
"response": {
|
||||
"response": {
|
||||
"fullResponse": true
|
||||
}
|
||||
},
|
||||
"timeout": 60000
|
||||
}
|
||||
},
|
||||
"id": "conv-006",
|
||||
"name": "Call Robeing Gateway",
|
||||
"type": "n8n-nodes-base.httpRequest",
|
||||
"typeVersion": 4.2,
|
||||
"position": [1470, 180]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"jsCode": "const body = $json.body || {};\nconst base = $('Build Gateway Request').item.json;\nreturn {\n channel: base.channel,\n thread_ts: base.thread_ts,\n text: body.reply || body.response || body.message || body.text || '지금은 응답을 생성하지 못했습니다. 잠시 후 다시 시도해주세요.'\n};"
|
||||
},
|
||||
"id": "conv-007",
|
||||
"name": "Prepare Slack Reply",
|
||||
"type": "n8n-nodes-base.code",
|
||||
"typeVersion": 2,
|
||||
"position": [1710, 180]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"resource": "message",
|
||||
"operation": "post",
|
||||
"channel": "={{ $json.channel }}",
|
||||
"text": "={{ $json.text }}",
|
||||
"otherOptions": {
|
||||
"threadTs": "={{ $json.thread_ts }}"
|
||||
}
|
||||
},
|
||||
"id": "conv-008",
|
||||
"name": "Reply to Slack",
|
||||
"type": "n8n-nodes-base.slack",
|
||||
"typeVersion": 2,
|
||||
"position": [1950, 180]
|
||||
}
|
||||
],
|
||||
"connections": {
|
||||
"Slack Trigger": {
|
||||
"main": [[{ "node": "Normalize Event", "type": "main", "index": 0 }]]
|
||||
},
|
||||
"Normalize Event": {
|
||||
"main": [[{ "node": "Should Process?", "type": "main", "index": 0 }]]
|
||||
},
|
||||
"Should Process?": {
|
||||
"main": [
|
||||
[{ "node": "Get User Mapping", "type": "main", "index": 0 }],
|
||||
[]
|
||||
]
|
||||
},
|
||||
"Get User Mapping": {
|
||||
"main": [[{ "node": "Build Gateway Request", "type": "main", "index": 0 }]]
|
||||
},
|
||||
"Build Gateway Request": {
|
||||
"main": [[{ "node": "Call Robeing Gateway", "type": "main", "index": 0 }]]
|
||||
},
|
||||
"Call Robeing Gateway": {
|
||||
"main": [[{ "node": "Prepare Slack Reply", "type": "main", "index": 0 }]]
|
||||
},
|
||||
"Prepare Slack Reply": {
|
||||
"main": [[{ "node": "Reply to Slack", "type": "main", "index": 0 }]]
|
||||
}
|
||||
},
|
||||
"pinData": {},
|
||||
"meta": {
|
||||
"templateCredsSetupCompleted": true,
|
||||
"instanceId": "robeing-conversation"
|
||||
}
|
||||
}
|
||||
108
workflow/01_conversation/slack_thread_summary_request.json
Normal file
108
workflow/01_conversation/slack_thread_summary_request.json
Normal file
@ -0,0 +1,108 @@
|
||||
{
|
||||
"name": "robeing-slack-thread-summary-request",
|
||||
"nodes": [
|
||||
{
|
||||
"parameters": {
|
||||
"channelId": {
|
||||
"__rl": true,
|
||||
"mode": "list",
|
||||
"value": ""
|
||||
},
|
||||
"options": {}
|
||||
},
|
||||
"id": "conv-sum-001",
|
||||
"name": "Slack Trigger",
|
||||
"type": "n8n-nodes-base.slackTrigger",
|
||||
"typeVersion": 1,
|
||||
"position": [220, 220]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"jsCode": "const event = $json.event || {};\nconst text = (event.text || '').replace(/<@[^>]+>/g, '').trim();\nconst wantsSummary = /요약|정리|digest|summary/i.test(text);\nreturn {\n should_process: wantsSummary && Boolean(event.channel) && Boolean(event.user),\n channel_id: event.channel || '',\n thread_ts: event.thread_ts || event.ts || '',\n text,\n company_id: event.team || event.team_id || '',\n user_id: event.user || ''\n};"
|
||||
},
|
||||
"id": "conv-sum-002",
|
||||
"name": "Detect Summary Intent",
|
||||
"type": "n8n-nodes-base.code",
|
||||
"typeVersion": 2,
|
||||
"position": [460, 220]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"conditions": {
|
||||
"boolean": [
|
||||
{
|
||||
"value1": "={{ $json.should_process }}",
|
||||
"value2": true
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"id": "conv-sum-003",
|
||||
"name": "Summary Request?",
|
||||
"type": "n8n-nodes-base.if",
|
||||
"typeVersion": 2,
|
||||
"position": [700, 220]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"method": "POST",
|
||||
"url": "=http://192.168.219.52:8502/api/v1/summarize",
|
||||
"sendBody": true,
|
||||
"specifyBody": "json",
|
||||
"jsonBody": "={\"company_id\":\"{{$json.company_id}}\",\"user_id\":\"{{$json.user_id}}\",\"skill_level\":1,\"channel_id\":\"{{$json.channel_id}}\",\"thread_ts\":\"{{$json.thread_ts}}\",\"time_range\":\"24h\",\"options\":{\"include_files\":true,\"include_reactions\":false}}",
|
||||
"options": {
|
||||
"response": {
|
||||
"response": {
|
||||
"fullResponse": true
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"id": "conv-sum-004",
|
||||
"name": "Call skill-slack Summarize",
|
||||
"type": "n8n-nodes-base.httpRequest",
|
||||
"typeVersion": 4.2,
|
||||
"position": [960, 160]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"jsCode": "const body = $json.body || {};\nconst req = $('Detect Summary Intent').item.json;\nreturn {\n channel: req.channel_id,\n thread_ts: req.thread_ts,\n text: body.summary || '요약 결과를 가져오지 못했습니다.'\n};"
|
||||
},
|
||||
"id": "conv-sum-005",
|
||||
"name": "Build Summary Reply",
|
||||
"type": "n8n-nodes-base.code",
|
||||
"typeVersion": 2,
|
||||
"position": [1210, 160]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"resource": "message",
|
||||
"operation": "post",
|
||||
"channel": "={{ $json.channel }}",
|
||||
"text": "={{ $json.text }}",
|
||||
"otherOptions": {
|
||||
"threadTs": "={{ $json.thread_ts }}"
|
||||
}
|
||||
},
|
||||
"id": "conv-sum-006",
|
||||
"name": "Reply to Slack",
|
||||
"type": "n8n-nodes-base.slack",
|
||||
"typeVersion": 2,
|
||||
"position": [1450, 160]
|
||||
}
|
||||
],
|
||||
"connections": {
|
||||
"Slack Trigger": { "main": [[{ "node": "Detect Summary Intent", "type": "main", "index": 0 }]] },
|
||||
"Detect Summary Intent": { "main": [[{ "node": "Summary Request?", "type": "main", "index": 0 }]] },
|
||||
"Summary Request?": {
|
||||
"main": [
|
||||
[{ "node": "Call skill-slack Summarize", "type": "main", "index": 0 }],
|
||||
[]
|
||||
]
|
||||
},
|
||||
"Call skill-slack Summarize": { "main": [[{ "node": "Build Summary Reply", "type": "main", "index": 0 }]] },
|
||||
"Build Summary Reply": { "main": [[{ "node": "Reply to Slack", "type": "main", "index": 0 }]] }
|
||||
},
|
||||
"pinData": {},
|
||||
"meta": { "templateCredsSetupCompleted": true, "instanceId": "robeing-conversation" }
|
||||
}
|
||||
57
workflow/02_skills/skill_email_send_request.json
Normal file
57
workflow/02_skills/skill_email_send_request.json
Normal file
@ -0,0 +1,57 @@
|
||||
{
|
||||
"name": "robeing-skill-email-send-request",
|
||||
"nodes": [
|
||||
{
|
||||
"parameters": {
|
||||
"httpMethod": "POST",
|
||||
"path": "skills/email/send",
|
||||
"responseMode": "responseNode",
|
||||
"options": {}
|
||||
},
|
||||
"id": "skill-email-001",
|
||||
"name": "Webhook In",
|
||||
"type": "n8n-nodes-base.webhook",
|
||||
"typeVersion": 1,
|
||||
"position": [220, 220]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"method": "POST",
|
||||
"url": "=http://192.168.219.52:8501/api/v1/send",
|
||||
"sendBody": true,
|
||||
"specifyBody": "json",
|
||||
"jsonBody": "={{ $json.body }}",
|
||||
"options": {
|
||||
"response": {
|
||||
"response": {
|
||||
"fullResponse": true
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"id": "skill-email-002",
|
||||
"name": "Call skill-email",
|
||||
"type": "n8n-nodes-base.httpRequest",
|
||||
"typeVersion": 4.2,
|
||||
"position": [470, 220]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"respondWith": "json",
|
||||
"responseBody": "={{ $json.body || $json }}",
|
||||
"options": {}
|
||||
},
|
||||
"id": "skill-email-003",
|
||||
"name": "Return Response",
|
||||
"type": "n8n-nodes-base.respondToWebhook",
|
||||
"typeVersion": 1,
|
||||
"position": [710, 220]
|
||||
}
|
||||
],
|
||||
"connections": {
|
||||
"Webhook In": { "main": [[{ "node": "Call skill-email", "type": "main", "index": 0 }]] },
|
||||
"Call skill-email": { "main": [[{ "node": "Return Response", "type": "main", "index": 0 }]] }
|
||||
},
|
||||
"pinData": {},
|
||||
"meta": { "templateCredsSetupCompleted": true, "instanceId": "robeing-skills" }
|
||||
}
|
||||
57
workflow/02_skills/skill_news_briefing_request.json
Normal file
57
workflow/02_skills/skill_news_briefing_request.json
Normal file
@ -0,0 +1,57 @@
|
||||
{
|
||||
"name": "robeing-skill-news-briefing-request",
|
||||
"nodes": [
|
||||
{
|
||||
"parameters": {
|
||||
"httpMethod": "POST",
|
||||
"path": "skills/news/briefing",
|
||||
"responseMode": "responseNode",
|
||||
"options": {}
|
||||
},
|
||||
"id": "skill-news-001",
|
||||
"name": "Webhook In",
|
||||
"type": "n8n-nodes-base.webhook",
|
||||
"typeVersion": 1,
|
||||
"position": [220, 220]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"method": "POST",
|
||||
"url": "=http://192.168.219.52:8505/api/v1/briefing",
|
||||
"sendBody": true,
|
||||
"specifyBody": "json",
|
||||
"jsonBody": "={{ $json.body }}",
|
||||
"options": {
|
||||
"response": {
|
||||
"response": {
|
||||
"fullResponse": true
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"id": "skill-news-002",
|
||||
"name": "Call skill-news",
|
||||
"type": "n8n-nodes-base.httpRequest",
|
||||
"typeVersion": 4.2,
|
||||
"position": [470, 220]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"respondWith": "json",
|
||||
"responseBody": "={{ $json.body || $json }}",
|
||||
"options": {}
|
||||
},
|
||||
"id": "skill-news-003",
|
||||
"name": "Return Response",
|
||||
"type": "n8n-nodes-base.respondToWebhook",
|
||||
"typeVersion": 1,
|
||||
"position": [710, 220]
|
||||
}
|
||||
],
|
||||
"connections": {
|
||||
"Webhook In": { "main": [[{ "node": "Call skill-news", "type": "main", "index": 0 }]] },
|
||||
"Call skill-news": { "main": [[{ "node": "Return Response", "type": "main", "index": 0 }]] }
|
||||
},
|
||||
"pinData": {},
|
||||
"meta": { "templateCredsSetupCompleted": true, "instanceId": "robeing-skills" }
|
||||
}
|
||||
63
workflow/02_skills/skill_slack_send_message_bridge.json
Normal file
63
workflow/02_skills/skill_slack_send_message_bridge.json
Normal file
@ -0,0 +1,63 @@
|
||||
{
|
||||
"name": "robeing-skill-slack-send-message-bridge",
|
||||
"nodes": [
|
||||
{
|
||||
"parameters": {
|
||||
"httpMethod": "POST",
|
||||
"path": "skills/slack/send",
|
||||
"responseMode": "responseNode",
|
||||
"options": {}
|
||||
},
|
||||
"id": "skill-slack-001",
|
||||
"name": "Webhook In",
|
||||
"type": "n8n-nodes-base.webhook",
|
||||
"typeVersion": 1,
|
||||
"position": [220, 220]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"jsCode": "const body = $json.body || {};\nreturn {\n channel: body.channel,\n text: body.text,\n thread_ts: body.thread_ts || '',\n blocks: body.blocks || []\n};"
|
||||
},
|
||||
"id": "skill-slack-002",
|
||||
"name": "Normalize Payload",
|
||||
"type": "n8n-nodes-base.code",
|
||||
"typeVersion": 2,
|
||||
"position": [460, 220]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"resource": "message",
|
||||
"operation": "post",
|
||||
"channel": "={{ $json.channel }}",
|
||||
"text": "={{ $json.text }}",
|
||||
"otherOptions": {
|
||||
"threadTs": "={{ $json.thread_ts }}"
|
||||
}
|
||||
},
|
||||
"id": "skill-slack-003",
|
||||
"name": "Post to Slack",
|
||||
"type": "n8n-nodes-base.slack",
|
||||
"typeVersion": 2,
|
||||
"position": [710, 220]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"respondWith": "json",
|
||||
"responseBody": "={\"success\":true,\"channel\":\"{{$('Normalize Payload').item.json.channel}}\",\"thread_ts\":\"{{$('Normalize Payload').item.json.thread_ts}}\"}",
|
||||
"options": {}
|
||||
},
|
||||
"id": "skill-slack-004",
|
||||
"name": "Return Response",
|
||||
"type": "n8n-nodes-base.respondToWebhook",
|
||||
"typeVersion": 1,
|
||||
"position": [940, 220]
|
||||
}
|
||||
],
|
||||
"connections": {
|
||||
"Webhook In": { "main": [[{ "node": "Normalize Payload", "type": "main", "index": 0 }]] },
|
||||
"Normalize Payload": { "main": [[{ "node": "Post to Slack", "type": "main", "index": 0 }]] },
|
||||
"Post to Slack": { "main": [[{ "node": "Return Response", "type": "main", "index": 0 }]] }
|
||||
},
|
||||
"pinData": {},
|
||||
"meta": { "templateCredsSetupCompleted": true, "instanceId": "robeing-skills" }
|
||||
}
|
||||
70
workflow/03_rag/rag_search_grounding_request.json
Normal file
70
workflow/03_rag/rag_search_grounding_request.json
Normal file
@ -0,0 +1,70 @@
|
||||
{
|
||||
"name": "robeing-rag-search-grounding-request",
|
||||
"nodes": [
|
||||
{
|
||||
"parameters": {
|
||||
"httpMethod": "POST",
|
||||
"path": "rag/search",
|
||||
"responseMode": "responseNode",
|
||||
"options": {}
|
||||
},
|
||||
"id": "rag-search-001",
|
||||
"name": "Webhook In",
|
||||
"type": "n8n-nodes-base.webhook",
|
||||
"typeVersion": 1,
|
||||
"position": [200, 220]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"method": "POST",
|
||||
"url": "=http://192.168.219.52:8508/api/search",
|
||||
"sendHeaders": true,
|
||||
"headerParameters": {
|
||||
"parameters": [
|
||||
{
|
||||
"name": "Content-Type",
|
||||
"value": "application/json"
|
||||
},
|
||||
{
|
||||
"name": "X-User-Id",
|
||||
"value": "=system"
|
||||
}
|
||||
]
|
||||
},
|
||||
"sendBody": true,
|
||||
"specifyBody": "json",
|
||||
"jsonBody": "={{ $json.body }}",
|
||||
"options": {
|
||||
"response": {
|
||||
"response": {
|
||||
"fullResponse": true
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"id": "rag-search-002",
|
||||
"name": "Call skill-rag-file Search",
|
||||
"type": "n8n-nodes-base.httpRequest",
|
||||
"typeVersion": 4.2,
|
||||
"position": [460, 220]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"respondWith": "json",
|
||||
"responseBody": "={{ $json.body || $json }}",
|
||||
"options": {}
|
||||
},
|
||||
"id": "rag-search-003",
|
||||
"name": "Return Response",
|
||||
"type": "n8n-nodes-base.respondToWebhook",
|
||||
"typeVersion": 1,
|
||||
"position": [700, 220]
|
||||
}
|
||||
],
|
||||
"connections": {
|
||||
"Webhook In": { "main": [[{ "node": "Call skill-rag-file Search", "type": "main", "index": 0 }]] },
|
||||
"Call skill-rag-file Search": { "main": [[{ "node": "Return Response", "type": "main", "index": 0 }]] }
|
||||
},
|
||||
"pinData": {},
|
||||
"meta": { "templateCredsSetupCompleted": true, "instanceId": "robeing-rag" }
|
||||
}
|
||||
82
workflow/03_rag/rag_upload_indexing_pipeline.json
Normal file
82
workflow/03_rag/rag_upload_indexing_pipeline.json
Normal file
@ -0,0 +1,82 @@
|
||||
{
|
||||
"name": "robeing-rag-upload-indexing-pipeline",
|
||||
"nodes": [
|
||||
{
|
||||
"parameters": {
|
||||
"httpMethod": "POST",
|
||||
"path": "rag/upload-index",
|
||||
"responseMode": "responseNode",
|
||||
"options": {}
|
||||
},
|
||||
"id": "rag-up-001",
|
||||
"name": "Webhook In",
|
||||
"type": "n8n-nodes-base.webhook",
|
||||
"typeVersion": 1,
|
||||
"position": [200, 240]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"jsCode": "const body = $json.body || {};\nreturn {\n team_id: body.team_id,\n file_url: body.file_url || '',\n file_name: body.file_name || '',\n metadata: body.metadata || {},\n request_body: body\n};"
|
||||
},
|
||||
"id": "rag-up-002",
|
||||
"name": "Normalize Upload Payload",
|
||||
"type": "n8n-nodes-base.code",
|
||||
"typeVersion": 2,
|
||||
"position": [440, 240]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"method": "POST",
|
||||
"url": "=http://192.168.219.52:8508/api/upload",
|
||||
"sendHeaders": true,
|
||||
"headerParameters": {
|
||||
"parameters": [
|
||||
{
|
||||
"name": "Content-Type",
|
||||
"value": "application/json"
|
||||
},
|
||||
{
|
||||
"name": "X-User-Id",
|
||||
"value": "=system"
|
||||
}
|
||||
]
|
||||
},
|
||||
"sendBody": true,
|
||||
"specifyBody": "json",
|
||||
"jsonBody": "={{ $json.request_body }}",
|
||||
"options": {
|
||||
"response": {
|
||||
"response": {
|
||||
"fullResponse": true
|
||||
}
|
||||
},
|
||||
"timeout": 120000
|
||||
}
|
||||
},
|
||||
"id": "rag-up-003",
|
||||
"name": "Call skill-rag-file Upload",
|
||||
"type": "n8n-nodes-base.httpRequest",
|
||||
"typeVersion": 4.2,
|
||||
"position": [690, 240]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"respondWith": "json",
|
||||
"responseBody": "={{ $json.body || $json }}",
|
||||
"options": {}
|
||||
},
|
||||
"id": "rag-up-004",
|
||||
"name": "Return Response",
|
||||
"type": "n8n-nodes-base.respondToWebhook",
|
||||
"typeVersion": 1,
|
||||
"position": [930, 240]
|
||||
}
|
||||
],
|
||||
"connections": {
|
||||
"Webhook In": { "main": [[{ "node": "Normalize Upload Payload", "type": "main", "index": 0 }]] },
|
||||
"Normalize Upload Payload": { "main": [[{ "node": "Call skill-rag-file Upload", "type": "main", "index": 0 }]] },
|
||||
"Call skill-rag-file Upload": { "main": [[{ "node": "Return Response", "type": "main", "index": 0 }]] }
|
||||
},
|
||||
"pinData": {},
|
||||
"meta": { "templateCredsSetupCompleted": true, "instanceId": "robeing-rag" }
|
||||
}
|
||||
79
workflow/03_rag/skill_embedding_bridge.json
Normal file
79
workflow/03_rag/skill_embedding_bridge.json
Normal file
@ -0,0 +1,79 @@
|
||||
{
|
||||
"name": "robeing-skill-embedding-bridge",
|
||||
"nodes": [
|
||||
{
|
||||
"parameters": {
|
||||
"httpMethod": "POST",
|
||||
"path": "v1/multimodal-embed",
|
||||
"responseMode": "responseNode",
|
||||
"options": {}
|
||||
},
|
||||
"id": "embed-001",
|
||||
"name": "Webhook In",
|
||||
"type": "n8n-nodes-base.webhook",
|
||||
"typeVersion": 1,
|
||||
"position": [200, 240]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"jsCode": "const body = $json.body || {};\nreturn {\n api_key: body.api_key,\n gemini_payload: {\n model: 'models/gemini-embedding-2-preview',\n task_type: body.task_type || 'RETRIEVAL_DOCUMENT',\n content: body.content || { parts: [{ text: body.text || '' }] },\n output_dimensionality: body.dimension || 768\n }\n};"
|
||||
},
|
||||
"id": "embed-002",
|
||||
"name": "Build Gemini Payload",
|
||||
"type": "n8n-nodes-base.code",
|
||||
"typeVersion": 2,
|
||||
"position": [450, 240]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"method": "POST",
|
||||
"url": "=https://generativelanguage.googleapis.com/v1beta/models/gemini-embedding-2-preview:embedContent?key={{$json.api_key}}",
|
||||
"sendBody": true,
|
||||
"specifyBody": "json",
|
||||
"jsonBody": "={{ $json.gemini_payload }}",
|
||||
"options": {
|
||||
"response": {
|
||||
"response": {
|
||||
"fullResponse": true
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"id": "embed-003",
|
||||
"name": "Call Gemini Embedding API",
|
||||
"type": "n8n-nodes-base.httpRequest",
|
||||
"typeVersion": 4.2,
|
||||
"position": [700, 240]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"jsCode": "const body = $json.body || {};\nreturn {\n success: true,\n embedding: body.embedding?.values || [],\n model: 'gemini-embedding-2-preview'\n};"
|
||||
},
|
||||
"id": "embed-004",
|
||||
"name": "Normalize Response",
|
||||
"type": "n8n-nodes-base.code",
|
||||
"typeVersion": 2,
|
||||
"position": [940, 240]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"respondWith": "json",
|
||||
"responseBody": "={{ $json }}",
|
||||
"options": {}
|
||||
},
|
||||
"id": "embed-005",
|
||||
"name": "Return Response",
|
||||
"type": "n8n-nodes-base.respondToWebhook",
|
||||
"typeVersion": 1,
|
||||
"position": [1170, 240]
|
||||
}
|
||||
],
|
||||
"connections": {
|
||||
"Webhook In": { "main": [[{ "node": "Build Gemini Payload", "type": "main", "index": 0 }]] },
|
||||
"Build Gemini Payload": { "main": [[{ "node": "Call Gemini Embedding API", "type": "main", "index": 0 }]] },
|
||||
"Call Gemini Embedding API": { "main": [[{ "node": "Normalize Response", "type": "main", "index": 0 }]] },
|
||||
"Normalize Response": { "main": [[{ "node": "Return Response", "type": "main", "index": 0 }]] }
|
||||
},
|
||||
"pinData": {},
|
||||
"meta": { "templateCredsSetupCompleted": true, "instanceId": "robeing-rag" }
|
||||
}
|
||||
69
workflow/04_scheduler/scheduled_daily_briefing.json
Normal file
69
workflow/04_scheduler/scheduled_daily_briefing.json
Normal file
@ -0,0 +1,69 @@
|
||||
{
|
||||
"name": "robeing-scheduled-daily-briefing",
|
||||
"nodes": [
|
||||
{
|
||||
"parameters": {
|
||||
"rule": {
|
||||
"cronExpression": "0 9 * * 1-5"
|
||||
}
|
||||
},
|
||||
"id": "sched-brief-001",
|
||||
"name": "Schedule Trigger",
|
||||
"type": "n8n-nodes-base.scheduleTrigger",
|
||||
"typeVersion": 1,
|
||||
"position": [220, 220]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"method": "POST",
|
||||
"url": "=http://192.168.219.52:8505/api/v1/briefing",
|
||||
"sendBody": true,
|
||||
"specifyBody": "json",
|
||||
"jsonBody": "={\"mode\":\"daily_briefing\",\"company_id\":\"companyx\",\"topic\":\"business\",\"limit\":10}",
|
||||
"options": {
|
||||
"response": {
|
||||
"response": {
|
||||
"fullResponse": true
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"id": "sched-brief-002",
|
||||
"name": "Call skill-news",
|
||||
"type": "n8n-nodes-base.httpRequest",
|
||||
"typeVersion": 4.2,
|
||||
"position": [470, 220]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"jsCode": "const body = $json.body || {};\nreturn { channel: 'C_DAILY_BRIEFING', text: body.message || body.summary || '브리핑 결과가 비어 있습니다.' };"
|
||||
},
|
||||
"id": "sched-brief-003",
|
||||
"name": "Build Slack Message",
|
||||
"type": "n8n-nodes-base.code",
|
||||
"typeVersion": 2,
|
||||
"position": [700, 220]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"resource": "message",
|
||||
"operation": "post",
|
||||
"channel": "={{ $json.channel }}",
|
||||
"text": "={{ $json.text }}",
|
||||
"otherOptions": {}
|
||||
},
|
||||
"id": "sched-brief-004",
|
||||
"name": "Post to Slack",
|
||||
"type": "n8n-nodes-base.slack",
|
||||
"typeVersion": 2,
|
||||
"position": [940, 220]
|
||||
}
|
||||
],
|
||||
"connections": {
|
||||
"Schedule Trigger": { "main": [[{ "node": "Call skill-news", "type": "main", "index": 0 }]] },
|
||||
"Call skill-news": { "main": [[{ "node": "Build Slack Message", "type": "main", "index": 0 }]] },
|
||||
"Build Slack Message": { "main": [[{ "node": "Post to Slack", "type": "main", "index": 0 }]] }
|
||||
},
|
||||
"pinData": {},
|
||||
"meta": { "templateCredsSetupCompleted": true, "instanceId": "robeing-scheduler" }
|
||||
}
|
||||
79
workflow/04_scheduler/scheduled_healthcheck_alert.json
Normal file
79
workflow/04_scheduler/scheduled_healthcheck_alert.json
Normal file
@ -0,0 +1,79 @@
|
||||
{
|
||||
"name": "robeing-scheduled-healthcheck-alert",
|
||||
"nodes": [
|
||||
{
|
||||
"parameters": {
|
||||
"rule": {
|
||||
"cronExpression": "*/10 * * * *"
|
||||
}
|
||||
},
|
||||
"id": "sched-health-001",
|
||||
"name": "Schedule Trigger",
|
||||
"type": "n8n-nodes-base.scheduleTrigger",
|
||||
"typeVersion": 1,
|
||||
"position": [220, 220]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"method": "GET",
|
||||
"url": "=http://192.168.219.52:8001/health",
|
||||
"options": {
|
||||
"response": {
|
||||
"response": {
|
||||
"fullResponse": true
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"id": "sched-health-002",
|
||||
"name": "Check rb8001 Health",
|
||||
"type": "n8n-nodes-base.httpRequest",
|
||||
"typeVersion": 4.2,
|
||||
"position": [470, 220]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"conditions": {
|
||||
"number": [
|
||||
{
|
||||
"value1": "={{ $json.statusCode }}",
|
||||
"operation": "notEqual",
|
||||
"value2": 200
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"id": "sched-health-003",
|
||||
"name": "Health Failed?",
|
||||
"type": "n8n-nodes-base.if",
|
||||
"typeVersion": 2,
|
||||
"position": [700, 220]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"resource": "message",
|
||||
"operation": "post",
|
||||
"channel": "=C_ALERTS",
|
||||
"text": "=rb8001 health check failed. status={{$json.statusCode}}",
|
||||
"otherOptions": {}
|
||||
},
|
||||
"id": "sched-health-004",
|
||||
"name": "Send Alert",
|
||||
"type": "n8n-nodes-base.slack",
|
||||
"typeVersion": 2,
|
||||
"position": [940, 160]
|
||||
}
|
||||
],
|
||||
"connections": {
|
||||
"Schedule Trigger": { "main": [[{ "node": "Check rb8001 Health", "type": "main", "index": 0 }]] },
|
||||
"Check rb8001 Health": { "main": [[{ "node": "Health Failed?", "type": "main", "index": 0 }]] },
|
||||
"Health Failed?": {
|
||||
"main": [
|
||||
[{ "node": "Send Alert", "type": "main", "index": 0 }],
|
||||
[]
|
||||
]
|
||||
}
|
||||
},
|
||||
"pinData": {},
|
||||
"meta": { "templateCredsSetupCompleted": true, "instanceId": "robeing-scheduler" }
|
||||
}
|
||||
83
workflow/04_scheduler/scheduled_rag_reindex_retry.json
Normal file
83
workflow/04_scheduler/scheduled_rag_reindex_retry.json
Normal file
@ -0,0 +1,83 @@
|
||||
{
|
||||
"name": "robeing-scheduled-rag-reindex-retry",
|
||||
"nodes": [
|
||||
{
|
||||
"parameters": {
|
||||
"rule": {
|
||||
"cronExpression": "0 */6 * * *"
|
||||
}
|
||||
},
|
||||
"id": "sched-rag-001",
|
||||
"name": "Schedule Trigger",
|
||||
"type": "n8n-nodes-base.scheduleTrigger",
|
||||
"typeVersion": 1,
|
||||
"position": [220, 220]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"operation": "executeQuery",
|
||||
"query": "SELECT id, payload_json FROM rag_retry_queue WHERE status = 'pending' ORDER BY created_at ASC LIMIT 20;",
|
||||
"options": {}
|
||||
},
|
||||
"id": "sched-rag-002",
|
||||
"name": "Load Retry Queue",
|
||||
"type": "n8n-nodes-base.postgres",
|
||||
"typeVersion": 2.2,
|
||||
"position": [470, 220]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"method": "POST",
|
||||
"url": "=http://192.168.219.52:8508/api/reindex",
|
||||
"sendHeaders": true,
|
||||
"headerParameters": {
|
||||
"parameters": [
|
||||
{
|
||||
"name": "Content-Type",
|
||||
"value": "application/json"
|
||||
},
|
||||
{
|
||||
"name": "X-User-Id",
|
||||
"value": "=system"
|
||||
}
|
||||
]
|
||||
},
|
||||
"sendBody": true,
|
||||
"specifyBody": "json",
|
||||
"jsonBody": "={{ $json.payload_json }}",
|
||||
"options": {
|
||||
"response": {
|
||||
"response": {
|
||||
"fullResponse": true
|
||||
}
|
||||
},
|
||||
"timeout": 120000
|
||||
}
|
||||
},
|
||||
"id": "sched-rag-003",
|
||||
"name": "Call Reindex API",
|
||||
"type": "n8n-nodes-base.httpRequest",
|
||||
"typeVersion": 4.2,
|
||||
"position": [720, 220]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"operation": "executeQuery",
|
||||
"query": "UPDATE rag_retry_queue SET status = 'done', processed_at = NOW() WHERE id = '{{ $('Load Retry Queue').item.json.id }}';",
|
||||
"options": {}
|
||||
},
|
||||
"id": "sched-rag-004",
|
||||
"name": "Mark Done",
|
||||
"type": "n8n-nodes-base.postgres",
|
||||
"typeVersion": 2.2,
|
||||
"position": [960, 220]
|
||||
}
|
||||
],
|
||||
"connections": {
|
||||
"Schedule Trigger": { "main": [[{ "node": "Load Retry Queue", "type": "main", "index": 0 }]] },
|
||||
"Load Retry Queue": { "main": [[{ "node": "Call Reindex API", "type": "main", "index": 0 }]] },
|
||||
"Call Reindex API": { "main": [[{ "node": "Mark Done", "type": "main", "index": 0 }]] }
|
||||
},
|
||||
"pinData": {},
|
||||
"meta": { "templateCredsSetupCompleted": true, "instanceId": "robeing-scheduler" }
|
||||
}
|
||||
16
workflow/README.md
Normal file
16
workflow/README.md
Normal file
@ -0,0 +1,16 @@
|
||||
# Robeing n8n Workflows
|
||||
|
||||
로빙의 반복 실행 절차를 n8n import용 JSON으로 분류해 둔 폴더입니다.
|
||||
|
||||
## 폴더
|
||||
|
||||
- `01_conversation/`: Slack 대화 진입, 스레드 요약, 액션 추출
|
||||
- `02_skills/`: `skill-*` 서비스 호출 브리지
|
||||
- `03_rag/`: 업로드, 임베딩, 검색, 인덱싱
|
||||
- `04_scheduler/`: APScheduler 성격의 정기 실행 대체/보조 흐름
|
||||
|
||||
## 사용 원칙
|
||||
|
||||
- 이 JSON은 n8n import 템플릿입니다.
|
||||
- 실제 운영 전 credential, URL, channel, API key, DB 연결은 환경에 맞게 교체해야 합니다.
|
||||
- 로빙의 판단 루프 자체를 대체하지 않고, 반복 실행 절차를 분리하는 용도로 사용합니다.
|
||||
@ -1,437 +0,0 @@
|
||||
{
|
||||
"name": "robeing-slack-basic-dialogue",
|
||||
"nodes": [
|
||||
{
|
||||
"parameters": {
|
||||
"channelId": {
|
||||
"__rl": true,
|
||||
"mode": "list",
|
||||
"value": ""
|
||||
},
|
||||
"options": {}
|
||||
},
|
||||
"id": "a1c3d2f0-b5e0-4f40-85fd-79f147ec0001",
|
||||
"name": "Slack Trigger",
|
||||
"type": "n8n-nodes-base.slackTrigger",
|
||||
"typeVersion": 1,
|
||||
"position": [
|
||||
240,
|
||||
260
|
||||
]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"jsCode": "const event = $json.event || {};\nconst headers = $json.headers || {};\nconst text = event.text || '';\nconst question = text.replace(/<@[^>]+>/g, '').trim();\nconst isBotMessage = Boolean(event.bot_id) || event.subtype === 'bot_message';\nconst isEditedMessage = event.subtype === 'message_changed';\nconst isDeletedMessage = event.subtype === 'message_deleted';\nconst isRetry = headers['x-slack-retry-num'] !== undefined || headers['X-Slack-Retry-Num'] !== undefined;\nconst shouldProcess = Boolean(event.channel) && Boolean(event.user) && Boolean(question) && !isBotMessage && !isEditedMessage && !isDeletedMessage && !isRetry;\n\nreturn {\n raw_event: event,\n headers,\n should_process: shouldProcess,\n skip_reason: shouldProcess ? null : {\n missing_channel: !event.channel,\n missing_user: !event.user,\n empty_question: !question,\n bot_message: isBotMessage,\n edited_message: isEditedMessage,\n deleted_message: isDeletedMessage,\n retry_event: isRetry\n },\n team_id: event.team || event.team_id || '',\n channel: event.channel || '',\n user_id: event.user || '',\n event_ts: event.ts || '',\n thread_ts: event.thread_ts || event.ts || '',\n original_text: text,\n question,\n mention_removed_text: question,\n robeing_id: 'rb8001',\n source: 'slack',\n response_mode: event.thread_ts ? 'reply_in_existing_thread' : 'reply_in_new_thread'\n};"
|
||||
},
|
||||
"id": "a1c3d2f0-b5e0-4f40-85fd-79f147ec0002",
|
||||
"name": "Normalize Slack Event",
|
||||
"type": "n8n-nodes-base.code",
|
||||
"typeVersion": 2,
|
||||
"position": [
|
||||
500,
|
||||
260
|
||||
]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"conditions": {
|
||||
"boolean": [
|
||||
{
|
||||
"value1": "={{ $json.should_process }}",
|
||||
"value2": true
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"id": "a1c3d2f0-b5e0-4f40-85fd-79f147ec0003",
|
||||
"name": "Should Process?",
|
||||
"type": "n8n-nodes-base.if",
|
||||
"typeVersion": 2,
|
||||
"position": [
|
||||
760,
|
||||
260
|
||||
]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"method": "GET",
|
||||
"url": "=http://192.168.219.45:9000/api/slack/mapping/{{$json.user_id}}",
|
||||
"options": {
|
||||
"response": {
|
||||
"response": {
|
||||
"fullResponse": true
|
||||
}
|
||||
},
|
||||
"timeout": 10000
|
||||
}
|
||||
},
|
||||
"id": "a1c3d2f0-b5e0-4f40-85fd-79f147ec0004",
|
||||
"name": "Get Slack User Mapping",
|
||||
"type": "n8n-nodes-base.httpRequest",
|
||||
"typeVersion": 4.2,
|
||||
"position": [
|
||||
1020,
|
||||
180
|
||||
]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"jsCode": "const mappingResponse = $json;\nconst eventData = $('Normalize Slack Event').item.json;\nconst body = mappingResponse.body || {};\nconst userUuid = body.user_id || body.id || body.uuid || '';\nconst username = body.username || `slack_${eventData.user_id}`;\nconst ok = mappingResponse.statusCode >= 200 && mappingResponse.statusCode < 300 && Boolean(userUuid);\n\nreturn {\n ...eventData,\n mapping_status_code: mappingResponse.statusCode,\n mapping_ok: ok,\n mapped_user_uuid: userUuid,\n mapped_username: username,\n mapped_user_payload: body\n};"
|
||||
},
|
||||
"id": "a1c3d2f0-b5e0-4f40-85fd-79f147ec0005",
|
||||
"name": "Parse Mapping Response",
|
||||
"type": "n8n-nodes-base.code",
|
||||
"typeVersion": 2,
|
||||
"position": [
|
||||
1260,
|
||||
180
|
||||
]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"conditions": {
|
||||
"boolean": [
|
||||
{
|
||||
"value1": "={{ $json.mapping_ok }}",
|
||||
"value2": true
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"id": "a1c3d2f0-b5e0-4f40-85fd-79f147ec0006",
|
||||
"name": "Mapping Found?",
|
||||
"type": "n8n-nodes-base.if",
|
||||
"typeVersion": 2,
|
||||
"position": [
|
||||
1500,
|
||||
180
|
||||
]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"jsCode": "return {\n channel: $json.channel,\n thread_ts: $json.thread_ts,\n text: 'Slack 사용자 매핑을 찾지 못했습니다. 관리자에게 문의해주세요.',\n response_kind: 'mapping_error',\n metadata: {\n user_id: $json.user_id,\n team_id: $json.team_id,\n mapping_status_code: $json.mapping_status_code\n }\n};"
|
||||
},
|
||||
"id": "a1c3d2f0-b5e0-4f40-85fd-79f147ec0007",
|
||||
"name": "Build Mapping Error Reply",
|
||||
"type": "n8n-nodes-base.code",
|
||||
"typeVersion": 2,
|
||||
"position": [
|
||||
1740,
|
||||
340
|
||||
]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"jsCode": "return {\n channel: $json.channel,\n user_uuid: $json.mapped_user_uuid,\n thread_ts: $json.thread_ts,\n message: $json.question,\n robeing_id: $json.robeing_id,\n request_body: {\n message: $json.question,\n source: 'slack',\n context: {\n slack: {\n team_id: $json.team_id,\n channel: $json.channel,\n user_id: $json.user_id,\n event_ts: $json.event_ts,\n thread_ts: $json.thread_ts,\n response_mode: $json.response_mode\n },\n robeing: {\n robeing_id: $json.robeing_id,\n mapped_username: $json.mapped_username\n }\n }\n }\n};"
|
||||
},
|
||||
"id": "a1c3d2f0-b5e0-4f40-85fd-79f147ec0008",
|
||||
"name": "Build Robeing Request",
|
||||
"type": "n8n-nodes-base.code",
|
||||
"typeVersion": 2,
|
||||
"position": [
|
||||
1740,
|
||||
100
|
||||
]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"method": "POST",
|
||||
"url": "=http://192.168.219.45:8100/api/chat",
|
||||
"sendHeaders": true,
|
||||
"headerParameters": {
|
||||
"parameters": [
|
||||
{
|
||||
"name": "Content-Type",
|
||||
"value": "application/json"
|
||||
},
|
||||
{
|
||||
"name": "X-User-Id",
|
||||
"value": "={{ $json.user_uuid }}"
|
||||
}
|
||||
]
|
||||
},
|
||||
"sendBody": true,
|
||||
"specifyBody": "json",
|
||||
"jsonBody": "={{ $json.request_body }}",
|
||||
"options": {
|
||||
"response": {
|
||||
"response": {
|
||||
"fullResponse": true
|
||||
}
|
||||
},
|
||||
"timeout": 60000
|
||||
}
|
||||
},
|
||||
"id": "a1c3d2f0-b5e0-4f40-85fd-79f147ec0009",
|
||||
"name": "Call Robeing Gateway",
|
||||
"type": "n8n-nodes-base.httpRequest",
|
||||
"typeVersion": 4.2,
|
||||
"position": [
|
||||
1990,
|
||||
100
|
||||
]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"jsCode": "const gatewayResponse = $json;\nconst request = $('Build Robeing Request').item.json;\nconst body = gatewayResponse.body || {};\nconst replyText = body.reply || body.response || body.message || body.text || body.answer || body.content || '';\nconst ok = gatewayResponse.statusCode >= 200 && gatewayResponse.statusCode < 300 && Boolean(replyText);\n\nreturn {\n channel: request.channel,\n thread_ts: request.thread_ts,\n success: ok,\n status_code: gatewayResponse.statusCode,\n text: ok ? replyText : '지금은 응답을 생성하지 못했습니다. 잠시 후 다시 시도해주세요.',\n raw_gateway_body: body,\n metadata: {\n user_uuid: request.user_uuid,\n robeing_id: request.robeing_id,\n source: 'slack',\n status_code: gatewayResponse.statusCode\n }\n};"
|
||||
},
|
||||
"id": "a1c3d2f0-b5e0-4f40-85fd-79f147ec0010",
|
||||
"name": "Parse Robeing Reply",
|
||||
"type": "n8n-nodes-base.code",
|
||||
"typeVersion": 2,
|
||||
"position": [
|
||||
2240,
|
||||
100
|
||||
]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"conditions": {
|
||||
"boolean": [
|
||||
{
|
||||
"value1": "={{ $json.success }}",
|
||||
"value2": true
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"id": "a1c3d2f0-b5e0-4f40-85fd-79f147ec0011",
|
||||
"name": "Reply Ready?",
|
||||
"type": "n8n-nodes-base.if",
|
||||
"typeVersion": 2,
|
||||
"position": [
|
||||
2480,
|
||||
100
|
||||
]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"jsCode": "return {\n channel: $json.channel,\n thread_ts: $json.thread_ts,\n text: $json.text,\n response_kind: 'agent_reply',\n metadata: $json.metadata\n};"
|
||||
},
|
||||
"id": "a1c3d2f0-b5e0-4f40-85fd-79f147ec0012",
|
||||
"name": "Build Slack Reply",
|
||||
"type": "n8n-nodes-base.code",
|
||||
"typeVersion": 2,
|
||||
"position": [
|
||||
2720,
|
||||
20
|
||||
]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"jsCode": "return {\n channel: $json.channel,\n thread_ts: $json.thread_ts,\n text: '로빙 응답 생성 중 오류가 발생했습니다. 잠시 후 다시 시도해주세요.',\n response_kind: 'agent_error',\n metadata: $json.metadata\n};"
|
||||
},
|
||||
"id": "a1c3d2f0-b5e0-4f40-85fd-79f147ec0013",
|
||||
"name": "Build Agent Error Reply",
|
||||
"type": "n8n-nodes-base.code",
|
||||
"typeVersion": 2,
|
||||
"position": [
|
||||
2720,
|
||||
180
|
||||
]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"resource": "message",
|
||||
"operation": "post",
|
||||
"channel": "={{ $json.channel }}",
|
||||
"text": "={{ $json.text }}",
|
||||
"otherOptions": {
|
||||
"threadTs": "={{ $json.thread_ts }}"
|
||||
}
|
||||
},
|
||||
"id": "a1c3d2f0-b5e0-4f40-85fd-79f147ec0014",
|
||||
"name": "Reply to Slack",
|
||||
"type": "n8n-nodes-base.slack",
|
||||
"typeVersion": 2,
|
||||
"position": [
|
||||
2980,
|
||||
100
|
||||
]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"jsCode": "return {\n skipped: true,\n reason: $json.skip_reason || 'ignored_event',\n original_event_ts: $json.event_ts,\n channel: $json.channel || null\n};"
|
||||
},
|
||||
"id": "a1c3d2f0-b5e0-4f40-85fd-79f147ec0015",
|
||||
"name": "Skip Event",
|
||||
"type": "n8n-nodes-base.code",
|
||||
"typeVersion": 2,
|
||||
"position": [
|
||||
1030,
|
||||
380
|
||||
]
|
||||
}
|
||||
],
|
||||
"connections": {
|
||||
"Slack Trigger": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Normalize Slack Event",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Normalize Slack Event": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Should Process?",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Should Process?": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Get Slack User Mapping",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
],
|
||||
[
|
||||
{
|
||||
"node": "Skip Event",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Get Slack User Mapping": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Parse Mapping Response",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Parse Mapping Response": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Mapping Found?",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Mapping Found?": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Build Robeing Request",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
],
|
||||
[
|
||||
{
|
||||
"node": "Build Mapping Error Reply",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Build Mapping Error Reply": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Reply to Slack",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Build Robeing Request": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Call Robeing Gateway",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Call Robeing Gateway": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Parse Robeing Reply",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Parse Robeing Reply": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Reply Ready?",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Reply Ready?": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Build Slack Reply",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
],
|
||||
[
|
||||
{
|
||||
"node": "Build Agent Error Reply",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Build Slack Reply": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Reply to Slack",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Build Agent Error Reply": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Reply to Slack",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
}
|
||||
},
|
||||
"pinData": {},
|
||||
"meta": {
|
||||
"templateCredsSetupCompleted": true,
|
||||
"instanceId": "robeing-docs-workflow"
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user