Quick overview
This workflow exposes a single webhook that either accepts new approval requests or handles Slack button callbacks, posting interactive Slack Block Kit messages and recording decisions in a PostgreSQL table.
How it works
- Receives a POST request on a webhook endpoint that serves as both the intake API and the Slack interactivity callback URL.
- Validates the Slack request signature and timestamp when the request includes Slack signature headers.
- Routes the request by detecting whether it contains a URL-encoded Slack
payload (callback) or a custom intake body (new request).
- For intake requests, builds a Slack Block Kit approval message with Approve/Reject/Flag buttons and posts it to Slack.
- Stores the request context, Slack channel ID, and message timestamp in PostgreSQL and returns a 200 response with the generated requestId.
- For Slack button callbacks, immediately returns a 200 response to Slack, looks up the request context in PostgreSQL, and merges it with the callback details.
- Updates the original Slack message to replace buttons with a static decision status and writes the decision (approved/rejected/flagged) back to PostgreSQL.
Setup
- Create the approval_requests table in your Postgres or Supabase instance
- Add your Postgres credentials and your Slack Bot Token (ensure the token has the chat:write scope).
- In your n8n environment variables, add your Slack App's Signing Secret as SLACK_SIGNING_SECRET and your target channel as SLACK_CHANNEL_ID.
- Activate the workflow and copy the Production Webhook URL.
- Paste this URL into your Slack App under Interactivity & Shortcuts → Request URL. Use this exact same URL as the target POST endpoint for your upstream systems to submit new approvals.
Requirements
- A Postgres or Supabase database instance.
- A Slack App with Interactive Components enabled and a Bot Token.
Customization
- Modify the "Create Slack Block Message" node to add dynamic fields, amounts, or internal company links to the approval UI.
- Extend the final "Determine Next Action Taken" Switch node to trigger CRM updates, email confirmations, or trigger agentic LLM workflows based on the 'approve', 'reject', or 'flag' outcomes.