AutomationFlowsData & Sheets › Handle Task Events Webhook to Postgres

Handle Task Events Webhook to Postgres

Original n8n title: Mis Sentinel - Task Events

MIS Sentinel - Task Events. Uses respondToWebhook, postgres, stickyNote. Webhook trigger; 11 nodes.

Webhook trigger★★★★☆ complexity11 nodesPostgres
Data & Sheets Trigger: Webhook Nodes: 11 Complexity: ★★★★☆ Added:

The workflow JSON

Copy or download the full n8n JSON below. Paste it into a new n8n workflow, add your credentials, activate. Full import guide →

Download .json
{
  "name": "MIS Sentinel - Task Events",
  "nodes": [
    {
      "parameters": {
        "httpMethod": "POST",
        "path": "mis-task-events",
        "responseMode": "responseNode",
        "options": {}
      },
      "id": "webhook-trigger",
      "name": "Task Events Webhook",
      "type": "n8n-nodes-base.webhook",
      "typeVersion": 2,
      "position": [
        250,
        300
      ]
    },
    {
      "parameters": {
        "jsCode": "// Validate and extract event data\nconst body = $input.first().json.body || $input.first().json;\n\nconst event = body.event;\nconst task = body.task || {};\nconst timestamp = body.timestamp || new Date().toISOString();\nconst triggeredBy = body.triggered_by || 'system';\n\nif (!event) {\n  return [{\n    json: {\n      valid: false,\n      error: 'Missing event type'\n    }\n  }];\n}\n\n// Determine notification priority\nlet shouldNotify = false;\nlet notificationType = 'log';\nlet notificationMessage = '';\n\nswitch (event) {\n  case 'task.created':\n    if (['urgent', 'high'].includes(task.priority)) {\n      shouldNotify = true;\n      notificationType = 'group_notify';\n      notificationMessage = `\ud83c\udd95 Nova task ${task.priority?.toUpperCase()}: ${task.title}\\n\ud83d\udcc1 Projeto: ${task.project_key || 'N/A'}\\n\ud83d\udcc5 Prazo: ${task.due_date || 'Sem prazo'}`;\n    }\n    break;\n    \n  case 'task.completed':\n    shouldNotify = true;\n    notificationType = 'log';\n    notificationMessage = `\u2705 Task conclu\u00edda: ${task.title}\\n\u23f1\ufe0f Tempo: ${task.actual_hours ? task.actual_hours + 'h' : 'N/A'}`;\n    break;\n    \n  case 'task.blocked':\n    shouldNotify = true;\n    notificationType = 'alert_responsible';\n    notificationMessage = `\ud83d\udeab Task BLOQUEADA: ${task.title}\\n\ud83d\udcc1 Projeto: ${task.project_key || 'N/A'}\\n\ud83d\udc64 Respons\u00e1vel: ${task.assigned_to || 'N\u00e3o atribu\u00eddo'}\\n\ud83d\udcdd Motivo: ${task.notes || 'N\u00e3o especificado'}`;\n    break;\n    \n  case 'task.overdue':\n    shouldNotify = true;\n    notificationType = 'overdue_alert';\n    notificationMessage = `\u26a0\ufe0f PRAZO ESTOURADO: ${task.title}\\n\ud83d\udcc1 Projeto: ${task.project_key || 'N/A'}\\n\ud83d\udcc5 Era para: ${task.due_date}\\n\ud83d\udc64 Respons\u00e1vel: ${task.assigned_to || 'N\u00e3o atribu\u00eddo'}`;\n    break;\n    \n  case 'task.due_soon':\n    shouldNotify = true;\n    notificationType = 'reminder';\n    notificationMessage = `\u23f0 Prazo pr\u00f3ximo (<24h): ${task.title}\\n\ud83d\udcc1 Projeto: ${task.project_key || 'N/A'}\\n\ud83d\udcc5 Prazo: ${task.due_date}`;\n    break;\n    \n  default:\n    notificationType = 'log';\n    notificationMessage = `\ud83d\udccc Evento: ${event} - ${task.title || 'N/A'}`;\n}\n\nreturn [{\n  json: {\n    valid: true,\n    event,\n    task,\n    timestamp,\n    triggeredBy,\n    shouldNotify,\n    notificationType,\n    notificationMessage,\n    taskId: task.id,\n    taskTitle: task.title,\n    taskPriority: task.priority,\n    taskStatus: task.status,\n    projectKey: task.project_key\n  }\n}];"
      },
      "id": "process-event",
      "name": "Process Event",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        450,
        300
      ]
    },
    {
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "strict"
          },
          "conditions": [
            {
              "id": "valid-check",
              "leftValue": "={{ $json.valid }}",
              "rightValue": true,
              "operator": {
                "type": "boolean",
                "operation": "equals"
              }
            }
          ],
          "combinator": "and"
        },
        "options": {}
      },
      "id": "check-valid",
      "name": "Is Valid?",
      "type": "n8n-nodes-base.if",
      "typeVersion": 2,
      "position": [
        650,
        300
      ]
    },
    {
      "parameters": {
        "respondWith": "json",
        "responseBody": "={{ JSON.stringify({ success: false, error: $json.error || 'Invalid event' }) }}",
        "options": {
          "responseCode": 400
        }
      },
      "id": "error-response",
      "name": "Error Response",
      "type": "n8n-nodes-base.respondToWebhook",
      "typeVersion": 1.1,
      "position": [
        850,
        450
      ]
    },
    {
      "parameters": {
        "rules": {
          "values": [
            {
              "conditions": {
                "options": {
                  "caseSensitive": true,
                  "leftValue": "",
                  "typeValidation": "strict"
                },
                "conditions": [
                  {
                    "leftValue": "={{ $json.notificationType }}",
                    "rightValue": "group_notify",
                    "operator": {
                      "type": "string",
                      "operation": "equals"
                    }
                  }
                ],
                "combinator": "and"
              },
              "renameOutput": true,
              "outputKey": "Group Notify"
            },
            {
              "conditions": {
                "options": {
                  "caseSensitive": true,
                  "leftValue": "",
                  "typeValidation": "strict"
                },
                "conditions": [
                  {
                    "leftValue": "={{ $json.notificationType }}",
                    "rightValue": "alert_responsible",
                    "operator": {
                      "type": "string",
                      "operation": "equals"
                    }
                  }
                ],
                "combinator": "and"
              },
              "renameOutput": true,
              "outputKey": "Alert Responsible"
            },
            {
              "conditions": {
                "options": {
                  "caseSensitive": true,
                  "leftValue": "",
                  "typeValidation": "strict"
                },
                "conditions": [
                  {
                    "leftValue": "={{ $json.notificationType }}",
                    "rightValue": "overdue_alert",
                    "operator": {
                      "type": "string",
                      "operation": "equals"
                    }
                  }
                ],
                "combinator": "and"
              },
              "renameOutput": true,
              "outputKey": "Overdue Alert"
            },
            {
              "conditions": {
                "options": {
                  "caseSensitive": true,
                  "leftValue": "",
                  "typeValidation": "strict"
                },
                "conditions": [
                  {
                    "leftValue": "={{ $json.notificationType }}",
                    "rightValue": "log",
                    "operator": {
                      "type": "string",
                      "operation": "equals"
                    }
                  }
                ],
                "combinator": "and"
              },
              "renameOutput": true,
              "outputKey": "Log Only"
            }
          ]
        },
        "options": {}
      },
      "id": "route-by-type",
      "name": "Route by Notification Type",
      "type": "n8n-nodes-base.switch",
      "typeVersion": 3,
      "position": [
        850,
        200
      ]
    },
    {
      "parameters": {
        "operation": "executeQuery",
        "query": "INSERT INTO mottivme_intelligence_system.task_event_logs (event_type, task_id, task_title, project_key, priority, notification_type, message, triggered_by, processed_at)\nVALUES (\n  '{{ $json.event }}',\n  '{{ $json.taskId }}',\n  '{{ $json.taskTitle }}',\n  '{{ $json.projectKey }}',\n  '{{ $json.taskPriority }}',\n  '{{ $json.notificationType }}',\n  '{{ $json.notificationMessage }}',\n  '{{ $json.triggeredBy }}',\n  NOW()\n)\nRETURNING id",
        "options": {}
      },
      "id": "log-event",
      "name": "Log Event to DB",
      "type": "n8n-nodes-base.postgres",
      "typeVersion": 2.6,
      "position": [
        1050,
        500
      ],
      "credentials": {
        "postgres": {
          "name": "<your credential>"
        }
      },
      "alwaysOutputData": true,
      "onError": "continueRegularOutput"
    },
    {
      "parameters": {
        "respondWith": "json",
        "responseBody": "={{ JSON.stringify({ success: true, event: $('Process Event').first().json.event, logged: true }) }}",
        "options": {}
      },
      "id": "success-response",
      "name": "Success Response",
      "type": "n8n-nodes-base.respondToWebhook",
      "typeVersion": 1.1,
      "position": [
        1250,
        500
      ]
    },
    {
      "parameters": {
        "jsCode": "// Prepare group notification\nconst data = $input.first().json;\n\nreturn [{\n  json: {\n    message: data.notificationMessage,\n    chat_id: process.env.TELEGRAM_GROUP_ID || '-1001234567890',\n    priority: data.taskPriority,\n    event: data.event\n  }\n}];"
      },
      "id": "prepare-group-notify",
      "name": "Prepare Group Notification",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        1050,
        0
      ]
    },
    {
      "parameters": {
        "jsCode": "// Prepare responsible alert\nconst data = $input.first().json;\n\nreturn [{\n  json: {\n    message: data.notificationMessage,\n    responsible: data.task?.assigned_to || 'team',\n    taskId: data.taskId,\n    event: data.event\n  }\n}];"
      },
      "id": "prepare-alert",
      "name": "Prepare Alert",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        1050,
        150
      ]
    },
    {
      "parameters": {
        "jsCode": "// Prepare overdue notification\nconst data = $input.first().json;\n\nreturn [{\n  json: {\n    message: `\ud83d\udd34 URGENTE\\n\\n${data.notificationMessage}`,\n    urgency: 'high',\n    taskId: data.taskId,\n    event: data.event\n  }\n}];"
      },
      "id": "prepare-overdue",
      "name": "Prepare Overdue Alert",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        1050,
        300
      ]
    },
    {
      "parameters": {
        "content": "## MIS Sentinel - Task Events Webhook\n\n### Eventos Suportados:\n- `task.created` \u2192 Notifica grupo se prioridade urgent/high\n- `task.completed` \u2192 Log de conclus\u00e3o\n- `task.blocked` \u2192 Alerta respons\u00e1vel\n- `task.overdue` \u2192 Notifica prazo estourado\n- `task.due_soon` \u2192 Lembrete 24h antes\n\n### Endpoint:\n`POST /webhook/mis-task-events`\n\n### Configurar:\n1. Adicionar credenciais Telegram\n2. Configurar ID do grupo\n3. Criar tabela task_event_logs no Supabase",
        "height": 400,
        "width": 350
      },
      "id": "sticky-note",
      "name": "Documentation",
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        40,
        40
      ]
    }
  ],
  "connections": {
    "Task Events Webhook": {
      "main": [
        [
          {
            "node": "Process Event",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Process Event": {
      "main": [
        [
          {
            "node": "Is Valid?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Is Valid?": {
      "main": [
        [
          {
            "node": "Route by Notification Type",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Error Response",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Route by Notification Type": {
      "main": [
        [
          {
            "node": "Prepare Group Notification",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Prepare Alert",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Prepare Overdue Alert",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Log Event to DB",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Prepare Group Notification": {
      "main": [
        [
          {
            "node": "Log Event to DB",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Prepare Alert": {
      "main": [
        [
          {
            "node": "Log Event to DB",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Prepare Overdue Alert": {
      "main": [
        [
          {
            "node": "Log Event to DB",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Log Event to DB": {
      "main": [
        [
          {
            "node": "Success Response",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "active": false,
  "settings": {
    "executionOrder": "v1"
  },
  "versionId": "1",
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "tags": [
    {
      "name": "MIS Sentinel"
    },
    {
      "name": "Webhooks"
    },
    {
      "name": "Tasks"
    }
  ]
}

Credentials you'll need

Each integration node will prompt for credentials when you import. We strip credential IDs before publishing — you'll add your own.

Pro

For the full experience including quality scoring and batch install features for each workflow upgrade to Pro

How this works

This workflow enables seamless monitoring and logging of task events in your management information system, ensuring every update is captured reliably without manual intervention. It suits teams handling high volumes of tasks, such as project managers or operations staff, who need real-time visibility to maintain oversight and respond promptly. The key step involves routing incoming webhook events by type—using a switch node—before logging them securely to a Postgres database, with immediate success or error responses sent back to the source for confirmation.

Use this workflow when integrating task notifications from external systems like project trackers into your MIS for automated auditing and alerts. Avoid it for simple, low-frequency updates where basic logging suffices, or if your setup lacks webhook support. Common variations include adding email notifications via integrations like SendGrid for group alerts, or expanding the Postgres schema to track additional event metadata for deeper analytics.

About this workflow

MIS Sentinel - Task Events. Uses respondToWebhook, postgres, stickyNote. Webhook trigger; 11 nodes.

Source: https://github.com/marcosdanielsf/MIS-Sentinel/blob/f6ee8ebd9d2daf476120db9e365eba33a3407576/n8n-workflows/mis-task-events.json — original creator credit. Request a take-down →

More Data & Sheets workflows → · Browse all categories →

Related workflows

Workflows that share integrations, category, or trigger type with this one. All free to copy and import.

Data & Sheets

Scraping. Uses httpRequest, postgres, @apify/n8n-nodes-apify, respondToWebhook. Webhook trigger; 61 nodes.

HTTP Request, Postgres, @Apify/N8N Nodes Apify
Data & Sheets

Workflow B — AI Listing Engine. Uses httpRequest, postgres, errorTrigger. Webhook trigger; 47 nodes.

HTTP Request, Postgres, Error Trigger
Data & Sheets

How it works

Postgres, Email Send
Data & Sheets

LogSentinel Workflow. Uses postgres, emailSend, httpRequest. Webhook trigger; 44 nodes.

Postgres, Email Send, HTTP Request
Data & Sheets

This workflow automates data maturity evaluation to measure how well an organization uses data to create value by capturing assessment data through forms or APIs, processing and scoring responses usin

Email Send, Postgres