{ "nodes": [ { "id": "triage-outlook-support-in-jira-0", "name": "Schedule Trigger", "type": "n8n-nodes-base.scheduleTrigger", "position": [ -640, -140 ], "parameters": { "rule": { "interval": [ { "field": "hours" } ] } }, "typeVersion": 1.2 }, { "id": "triage-outlook-support-in-jira-1", "name": "Get Recent Messages", "type": "n8n-nodes-base.microsoftOutlook", "position": [ -440, -140 ], "parameters": { "fields": [ "id", "body", "categories", "conversationId", "from", "hasAttachments", "internetMessageId", "sender", "subject", "toRecipients", "receivedDateTime", "webLink" ], "output": "fields", "options": {}, "filtersUI": { "values": { "filterBy": "filters", "filters": { "receivedAfter": "={{ $now.minus({hours:1}).toISO() }}" } } }, "operation": "getAll", "returnAll": false, "limit": 100 }, "typeVersion": 2 }, { "id": "triage-outlook-support-in-jira-2", "name": "OpenAI Chat Model", "type": "@n8n/n8n-nodes-langchain.lmChatOpenAi", "position": [ 280, 40 ], "parameters": { "model": { "__rl": true, "mode": "list", "value": "gpt-4o-mini" }, "options": {} }, "typeVersion": 1.2 }, { "id": "triage-outlook-support-in-jira-3", "name": "Structured Output Parser", "type": "@n8n/n8n-nodes-langchain.outputParserStructured", "position": [ 480, 40 ], "parameters": { "schemaType": "manual", "inputSchema": "{\"type\":\"object\",\"properties\":{\"labels\":{\"type\":\"array\",\"items\":{\"type\":\"string\",\"enum\":[\"[Technical]\",\"[Account]\",\"[Access]\",\"[Billing]\",\"[Product]\",\"[Training]\",\"[Feedback]\",\"[Complaints]\",\"[Security]\",\"[Privacy]\"]},\"minItems\":1},\"priority\":{\"type\":\"integer\",\"minimum\":1,\"maximum\":5},\"summary\":{\"type\":\"string\",\"minLength\":1},\"description\":{\"type\":\"string\",\"minLength\":1}},\"required\":[\"labels\",\"priority\",\"summary\",\"description\"],\"additionalProperties\":false}" }, "typeVersion": 1.2 }, { "id": "triage-outlook-support-in-jira-4", "name": "Markdown", "type": "n8n-nodes-base.markdown", "position": [ 100, -140 ], "parameters": { "html": "={{ $json.body.content }}", "options": {} }, "typeVersion": 1 }, { "id": "triage-outlook-support-in-jira-5", "name": "Create Issue", "type": "n8n-nodes-base.jira", "position": [ 900, -140 ], "parameters": { "project": { "__rl": true, "mode": "id", "value": "YOUR_JIRA_PROJECT_ID" }, "summary": "={{ $json.summary }}", "issueType": { "__rl": true, "mode": "id", "value": "YOUR_JIRA_ISSUE_TYPE_ID" }, "additionalFields": { "labels": "={{ $json.labels }}", "priority": { "__rl": true, "mode": "id", "value": "={{ $json.priorityId }}" }, "description": "={{ $json.description }}" } }, "typeVersion": 1 }, { "id": "triage-outlook-support-in-jira-6", "name": "Check message state", "type": "n8n-nodes-base.code", "position": [ -240, -140 ], "parameters": { "mode": "runOnceForEachItem", "jsCode": "const m=$input.item.json;if(typeof m.id!==\"string\"||!m.id)throw Error(\"Invalid Outlook message ID\");const state=$getWorkflowStaticData(\"global\"),seen=state.supportMessageIds??[];if(!Array.isArray(seen)||seen.some(x=>typeof x!==\"string\"))throw Error(\"Invalid saved message IDs\");if(seen.includes(m.id))return null;return $input.item;" }, "typeVersion": 2 }, { "id": "triage-outlook-support-in-jira-7", "name": "Generate Issue From Support Request", "type": "@n8n/n8n-nodes-langchain.chainLlm", "position": [ 300, -140 ], "parameters": { "text": "=Reported by {{ $json.from.emailAddress.name }} <{{ $json.from.emailAddress.address }}>\nReported at: {{ $now.toISO() }}\nSummary: {{ $json.subject }}\nDescription:\n{{ $json.data.replaceAll('\\n', ' ') }}", "messages": { "messageValues": [ { "message": "=Your are JIRA triage assistant who's task is to\n1) classify and label the given issue.\n2) Prioritise the given issue.\n3) Rewrite the issue summary and description.\n\n## Labels\nUse one or more. Use words wrapped in \"[]\" (square brackets):\n* Technical\n* Account\n* Access\n* Billing\n* Product\n* Training\n* Feedback\n* Complaints\n* Security\n* Privacy\n\n## Priority\n* 1 - highest\n* 2 - high\n* 3 - medium\n* 4 - low\n* 5 - lowest\n\n## Write Summary and Description\n* Remove emotional and anedotal phrases or information\n* Keep to the facts of the matter\n* Highlight what was attempted and is/was failing" } ] }, "promptType": "define", "hasOutputParser": true }, "typeVersion": 1.6 }, { "name": "Triage one message at a time", "type": "n8n-nodes-base.splitInBatches", "typeVersion": 3, "parameters": { "batchSize": 1, "options": {} }, "id": "triage-outlook-support-in-jira-8" }, { "name": "Prepare the Jira issue", "type": "n8n-nodes-base.code", "typeVersion": 2, "parameters": { "mode": "runOnceForAllItems", "jsCode": "function fields({result,priorityIds}){const allowed=['[Technical]','[Account]','[Access]','[Billing]','[Product]','[Training]','[Feedback]','[Complaints]','[Security]','[Privacy]'];if(!result||typeof result.summary!=='string'||!result.summary.trim()||typeof result.description!=='string'||!result.description.trim()||!Array.isArray(result.labels)||!result.labels.length||result.labels.some(x=>!allowed.includes(x))||!Number.isInteger(result.priority)||result.priority<1||result.priority>5||!Array.isArray(priorityIds)||priorityIds.length!==5||priorityIds.some(x=>typeof x!=='string'||!x||x.startsWith('YOUR_')))throw Error('Invalid triage result or Jira priority mapping');return{summary:result.summary,description:result.description,labels:result.labels,priorityId:priorityIds[result.priority-1]};}\n\nreturn $input.all().map((x,i)=>({json:fields({result:x.json.output,priorityIds:['YOUR_PRIORITY_1_ID','YOUR_PRIORITY_2_ID','YOUR_PRIORITY_3_ID','YOUR_PRIORITY_4_ID','YOUR_PRIORITY_5_ID']}),pairedItem:{item:i}}));" }, "id": "triage-outlook-support-in-jira-9" }, { "name": "Remember the processed message", "type": "n8n-nodes-base.code", "typeVersion": 2, "parameters": { "mode": "runOnceForEachItem", "jsCode": "const issue=$input.item.json,id=$(\"Triage one message at a time\").item.json.id;if(typeof issue.id!==\"string\"||!issue.id||typeof id!==\"string\"||!id)throw Error(\"Issue was not confirmed\");const state=$getWorkflowStaticData(\"global\"),seen=state.supportMessageIds??[];if(!Array.isArray(seen)||seen.some(x=>typeof x!==\"string\"))throw Error(\"Invalid saved message IDs\");if(!seen.includes(id))state.supportMessageIds=[...seen,id];return $input.item;" }, "id": "triage-outlook-support-in-jira-10" } ], "pinData": {}, "connections": { "Markdown": { "main": [ [ { "node": "Generate Issue From Support Request", "type": "main", "index": 0 } ] ] }, "Schedule Trigger": { "main": [ [ { "node": "Get Recent Messages", "type": "main", "index": 0 } ] ] }, "OpenAI Chat Model": { "ai_languageModel": [ [ { "node": "Generate Issue From Support Request", "type": "ai_languageModel", "index": 0 } ] ] }, "Get Recent Messages": { "main": [ [ { "node": "Check message state", "type": "main", "index": 0 } ] ] }, "Structured Output Parser": { "ai_outputParser": [ [ { "node": "Generate Issue From Support Request", "type": "ai_outputParser", "index": 0 } ] ] }, "Generate Issue From Support Request": { "main": [ [ { "node": "Prepare the Jira issue", "type": "main", "index": 0 } ] ] }, "Check message state": { "main": [ [ { "node": "Triage one message at a time", "type": "main", "index": 0 } ] ] }, "Triage one message at a time": { "main": [ [], [ { "node": "Markdown", "type": "main", "index": 0 } ] ] }, "Prepare the Jira issue": { "main": [ [ { "node": "Create Issue", "type": "main", "index": 0 } ] ] }, "Create Issue": { "main": [ [ { "node": "Remember the processed message", "type": "main", "index": 0 } ] ] }, "Remember the processed message": { "main": [ [ { "node": "Triage one message at a time", "type": "main", "index": 0 } ] ] } }, "name": "Triage Outlook Support in Jira", "settings": { "timezone": "UTC", "executionOrder": "v1" }, "active": false }