From 5457a8de39b81b7f69c184862e8bf90b7a92c73e Mon Sep 17 00:00:00 2001 From: ph34444 Date: Mon, 16 Mar 2026 17:16:02 +0100 Subject: [PATCH] =?UTF-8?q?feat:=20workflow=20B=20=E2=80=93=20approval=20g?= =?UTF-8?q?ate=20and=20execution?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../workflow-b-approval-execution.json | 684 ++++++++++++++++++ 1 file changed, 684 insertions(+) create mode 100644 n8n-workflows/workflow-b-approval-execution.json diff --git a/n8n-workflows/workflow-b-approval-execution.json b/n8n-workflows/workflow-b-approval-execution.json new file mode 100644 index 0000000..69e84c6 --- /dev/null +++ b/n8n-workflows/workflow-b-approval-execution.json @@ -0,0 +1,684 @@ +{ + "name": "Workflow B – Approval Gate & Execution", + "description": "Approval and execution workflow for AI-suggested solutions. Polls for approved conversations, routes to Baramundi or automatic reply, executes solution, and triggers KB update.", + "nodes": [ + { + "id": "uuid-trigger-b-1", + "name": "Cron Trigger", + "type": "n8n-nodes-base.cron", + "typeVersion": 1, + "position": [ + 250, + 200 + ], + "parameters": { + "cronExpression": "*/2 * * * *", + "timezone": "Europe/Berlin" + } + }, + { + "id": "uuid-freescout-approved-1", + "name": "Freescout Get Approved Conversations", + "type": "n8n-nodes-base.httpRequest", + "typeVersion": 4, + "position": [ + 450, + 200 + ], + "parameters": { + "authentication": "predefinedCredentialType", + "url": "https://ekshelpdesk.fft-it.de/api/v1/mailboxes/1/conversations", + "method": "GET", + "options": {}, + "sendQuery": true, + "queryParameters": { + "parameters": [ + { + "name": "status", + "value": "active" + }, + { + "name": "limit", + "value": "20" + } + ] + } + }, + "credentials": { + "httpBasicAuth": "Freescout API" + } + }, + { + "id": "uuid-filter-approved-1", + "name": "Filter Approved Conversations", + "type": "n8n-nodes-base.httpRequest", + "typeVersion": 4, + "position": [ + 650, + 200 + ], + "parameters": { + "authentication": "none", + "method": "GET", + "url": "={{ $json.body._embedded.conversations.filter(c => c.custom_fields?.AI_SUGGESTION_STATUS === 'APPROVED' && c.custom_fields?.PROCESSED_APPROVAL !== true).map(c => c.id) }}", + "options": {} + } + }, + { + "id": "uuid-loop-approved-1", + "name": "Loop Through Approved Conversations", + "type": "n8n-nodes-base.loop", + "typeVersion": 1, + "position": [ + 850, + 200 + ], + "parameters": { + "iterations": "={{ $json.body._embedded.conversations.filter(c => c.custom_fields?.AI_SUGGESTION_STATUS === 'APPROVED' && c.custom_fields?.PROCESSED_APPROVAL !== true).length }}", + "dataPropertyName": "filteredConversations" + } + }, + { + "id": "uuid-extract-approved-1", + "name": "Extract Approved Conversation", + "type": "n8n-nodes-base.set", + "typeVersion": 3, + "position": [ + 1050, + 200 + ], + "parameters": { + "options": {}, + "assignments": { + "assignments": [ + { + "name": "conversation_id", + "value": "={{ $json.id }}", + "type": "string" + }, + { + "name": "ticket_id", + "value": "={{ $json.id }}", + "type": "string" + }, + { + "name": "subject", + "value": "={{ $json.subject }}", + "type": "string" + }, + { + "name": "customer_name", + "value": "={{ $json.customer_name }}", + "type": "string" + }, + { + "name": "customer_email", + "value": "={{ $json.customer_email || $json.customer.emails[0] }}", + "type": "string" + }, + { + "name": "ai_suggestion", + "value": "={{ $json.custom_fields?.AI_SUGGESTION }}", + "type": "string" + }, + { + "name": "ai_solution_type", + "value": "={{ $json.custom_fields?.AI_SOLUTION_TYPE }}", + "type": "string" + }, + { + "name": "baramundi_job", + "value": "={{ $json.custom_fields?.BARAMUNDI_JOB_DETAILS }}", + "type": "object" + }, + { + "name": "automatic_reply", + "value": "={{ $json.custom_fields?.AUTOMATIC_REPLY_TEXT }}", + "type": "string" + }, + { + "name": "approved_by", + "value": "={{ $json.custom_fields?.APPROVED_BY }}", + "type": "string" + }, + { + "name": "approved_at", + "value": "={{ $json.custom_fields?.APPROVED_AT }}", + "type": "string" + } + ] + } + } + }, + { + "id": "uuid-parse-ai-suggestion-1", + "name": "Parse AI Suggestion JSON", + "type": "n8n-nodes-base.set", + "typeVersion": 3, + "position": [ + 1250, + 200 + ], + "parameters": { + "options": {}, + "assignments": { + "assignments": [ + { + "name": "ai_suggestion_parsed", + "value": "={{ typeof $json.ai_suggestion === 'string' ? JSON.parse($json.ai_suggestion) : $json.ai_suggestion }}", + "type": "object" + }, + { + "name": "lösung_typ", + "value": "={{ $json.ai_solution_type || $json.ai_suggestion_parsed?.lösung_typ }}", + "type": "string" + } + ] + } + } + }, + { + "id": "uuid-conditional-branch-1", + "name": "Branch by Solution Type", + "type": "n8n-nodes-base.if", + "typeVersion": 2, + "position": [ + 1450, + 200 + ], + "parameters": { + "conditions": { + "options": { + "caseSensitive": true, + "extractValue": false + }, + "combinator": "or", + "conditions": [ + { + "id": "condition_baramundi", + "leftValue": "={{ $json.lösung_typ }}", + "rightValue": "BARAMUNDI_JOB", + "operator": { + "name": "filter.operator.equals", + "value": "==" + } + } + ] + } + } + }, + { + "id": "uuid-baramundi-api-1", + "name": "Baramundi API POST Job", + "type": "n8n-nodes-base.httpRequest", + "typeVersion": 4, + "position": [ + 1250, + 450 + ], + "parameters": { + "authentication": "predefinedCredentialType", + "url": "=https://baramundi-ms.fft-it.de/api/jobs", + "method": "POST", + "headers": { + "Content-Type": "application/json" + }, + "sendBody": true, + "specifyBody": "json", + "jsonBody": "={{ {\n \"job_name\": $json.ai_suggestion_parsed?.baramundi_job?.job_name || $json.baramundi_job?.job_name,\n \"job_type\": $json.ai_suggestion_parsed?.baramundi_job?.job_type || $json.baramundi_job?.job_type,\n \"target_devices\": $json.ai_suggestion_parsed?.baramundi_job?.target_devices || $json.baramundi_job?.target_devices,\n \"parameters\": $json.ai_suggestion_parsed?.baramundi_job?.parameters || $json.baramundi_job?.parameters,\n \"description\": \"Auto-triggered from Freescout ticket \" + $json.ticket_id,\n \"priority\": $json.ai_suggestion_parsed?.baramundi_job?.priority || 5\n} }}" + }, + "credentials": { + "httpBasicAuth": "Baramundi API" + } + }, + { + "id": "uuid-baramundi-success-1", + "name": "Baramundi Job Success", + "type": "n8n-nodes-base.set", + "typeVersion": 3, + "position": [ + 1450, + 450 + ], + "parameters": { + "options": {}, + "assignments": { + "assignments": [ + { + "name": "job_id", + "value": "={{ $json.id }}", + "type": "string" + }, + { + "name": "job_status", + "value": "executed", + "type": "string" + }, + { + "name": "execution_type", + "value": "BARAMUNDI_JOB", + "type": "string" + } + ] + } + } + }, + { + "id": "uuid-reply-api-1", + "name": "Freescout Reply API", + "type": "n8n-nodes-base.httpRequest", + "typeVersion": 4, + "position": [ + 1250, + 700 + ], + "parameters": { + "authentication": "predefinedCredentialType", + "url": "=https://ekshelpdesk.fft-it.de/api/v1/conversations/{{ $json.ticket_id }}/threads", + "method": "POST", + "headers": { + "Content-Type": "application/json" + }, + "sendBody": true, + "specifyBody": "json", + "jsonBody": "={{ {\n \"body\": $json.automatic_reply || $json.ai_suggestion_parsed?.antwort_text,\n \"type\": \"note\",\n \"from_customer\": false\n} }}" + }, + "credentials": { + "httpBasicAuth": "Freescout API" + } + }, + { + "id": "uuid-reply-success-1", + "name": "Reply Sent Success", + "type": "n8n-nodes-base.set", + "typeVersion": 3, + "position": [ + 1450, + 700 + ], + "parameters": { + "options": {}, + "assignments": { + "assignments": [ + { + "name": "reply_status", + "value": "sent", + "type": "string" + }, + { + "name": "execution_type", + "value": "AUTOMATISCHE_ANTWORT", + "type": "string" + } + ] + } + } + }, + { + "id": "uuid-freescout-update-executed-1", + "name": "Freescout Mark as EXECUTED", + "type": "n8n-nodes-base.httpRequest", + "typeVersion": 4, + "position": [ + 1650, + 200 + ], + "parameters": { + "authentication": "predefinedCredentialType", + "url": "=https://ekshelpdesk.fft-it.de/api/v1/conversations/{{ $json.ticket_id }}", + "method": "PUT", + "headers": { + "Content-Type": "application/json" + }, + "sendBody": true, + "specifyBody": "json", + "jsonBody": "={{ {\n \"custom_fields\": {\n \"AI_SUGGESTION_STATUS\": \"EXECUTED\",\n \"PROCESSED_APPROVAL\": true,\n \"EXECUTED_AT\": new Date().toISOString(),\n \"EXECUTED_BY\": \"workflow-b\",\n \"EXECUTION_TYPE\": $json.execution_type,\n \"EXECUTION_JOB_ID\": $json.job_id || null\n }\n} }}" + }, + "credentials": { + "httpBasicAuth": "Freescout API" + } + }, + { + "id": "uuid-webhook-c-1", + "name": "Trigger Workflow C Webhook", + "type": "n8n-nodes-base.httpRequest", + "typeVersion": 4, + "position": [ + 1850, + 200 + ], + "parameters": { + "authentication": "none", + "url": "={{ $env.WEBHOOK_WORKFLOW_C || 'http://n8n:5678/webhook/workflow-c' }}", + "method": "POST", + "headers": { + "Content-Type": "application/json" + }, + "sendBody": true, + "specifyBody": "json", + "jsonBody": "={{ {\n \"ticket_id\": $json.ticket_id,\n \"conversation_id\": $json.conversation_id,\n \"subject\": $json.subject,\n \"solution_type\": $json.lösung_typ,\n \"execution_type\": $json.execution_type,\n \"ai_suggestion\": $json.ai_suggestion_parsed,\n \"timestamp\": new Date().toISOString()\n} }}" + } + }, + { + "id": "uuid-log-execution-1", + "name": "Log Execution Result", + "type": "n8n-nodes-base.set", + "typeVersion": 3, + "position": [ + 2050, + 200 + ], + "parameters": { + "options": {}, + "assignments": { + "assignments": [ + { + "name": "log_entry", + "value": "={{ {\n \"timestamp\": new Date().toISOString(),\n \"ticket_id\": $json.ticket_id,\n \"status\": \"SUCCESS\",\n \"execution_type\": $json.execution_type,\n \"workflow\": \"workflow-b\"\n} }}", + "type": "object" + } + ] + } + } + }, + { + "id": "uuid-error-handler-1", + "name": "Error Handler", + "type": "n8n-nodes-base.set", + "typeVersion": 3, + "position": [ + 1650, + 500 + ], + "parameters": { + "options": {}, + "assignments": { + "assignments": [ + { + "name": "error_log", + "value": "={{ {\n \"timestamp\": new Date().toISOString(),\n \"ticket_id\": $json.ticket_id || 'unknown',\n \"status\": \"ERROR\",\n \"error_message\": $error.message,\n \"workflow\": \"workflow-b\"\n} }}", + "type": "object" + }, + { + "name": "processed", + "value": false, + "type": "boolean" + } + ] + } + } + }, + { + "id": "uuid-freescout-mark-rejected-1", + "name": "Freescout Mark as REJECTED", + "type": "n8n-nodes-base.httpRequest", + "typeVersion": 4, + "position": [ + 1650, + 800 + ], + "parameters": { + "authentication": "predefinedCredentialType", + "url": "=https://ekshelpdesk.fft-it.de/api/v1/conversations/{{ $json.ticket_id }}", + "method": "PUT", + "headers": { + "Content-Type": "application/json" + }, + "sendBody": true, + "specifyBody": "json", + "jsonBody": "={{ {\n \"custom_fields\": {\n \"AI_SUGGESTION_STATUS\": \"REJECTED\",\n \"PROCESSED_APPROVAL\": true,\n \"REJECTED_AT\": new Date().toISOString(),\n \"REJECTION_REASON\": \"Unknown solution type: \" + $json.lösung_typ\n }\n} }}" + }, + "credentials": { + "httpBasicAuth": "Freescout API" + } + }, + { + "id": "uuid-else-branch-1", + "name": "Handle Unknown Solution Type", + "type": "n8n-nodes-base.set", + "typeVersion": 3, + "position": [ + 1450, + 800 + ], + "parameters": { + "options": {}, + "assignments": { + "assignments": [ + { + "name": "solution_type", + "value": "={{ $json.lösung_typ }}", + "type": "string" + }, + { + "name": "status", + "value": "REJECTED", + "type": "string" + } + ] + } + } + } + ], + "connections": { + "Cron Trigger": { + "main": [ + [ + { + "node": "Freescout Get Approved Conversations", + "index": 0 + } + ] + ] + }, + "Freescout Get Approved Conversations": { + "main": [ + [ + { + "node": "Filter Approved Conversations", + "index": 0 + } + ] + ] + }, + "Filter Approved Conversations": { + "main": [ + [ + { + "node": "Loop Through Approved Conversations", + "index": 0 + } + ] + ] + }, + "Loop Through Approved Conversations": { + "main": [ + [ + { + "node": "Extract Approved Conversation", + "index": 0 + } + ] + ] + }, + "Extract Approved Conversation": { + "main": [ + [ + { + "node": "Parse AI Suggestion JSON", + "index": 0 + } + ] + ] + }, + "Parse AI Suggestion JSON": { + "main": [ + [ + { + "node": "Branch by Solution Type", + "index": 0 + } + ] + ] + }, + "Branch by Solution Type": { + "main": [ + [ + { + "node": "Baramundi API POST Job", + "index": 0 + } + ], + [ + { + "node": "Freescout Reply API", + "index": 0 + } + ], + [ + { + "node": "Handle Unknown Solution Type", + "index": 0 + } + ] + ] + }, + "Baramundi API POST Job": { + "main": [ + [ + { + "node": "Baramundi Job Success", + "index": 0 + } + ] + ], + "error": [ + [ + { + "node": "Error Handler", + "index": 0 + } + ] + ] + }, + "Baramundi Job Success": { + "main": [ + [ + { + "node": "Freescout Mark as EXECUTED", + "index": 0 + } + ] + ] + }, + "Freescout Reply API": { + "main": [ + [ + { + "node": "Reply Sent Success", + "index": 0 + } + ] + ], + "error": [ + [ + { + "node": "Error Handler", + "index": 0 + } + ] + ] + }, + "Reply Sent Success": { + "main": [ + [ + { + "node": "Freescout Mark as EXECUTED", + "index": 0 + } + ] + ] + }, + "Freescout Mark as EXECUTED": { + "main": [ + [ + { + "node": "Trigger Workflow C Webhook", + "index": 0 + } + ] + ], + "error": [ + [ + { + "node": "Error Handler", + "index": 0 + } + ] + ] + }, + "Trigger Workflow C Webhook": { + "main": [ + [ + { + "node": "Log Execution Result", + "index": 0 + } + ] + ], + "error": [ + [ + { + "node": "Error Handler", + "index": 0 + } + ] + ] + }, + "Log Execution Result": { + "main": [ + [] + ] + }, + "Error Handler": { + "main": [ + [] + ] + }, + "Handle Unknown Solution Type": { + "main": [ + [ + { + "node": "Freescout Mark as REJECTED", + "index": 0 + } + ] + ] + }, + "Freescout Mark as REJECTED": { + "main": [ + [ + { + "node": "Log Execution Result", + "index": 0 + } + ] + ], + "error": [ + [ + { + "node": "Error Handler", + "index": 0 + } + ] + ] + } + }, + "active": false, + "settings": { + "errorHandler": "continueOnError", + "timezone": "Europe/Berlin" + }, + "owner": "admin", + "versionId": "1" +}