AutomationFlowsData & Sheets › Wf 005 Asset Approval Gate

Wf 005 Asset Approval Gate

WF-005-asset-approval-gate. Uses httpRequest, postgres. Webhook trigger; 13 nodes.

Webhook trigger★★★★☆ complexity13 nodesHTTP RequestPostgres
Data & Sheets Trigger: Webhook Nodes: 13 Complexity: ★★★★☆ Added:

This workflow follows the HTTP Request → 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
{
  "name": "WF-005-asset-approval-gate",
  "nodes": [
    {
      "parameters": {
        "httpMethod": "POST",
        "path": "telegram-approval",
        "responseMode": "onReceived",
        "options": {}
      },
      "id": "c50500000-0005-0005-0005-000000000001",
      "name": "Telegram Webhook",
      "type": "n8n-nodes-base.webhook",
      "typeVersion": 2,
      "position": [
        240,
        400
      ]
    },
    {
      "parameters": {
        "jsCode": "const b = $input.item.json.body || {};\nif (b.callback_query) {\n  const cq = b.callback_query;\n  const m = String(cq.data || '').match(/^(approve|reject)_(\\d+)$/);\n  return [{ json: {\n    kind: m ? 'callback' : 'other',\n    action: m ? m[1] : null,\n    asset_id: m ? Number(m[2]) : null,\n    callback_query_id: cq.id,\n    chat_id: cq.message && cq.message.chat && cq.message.chat.id\n  } }];\n}\nif (b.message && b.message.reply_to_message) {\n  const rm = b.message.reply_to_message.text || '';\n  const m = rm.match(/asset #(\\d+)/);\n  return [{ json: {\n    kind: m ? 'reject_reason' : 'other',\n    asset_id: m ? Number(m[1]) : null,\n    reason: b.message.text || '',\n    chat_id: b.message.chat && b.message.chat.id\n  } }];\n}\nreturn [{ json: { kind: 'other' } }];"
      },
      "id": "c50500000-0005-0005-0005-000000000002",
      "name": "Route Update",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        460,
        400
      ]
    },
    {
      "parameters": {
        "rules": {
          "values": [
            {
              "conditions": {
                "options": {
                  "caseSensitive": true,
                  "typeValidation": "strict"
                },
                "conditions": [
                  {
                    "leftValue": "={{ $json.kind }}",
                    "rightValue": "callback",
                    "operator": {
                      "type": "string",
                      "operation": "equals"
                    }
                  }
                ],
                "combinator": "and"
              },
              "renameOutput": true,
              "outputKey": "callback"
            },
            {
              "conditions": {
                "options": {
                  "caseSensitive": true,
                  "typeValidation": "strict"
                },
                "conditions": [
                  {
                    "leftValue": "={{ $json.kind }}",
                    "rightValue": "reject_reason",
                    "operator": {
                      "type": "string",
                      "operation": "equals"
                    }
                  }
                ],
                "combinator": "and"
              },
              "renameOutput": true,
              "outputKey": "reject_reason"
            }
          ]
        },
        "options": {
          "fallbackOutput": "none"
        }
      },
      "id": "c50500000-0005-0005-0005-000000000003",
      "name": "Switch Update Type",
      "type": "n8n-nodes-base.switch",
      "typeVersion": 3.2,
      "position": [
        680,
        400
      ]
    },
    {
      "parameters": {
        "method": "POST",
        "url": "=https://api.telegram.org/bot{{ $env.TELEGRAM_BOT_TOKEN }}/answerCallbackQuery",
        "sendBody": true,
        "bodyParameters": {
          "parameters": [
            {
              "name": "callback_query_id",
              "value": "={{ $json.callback_query_id }}"
            }
          ]
        },
        "options": {}
      },
      "id": "c50500000-0005-0005-0005-000000000004",
      "name": "Answer Callback Query",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        900,
        300
      ],
      "onError": "continueRegularOutput"
    },
    {
      "parameters": {
        "rules": {
          "values": [
            {
              "conditions": {
                "options": {
                  "caseSensitive": true,
                  "typeValidation": "strict"
                },
                "conditions": [
                  {
                    "leftValue": "={{ $('Route Update').item.json.action }}",
                    "rightValue": "approve",
                    "operator": {
                      "type": "string",
                      "operation": "equals"
                    }
                  }
                ],
                "combinator": "and"
              },
              "renameOutput": true,
              "outputKey": "approve"
            },
            {
              "conditions": {
                "options": {
                  "caseSensitive": true,
                  "typeValidation": "strict"
                },
                "conditions": [
                  {
                    "leftValue": "={{ $('Route Update').item.json.action }}",
                    "rightValue": "reject",
                    "operator": {
                      "type": "string",
                      "operation": "equals"
                    }
                  }
                ],
                "combinator": "and"
              },
              "renameOutput": true,
              "outputKey": "reject"
            }
          ]
        },
        "options": {
          "fallbackOutput": "none"
        }
      },
      "id": "c50500000-0005-0005-0005-000000000005",
      "name": "Switch Action",
      "type": "n8n-nodes-base.switch",
      "typeVersion": 3.2,
      "position": [
        1120,
        300
      ]
    },
    {
      "parameters": {
        "operation": "executeQuery",
        "query": "=UPDATE content_assets SET status = 'approved', approved_at = NOW() WHERE id = {{ $('Route Update').item.json.asset_id }} RETURNING id, topic_id",
        "options": {}
      },
      "id": "c50500000-0005-0005-0005-000000000006",
      "name": "Approve Asset",
      "type": "n8n-nodes-base.postgres",
      "typeVersion": 2.5,
      "position": [
        1340,
        200
      ],
      "credentials": {
        "postgres": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "method": "POST",
        "url": "=https://api.telegram.org/bot{{ $env.TELEGRAM_BOT_TOKEN }}/sendMessage",
        "sendBody": true,
        "bodyParameters": {
          "parameters": [
            {
              "name": "chat_id",
              "value": "={{ $('Route Update').item.json.chat_id }}"
            },
            {
              "name": "text",
              "value": "=Asset approved. Scripts will be generated."
            }
          ]
        },
        "options": {}
      },
      "id": "c50500000-0005-0005-0005-000000000007",
      "name": "Send Approve Confirmation",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        1560,
        200
      ],
      "onError": "continueRegularOutput"
    },
    {
      "parameters": {
        "operation": "executeQuery",
        "query": "=INSERT INTO workflow_logs (workflow_name, execution_id, status, input_summary, output_summary) VALUES ('WF-005-asset-approval-gate', '{{ $execution.id }}', 'completed', '{{ JSON.stringify({ asset_id: $('Route Update').item.json.asset_id, action: 'approve' }) }}'::jsonb, '{}'::jsonb)",
        "options": {}
      },
      "id": "c50500000-0005-0005-0005-000000000008",
      "name": "Log Approve",
      "type": "n8n-nodes-base.postgres",
      "typeVersion": 2.5,
      "position": [
        1780,
        200
      ],
      "credentials": {
        "postgres": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "method": "POST",
        "url": "=https://api.telegram.org/bot{{ $env.TELEGRAM_BOT_TOKEN }}/sendMessage",
        "sendBody": true,
        "bodyParameters": {
          "parameters": [
            {
              "name": "chat_id",
              "value": "={{ $('Route Update').item.json.chat_id }}"
            },
            {
              "name": "text",
              "value": "=Reply to this message with the rejection reason for asset #{{ $('Route Update').item.json.asset_id }}:"
            },
            {
              "name": "reply_markup",
              "value": "={{ JSON.stringify({ force_reply: true }) }}"
            }
          ]
        },
        "options": {}
      },
      "id": "c50500000-0005-0005-0005-000000000009",
      "name": "Ask Rejection Reason",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        1340,
        400
      ],
      "onError": "continueRegularOutput"
    },
    {
      "parameters": {
        "operation": "executeQuery",
        "query": "=INSERT INTO workflow_logs (workflow_name, execution_id, status, input_summary, output_summary) VALUES ('WF-005-asset-approval-gate', '{{ $execution.id }}', 'completed', '{{ JSON.stringify({ asset_id: $('Route Update').item.json.asset_id, action: 'reject_prompted' }) }}'::jsonb, '{}'::jsonb)",
        "options": {}
      },
      "id": "c50500000-0005-0005-0005-000000000010",
      "name": "Log Reject Prompt",
      "type": "n8n-nodes-base.postgres",
      "typeVersion": 2.5,
      "position": [
        1560,
        400
      ],
      "credentials": {
        "postgres": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "operation": "executeQuery",
        "query": "=UPDATE content_assets SET status = 'rejected', rejection_reason = '{{ String($('Route Update').item.json.reason || '').replace(/'/g, \"''\") }}' WHERE id = {{ $('Route Update').item.json.asset_id }} RETURNING id",
        "options": {}
      },
      "id": "c50500000-0005-0005-0005-000000000011",
      "name": "Reject Asset",
      "type": "n8n-nodes-base.postgres",
      "typeVersion": 2.5,
      "position": [
        900,
        550
      ],
      "credentials": {
        "postgres": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "method": "POST",
        "url": "=https://api.telegram.org/bot{{ $env.TELEGRAM_BOT_TOKEN }}/sendMessage",
        "sendBody": true,
        "bodyParameters": {
          "parameters": [
            {
              "name": "chat_id",
              "value": "={{ $('Route Update').item.json.chat_id }}"
            },
            {
              "name": "text",
              "value": "=Asset #{{ $('Route Update').item.json.asset_id }} rejected. Reason recorded."
            }
          ]
        },
        "options": {}
      },
      "id": "c50500000-0005-0005-0005-000000000012",
      "name": "Send Reject Confirmation",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        1120,
        550
      ],
      "onError": "continueRegularOutput"
    },
    {
      "parameters": {
        "operation": "executeQuery",
        "query": "=INSERT INTO workflow_logs (workflow_name, execution_id, status, input_summary, output_summary) VALUES ('WF-005-asset-approval-gate', '{{ $execution.id }}', 'completed', '{{ JSON.stringify({ asset_id: $('Route Update').item.json.asset_id, action: 'reject' }) }}'::jsonb, '{}'::jsonb)",
        "options": {}
      },
      "id": "c50500000-0005-0005-0005-000000000013",
      "name": "Log Reject",
      "type": "n8n-nodes-base.postgres",
      "typeVersion": 2.5,
      "position": [
        1340,
        550
      ],
      "credentials": {
        "postgres": {
          "name": "<your credential>"
        }
      }
    }
  ],
  "connections": {
    "Telegram Webhook": {
      "main": [
        [
          {
            "node": "Route Update",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Route Update": {
      "main": [
        [
          {
            "node": "Switch Update Type",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Switch Update Type": {
      "main": [
        [
          {
            "node": "Answer Callback Query",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Reject Asset",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Answer Callback Query": {
      "main": [
        [
          {
            "node": "Switch Action",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Switch Action": {
      "main": [
        [
          {
            "node": "Approve Asset",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Ask Rejection Reason",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Approve Asset": {
      "main": [
        [
          {
            "node": "Send Approve Confirmation",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Send Approve Confirmation": {
      "main": [
        [
          {
            "node": "Log Approve",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Ask Rejection Reason": {
      "main": [
        [
          {
            "node": "Log Reject Prompt",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Reject Asset": {
      "main": [
        [
          {
            "node": "Send Reject Confirmation",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Send Reject Confirmation": {
      "main": [
        [
          {
            "node": "Log Reject",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "settings": {
    "executionOrder": "v1"
  },
  "id": "wf005-asset-approval-gate-000000"
}

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

WF-005-asset-approval-gate. Uses httpRequest, postgres. Webhook trigger; 13 nodes.

Source: https://github.com/navin-labs/content-factory-os/blob/main/n8n/workflows/main/WF-005-asset-approval-gate.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

CMM. Uses httpRequest, postgres, redis. Webhook trigger; 90 nodes.

HTTP Request, Postgres, Redis
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

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

Postgres, Email Send, HTTP Request
Data & Sheets

Post-Prayer. Uses postgres, httpRequest. Webhook trigger; 44 nodes.

Postgres, HTTP Request