- Introduced a new API endpoint for sending email notifications using Nodemailer, allowing for customizable email content and recipient management. - Enhanced the notification configuration to support various recipient types (email, user, role, variable) and added error handling for recipient resolution. - Updated the process builder to include HTML message formatting and improved logging for notification processing. - Modified the Nuxt configuration to include Nodemailer as a dependency and adjusted security settings for the notifications API. - Refactored process definition JSON to accommodate changes in notification handling and updated UI components accordingly.
326 lines
12 KiB
JSON
326 lines
12 KiB
JSON
{
|
|
"edges": [
|
|
{
|
|
"id": "start-1752546699787-form-1752546702226-1752546704356",
|
|
"data": {},
|
|
"type": "custom",
|
|
"label": "",
|
|
"source": "start-1752546699787",
|
|
"target": "form-1752546702226",
|
|
"animated": true,
|
|
"sourceHandle": "start-1752546699787-right",
|
|
"targetHandle": "form-1752546702226-left"
|
|
},
|
|
{
|
|
"id": "form-1752546702226-api-1752550319410-1752550321449",
|
|
"data": {},
|
|
"type": "custom",
|
|
"label": "",
|
|
"source": "form-1752546702226",
|
|
"target": "api-1752550319410",
|
|
"animated": true,
|
|
"sourceHandle": "form-1752546702226-right",
|
|
"targetHandle": "api-1752550319410-left"
|
|
},
|
|
{
|
|
"id": "api-1752550319410-script-1752550430989-1752550433556",
|
|
"data": {},
|
|
"type": "custom",
|
|
"label": "",
|
|
"source": "api-1752550319410",
|
|
"target": "script-1752550430989",
|
|
"animated": true,
|
|
"sourceHandle": "api-1752550319410-right",
|
|
"targetHandle": "script-1752550430989-left"
|
|
},
|
|
{
|
|
"id": "html-1752550500000-end-1752546716111-1752550899936",
|
|
"data": {},
|
|
"type": "custom",
|
|
"label": "",
|
|
"source": "html-1752550500000",
|
|
"target": "end-1752546716111",
|
|
"animated": true,
|
|
"sourceHandle": "html-1752550500000-right",
|
|
"targetHandle": "end-1752546716111-left"
|
|
},
|
|
{
|
|
"id": "html-1752550500000-notification-1752621850786-1752621852927",
|
|
"data": {},
|
|
"type": "custom",
|
|
"label": "",
|
|
"source": "html-1752550500000",
|
|
"target": "notification-1752621850786",
|
|
"animated": true,
|
|
"sourceHandle": "html-1752550500000-bottom",
|
|
"targetHandle": "notification-1752621850786-left"
|
|
},
|
|
{
|
|
"id": "notification-1752621850786-end-1752546716111-1752621856004",
|
|
"data": {},
|
|
"type": "custom",
|
|
"label": "",
|
|
"source": "notification-1752621850786",
|
|
"target": "end-1752546716111",
|
|
"animated": true,
|
|
"sourceHandle": "notification-1752621850786-right",
|
|
"targetHandle": "end-1752546716111-left"
|
|
},
|
|
{
|
|
"id": "script-1752550430989-gateway-1752550505000",
|
|
"data": {},
|
|
"type": "custom",
|
|
"label": "",
|
|
"source": "script-1752550430989",
|
|
"target": "gateway-1752550505000",
|
|
"animated": true,
|
|
"sourceHandle": "script-1752550430989-right",
|
|
"targetHandle": "gateway-1752550505000-left"
|
|
},
|
|
{
|
|
"id": "gateway-1752550505000-html-1752550500000",
|
|
"data": { "condition": "todoStatus === true" },
|
|
"type": "custom",
|
|
"label": "Completed",
|
|
"source": "gateway-1752550505000",
|
|
"target": "html-1752550500000",
|
|
"animated": true,
|
|
"sourceHandle": "gateway-1752550505000-right",
|
|
"targetHandle": "html-1752550500000-left"
|
|
},
|
|
{
|
|
"id": "gateway-1752550505000-form-1752546702226-1753409198979",
|
|
"data": {},
|
|
"type": "custom",
|
|
"label": "Not Completed",
|
|
"source": "gateway-1752550505000",
|
|
"target": "form-1752546702226",
|
|
"animated": true,
|
|
"sourceHandle": "gateway-1752550505000-bottom",
|
|
"targetHandle": "form-1752546702226-top"
|
|
}
|
|
],
|
|
"nodes": [
|
|
{
|
|
"id": "start-1752546699787",
|
|
"data": { "label": "Start", "description": "Process start point" },
|
|
"type": "start",
|
|
"label": "Start",
|
|
"position": { "x": 300, "y": 300 }
|
|
},
|
|
{
|
|
"id": "form-1752546702226",
|
|
"data": {
|
|
"label": "Pilihan Kategori Asnaf",
|
|
"shape": "rectangle",
|
|
"formId": 1,
|
|
"formName": "Pilihan Kategori Asnaf",
|
|
"formUuid": "d3612e05-b31a-46dc-b5e5-67e6c5bd3e78",
|
|
"textColor": "#6b21a8",
|
|
"borderColor": "#9333ea",
|
|
"description": "Form: Pilihan Kategori Asnaf",
|
|
"assignedRoles": [
|
|
{ "label": "Pemohon", "value": "2", "description": "" }
|
|
],
|
|
"assignedUsers": [],
|
|
"inputMappings": [],
|
|
"assignmentType": "roles",
|
|
"outputMappings": [
|
|
{ "formField": "kategori_asnaf", "processVariable": "kategoriAsnaf" },
|
|
{ "formField": "nama_asnaf", "processVariable": "namaAsnaf" }
|
|
],
|
|
"backgroundColor": "#faf5ff",
|
|
"fieldConditions": [],
|
|
"assignmentVariable": "",
|
|
"assignmentVariableType": "user_id"
|
|
},
|
|
"type": "form",
|
|
"label": "Pilihan Kategori Asnaf",
|
|
"position": { "x": 555, "y": 270 }
|
|
},
|
|
{
|
|
"id": "end-1752546716111",
|
|
"data": { "label": "End", "description": "Process end point" },
|
|
"type": "end",
|
|
"label": "End",
|
|
"position": { "x": 2070, "y": 300 }
|
|
},
|
|
{
|
|
"id": "api-1752550319410",
|
|
"data": {
|
|
"body": {
|
|
"data": "{ \"kategori_asnaf\" : \"{kategoriAsnaf}\", \"nama_asnaf\" : \"{namaAsnaf}\"}",
|
|
"type": "raw"
|
|
},
|
|
"label": "API Call",
|
|
"shape": "rectangle",
|
|
"apiUrl": "https://jsonplaceholder.typicode.com/posts",
|
|
"params": [],
|
|
"headers": [{ "key": "Content-Type", "value": "application/json" }],
|
|
"apiMethod": "POST",
|
|
"textColor": "#1e40af",
|
|
"borderColor": "#3b82f6",
|
|
"description": "External API call",
|
|
"requestBody": "",
|
|
"authorization": { "type": "none" },
|
|
"errorVariable": "apiError",
|
|
"outputVariable": "apiResponse",
|
|
"backgroundColor": "#eff6ff",
|
|
"continueOnError": false
|
|
},
|
|
"type": "api",
|
|
"label": "API Call",
|
|
"position": { "x": 795, "y": -60 }
|
|
},
|
|
{
|
|
"id": "script-1752550430989",
|
|
"data": {
|
|
"label": "Script Task",
|
|
"shape": "rectangle",
|
|
"textColor": "#374151",
|
|
"scriptCode": "// Map API response to process variables\nconst api = processVariables.apiResponse || {};\nprocessVariables.todoTitle = api.kategori_asnaf || '';\nprocessVariables.namaAsnaf = api.nama_asnaf || '';\nprocessVariables.todoStatus = api.id > 100; // true if id > 100, otherwise false\n\n// New logic: Calculate a score\nconst katLen = (api.kategori_asnaf || '').length;\nconst namaLen = (api.nama_asnaf || '').length;\nprocessVariables.asnafScore = katLen * 10 + namaLen * 5;\n\n// New logic: Add a timestamp\nprocessVariables.resultTimestamp = new Date().toISOString();\n\n// New logic: Create a summary string\nprocessVariables.resultSummary = `Asnaf: ${processVariables.todoTitle}, Nama: ${processVariables.namaAsnaf}, Score: ${processVariables.asnafScore}, Time: ${processVariables.resultTimestamp}`;\n",
|
|
"borderColor": "#6b7280",
|
|
"description": "Execute JavaScript code",
|
|
"inputVariables": ["apiResponse"],
|
|
"scriptLanguage": "javascript",
|
|
"backgroundColor": "#f9fafb",
|
|
"outputVariables": [
|
|
{
|
|
"name": "todoTitle",
|
|
"type": "string",
|
|
"description": "Title from API response"
|
|
},
|
|
{
|
|
"name": "namaAsnaf",
|
|
"type": "string",
|
|
"description": "Nama Asnaf from API response"
|
|
},
|
|
{
|
|
"name": "todoStatus",
|
|
"type": "boolean",
|
|
"description": "Todo Status from API response"
|
|
},
|
|
{
|
|
"name": "asnafScore",
|
|
"type": "number",
|
|
"description": "Calculated Asnaf Score"
|
|
},
|
|
{
|
|
"name": "resultTimestamp",
|
|
"type": "string",
|
|
"description": "Result Timestamp"
|
|
},
|
|
{
|
|
"name": "resultSummary",
|
|
"type": "string",
|
|
"description": "Result Summary"
|
|
}
|
|
]
|
|
},
|
|
"type": "script",
|
|
"label": "Script Task",
|
|
"position": { "x": 1110, "y": -60 }
|
|
},
|
|
{
|
|
"id": "gateway-1752550505000",
|
|
"data": {
|
|
"label": "Decision: Todo Status",
|
|
"shape": "diamond",
|
|
"textColor": "#c2410c",
|
|
"conditions": [
|
|
{
|
|
"id": "condition-group-1",
|
|
"output": "Completed",
|
|
"conditions": [
|
|
{
|
|
"id": "condition-1753408402567",
|
|
"value": "afiq",
|
|
"maxValue": "",
|
|
"minValue": "",
|
|
"operator": "contains",
|
|
"variable": "namaAsnaf",
|
|
"valueType": "string",
|
|
"logicalOperator": "and"
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"id": "condition-group-2",
|
|
"output": "Not Completed",
|
|
"conditions": [
|
|
{
|
|
"id": "condition-2",
|
|
"value": "afiq",
|
|
"maxValue": "",
|
|
"minValue": "",
|
|
"operator": "not_contains",
|
|
"variable": "namaAsnaf",
|
|
"valueType": "string",
|
|
"logicalOperator": "and"
|
|
}
|
|
]
|
|
}
|
|
],
|
|
"borderColor": "#f97316",
|
|
"defaultPath": "Default",
|
|
"description": "Branch based on todoStatus",
|
|
"backgroundColor": "#fff7ed"
|
|
},
|
|
"type": "gateway",
|
|
"label": "Decision: Todo Status",
|
|
"position": { "x": 1365, "y": 120 }
|
|
},
|
|
{
|
|
"id": "html-1752550500000",
|
|
"data": {
|
|
"label": "Show Result",
|
|
"shape": "rectangle",
|
|
"jsCode": "const completed = \"{{todoStatus}}\" === 'true' || \"{{todoStatus}}\" === true;\ndocument.getElementById('todo-title').innerText = \"{{todoTitle}}\";\ndocument.getElementById('todo-status').innerText = completed ? 'Completed ✅' : 'Not Completed ❌';\ndocument.getElementById('todo-status').className = completed ? 'done' : 'not-done';",
|
|
"cssCode": ".result-box {\n background-color: #ffffff;\n border-radius: 12px;\n box-shadow: 0 8px 16px rgba(0,0,0,0.1);\n padding: 30px 40px;\n max-width: 600px;\n text-align: center;\n }\n .result-box h2 {\n color: #333;\n margin-bottom: 20px;\n }\n .result-box p {\n font-size: 1.2em;\n color: #555;\n }\n .done {\n color: green;\n font-weight: bold;\n }\n .not-done {\n color: red;\n font-weight: bold;\n }",
|
|
"htmlCode": "<div class=\"result-box\">\n <h2>Asnaf Result</h2>\n <p><strong>Title:</strong> <span id=\"todo-title\">{{todoTitle}}</span></p>\n <p><strong>Status:</strong> <span id=\"todo-status\">{{todoStatus}}</span></p>\n <p><strong>Nama:</strong> {{namaAsnaf}}</p>\n <p><strong>Score:</strong> {{asnafScore}}</p>\n <p><strong>Timestamp:</strong> {{resultTimestamp}}</p>\n <p><strong>Summary:</strong> {{resultSummary}}</p>\n</div>",
|
|
"textColor": "#333333",
|
|
"autoRefresh": true,
|
|
"borderColor": "#dddddd",
|
|
"description": "Display the todo title from API",
|
|
"inputVariables": ["todoTitle", "todoStatus"],
|
|
"backgroundColor": "#ffffff",
|
|
"outputVariables": [],
|
|
"allowVariableAccess": true
|
|
},
|
|
"type": "html",
|
|
"label": "Show Result",
|
|
"position": { "x": 1635, "y": 150 }
|
|
},
|
|
{
|
|
"id": "notification-1752621850786",
|
|
"data": {
|
|
"label": "Notification",
|
|
"message": "This is the notification",
|
|
"subject": "This is the notification",
|
|
"priority": "medium",
|
|
"expiration": { "unit": "hours", "value": 24, "enabled": false },
|
|
"description": "Send notification to users",
|
|
"htmlMessage": "<div style=\"font-family: Arial, sans-serif; padding: 15px;\">\n <h2 style=\"color: #3b82f6;\">Notification Title</h2>\n <p>Hello {namaAsnaf},</p>\n <p>This is a basic notification message.</p>\n <p>Thank you,<br>Process Maker</p>\n</div>",
|
|
"messageFormat": "html",
|
|
"recipientRole": "",
|
|
"recipientType": "email",
|
|
"recipientUser": "",
|
|
"recipientEmail": "mdafiqiskandar@gmail.com",
|
|
"recipientGroup": "",
|
|
"deliveryOptions": { "sms": false, "email": true, "inApp": true },
|
|
"richTextMessage": "",
|
|
"notificationType": "info",
|
|
"recipientVariable": ""
|
|
},
|
|
"type": "notification",
|
|
"label": "Notification",
|
|
"position": { "x": 1815, "y": 405 }
|
|
}
|
|
],
|
|
"viewport": {
|
|
"x": -145.563928050559,
|
|
"y": 328.559309674283,
|
|
"zoom": 0.7049100631988332
|
|
}
|
|
}
|