AutomationFlowsSlack & Telegram › Handle Quality Rating

Handle Quality Rating

Handle_Quality_Rating. Uses executeWorkflowTrigger, postgres, discord. Event-driven trigger; 5 nodes.

Event trigger★★★★☆ complexity5 nodesExecute Workflow TriggerPostgresDiscord
Slack & Telegram Trigger: Event Nodes: 5 Complexity: ★★★★☆ Added:

This workflow follows the Execute Workflow Trigger → Postgres recipe pattern — see all workflows that pair these two integrations.

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
{
  "updatedAt": "2025-12-24T08:53:14.532Z",
  "createdAt": "2025-12-23T09:30:29.200Z",
  "id": "887fJOHvjP78PQoO",
  "name": "Handle_Quality_Rating",
  "description": null,
  "active": false,
  "isArchived": false,
  "nodes": [
    {
      "parameters": {
        "inputSource": "passthrough"
      },
      "type": "n8n-nodes-base.executeWorkflowTrigger",
      "typeVersion": 1.1,
      "position": [
        -400,
        300
      ],
      "id": "trigger-quality-rating",
      "name": "ReceiveEvent"
    },
    {
      "parameters": {
        "jsCode": "// Parse quality rating from emoji\nconst ctx = $json.ctx;\nconst emoji = ctx.event.emoji;\n\n// Map emoji to quality score\nconst qualityMap = {\n  '\ud83d\udc4d': 1.0,\n  '\ud83d\udc4e': 0.0\n};\n\nconst qualityScore = qualityMap[emoji];\n\nif (qualityScore === undefined) {\n  throw new Error(`Unknown quality emoji: ${emoji}`);\n}\n\nreturn {\n  json: {\n    ctx,\n    quality_score: qualityScore,\n    emoji\n  }\n};",
        "mode": "runOnceForEachItem"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        -180,
        300
      ],
      "id": "parse-quality",
      "name": "ParseQualityRating"
    },
    {
      "parameters": {
        "operation": "executeQuery",
        "query": "-- Find projections by either the original user message or the bot reply message\nWITH target_projections AS (\n  -- Option 1: User message that triggered projections\n  SELECT p.id\n  FROM projections p\n  JOIN events e ON p.event_id = e.id\n  WHERE e.payload->>'discord_message_id' = $3\n    AND e.event_type = 'discord_message'\n    AND p.status IN ('auto_confirmed', 'confirmed')\n  UNION\n  -- Option 2: Bot reply message (projection stores the message ID)\n  SELECT p.id\n  FROM projections p\n  WHERE (p.data->>'discord_message_id' = $3\n     OR p.metadata->>'message_id' = $3)\n    AND p.status IN ('auto_confirmed', 'confirmed')\n)\nUPDATE projections\nSET \n  quality_score = $1,\n  metadata = COALESCE(metadata, '{}'::jsonb) || jsonb_build_object(\n    'quality_rated_at', NOW(),\n    'quality_emoji', $2\n  )\nWHERE id IN (SELECT id FROM target_projections)\nRETURNING id, projection_type, quality_score;",
        "options": {
          "values": "={{ [  $json.quality_score ,  $json.emoji ,  $json.ctx.event.message_id  ] }}"
        }
      },
      "type": "n8n-nodes-base.postgres",
      "typeVersion": 2.4,
      "position": [
        40,
        300
      ],
      "id": "update-quality-score",
      "name": "UpdateQualityScore",
      "alwaysOutputData": true,
      "credentials": {
        "postgres": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "mode": "runOnceForAllItems",
        "jsCode": "const result = $json;\nconst rating = result.rating;\nconst projectionId = result.projection_id;\nconst qualityScore = result.quality_score;\nconst userFeedback = result.user_feedback;\n\nconst response = `\u2705 Quality rating recorded!`;\n\nif (userFeedback) {\n  response += `\\n\\n**Your feedback:** ${userFeedback}`;\n}\n\nresponse += `\\n\\n**Rating Summary:**\\n- Rating: ${rating}/5\\n- Projection: ${projectionId}\\n- Score: ${qualityScore}`;\n\nreturn {\n  json: {\n    response: response,\n    channel_id: result.ctx.event.channel_id\n  }\n};"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        260,
        300
      ],
      "id": "format-response",
      "name": "FormatResponse"
    },
    {
      "parameters": {
        "resource": "message",
        "guildId": {
          "__rl": true,
          "value": "={{ $json.ctx.event.guild_id }}",
          "mode": "id"
        },
        "channelId": {
          "__rl": true,
          "value": "={{ $json.ctx.event.channel_id }}",
          "mode": "id"
        },
        "content": "={{ $json.response.content }}",
        "options": {
          "messageReference": "={{ $json.ctx.event.message_id }}"
        }
      },
      "type": "n8n-nodes-base.discord",
      "typeVersion": 2,
      "position": [
        480,
        300
      ],
      "id": "send-response",
      "name": "SendResponse",
      "retryOnFail": true,
      "maxTries": 3,
      "waitBetweenTries": 1000,
      "credentials": {
        "discordBotApi": {
          "name": "<your credential>"
        }
      }
    }
  ],
  "connections": {
    "ReceiveEvent": {
      "main": [
        [
          {
            "node": "ParseQualityRating",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "ParseQualityRating": {
      "main": [
        [
          {
            "node": "UpdateQualityScore",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "UpdateQualityScore": {
      "main": [
        [
          {
            "node": "FormatResponse",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "FormatResponse": {
      "main": [
        [
          {
            "node": "SendResponse",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "settings": {
    "callerPolicy": "workflowsFromSameOwner",
    "errorWorkflow": "NOJ7FqVhVLqw0n8D",
    "availableInMCP": false,
    "executionOrder": "v1"
  },
  "staticData": null,
  "meta": null,
  "versionId": "9271c0f2-3250-4718-b3b8-aaaf9a4d1f23",
  "activeVersionId": null,
  "versionCounter": 126,
  "triggerCount": 0,
  "shared": [
    {
      "updatedAt": "2025-12-23T09:30:29.200Z",
      "createdAt": "2025-12-23T09:30:29.200Z",
      "role": "workflow:owner",
      "workflowId": "887fJOHvjP78PQoO",
      "projectId": "erM3nntdLL53noWi",
      "project": {
        "updatedAt": "2025-12-23T09:23:39.658Z",
        "createdAt": "2025-12-23T09:16:56.460Z",
        "id": "erM3nntdLL53noWi",
        "name": "Chris Irineo <chriskevini@gmail.com>",
        "type": "personal",
        "icon": null,
        "description": null,
        "projectRelations": [
          {
            "updatedAt": "2025-12-23T09:16:56.460Z",
            "createdAt": "2025-12-23T09:16:56.460Z",
            "userId": "2a851a2d-b7e5-4b3c-aefb-6eaaa79e0659",
            "projectId": "erM3nntdLL53noWi",
            "user": {
              "updatedAt": "2025-12-24T08:40:46.063Z",
              "createdAt": "2025-12-23T09:16:54.881Z",
              "id": "2a851a2d-b7e5-4b3c-aefb-6eaaa79e0659",
              "email": "chriskevini@gmail.com",
              "firstName": "Chris",
              "lastName": "Irineo",
              "personalizationAnswers": {
                "version": "v4",
                "personalization_survey_submitted_at": "2025-12-23T09:23:43.723Z",
                "personalization_survey_n8n_version": "1.123.5"
              },
              "settings": {
                "userActivated": true,
                "firstSuccessfulWorkflowId": "CgUAxK0i4YhrZ2Wp",
                "userActivatedAt": 1766487000077,
                "easyAIWorkflowOnboarded": true
              },
              "disabled": false,
              "mfaEnabled": false,
              "lastActiveAt": "2025-12-24",
              "isPending": false
            }
          }
        ]
      }
    }
  ],
  "tags": [],
  "activeVersion": null
}

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

About this workflow

Handle_Quality_Rating. Uses executeWorkflowTrigger, postgres, discord. Event-driven trigger; 5 nodes.

Source: https://github.com/chriskevini/kairon/blob/ab924f228ceb22522b9a4dfa1ab4589eb86273ad/n8n-workflows/Handle_Quality_Rating.json — original creator credit. Request a take-down →

More Slack & Telegram workflows → · Browse all categories →

Related workflows

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

Slack & Telegram

Execute_Command. Uses executeWorkflowTrigger, postgres, discord, httpRequest. Event-driven trigger; 47 nodes.

Execute Workflow Trigger, Postgres, Discord +1
Slack & Telegram

03 - Command Handler. Uses executeWorkflowTrigger, telegram, executeCommand, postgres. Event-driven trigger; 53 nodes.

Execute Workflow Trigger, Telegram, Execute Command +2
Slack & Telegram

Unlock low-cost, high-control generative media workflows directly from n8n by integrating with ComfyUI. Ideal for indie creators, AI developers, or small teams seeking scalable media automation—from i

Execute Workflow Trigger, HTTP Request, Read Write File +2
Slack & Telegram

This workflow will backup all of your existed workflows to a single Github repository.

Execute Workflow Trigger, n8n, GitHub +1
Slack & Telegram

Trying to connect n8n to your Discord server but not sure where to start? 🤔 Setting up a Discord Bot and its credentials can be confusing. This workflow provides the perfect starting point, guiding yo

Discord, Execute Workflow Trigger