Request discount approval in Slack for HubSpot deals using n8n

high complexityCost: $0-24/moRecommended

Prerequisites

Prerequisites
  • n8n instance (cloud or self-hosted)
  • HubSpot private app token with crm.objects.deals.read and crm.objects.deals.write scopes
  • Slack app with Bot Token (chat:write, chat:write.public scopes)
  • A custom HubSpot deal property for discount percentage (e.g., discount_percent, number type)
  • A custom HubSpot deal property for approval status (e.g., discount_approval, dropdown: Pending, Approved, Denied)

Why n8n?

n8n is the only visual automation tool that supports true interactive Slack approvals out of the box. The "Send and Wait for Approval" operation pauses the workflow until the manager clicks Approve or Deny — no separate webhook scenario, no custom code. The workflow literally waits (consuming zero credits while paused) and resumes with the manager's decision.

Self-hosted n8n is completely free with unlimited executions. Cloud plans start at $24/mo. If your discount approval volume is high (10+ per day), self-hosted n8n saves significantly compared to Zapier's per-task pricing. The trade-off is initial setup: Docker or npm install adds 15 minutes to your first deployment.

How it works

  • HubSpot Trigger node fires when the discount_percent property changes on any deal via webhook
  • HTTP Request node fetches the full deal record (name, amount, discount, owner)
  • IF node checks whether the discount exceeds your threshold (e.g., 15%)
  • Slack "Send and Wait" node posts an interactive message with Approve/Deny buttons and pauses the workflow
  • IF node routes the response — Approved or Denied — to the corresponding HubSpot update
  • HTTP Request node writes the approval decision back to the deal's discount_approval property
  • Slack node notifies the rep of the decision

Step 1: Trigger on discount change

Add a HubSpot Trigger node:

  • Event: Deal Property Changed
  • Property: discount_percent

This fires whenever a rep enters or updates the discount percentage on a deal.

Step 2: Fetch deal details

Add an HTTP Request node to get the full deal:

  • Method: GET
  • URL: https://api.hubapi.com/crm/v3/objects/deals/{{ $json.objectId }}
  • Query params: properties=dealname,amount,discount_percent,hubspot_owner_id,dealstage

Step 3: Check if discount exceeds threshold

Add an IF node:

  • Condition: {{ parseFloat($json.properties.discount_percent || '0') }} greater than 15

Discounts of 15% or less are auto-approved. Only higher discounts need manager approval.

Step 4: Send interactive Slack message

n8n's Slack node supports a Send and Wait for Response operation. This sends a message with buttons and pauses the workflow until someone clicks:

  • Resource: Message
  • Operation: Send and Wait for Approval
  • Channel: #deal-desk (or DM the manager)
  • Message:
🏷️ *Discount Approval Needed*
 
*Deal:* {{ $json.properties.dealname }}
*Amount:* ${{ parseFloat($json.properties.amount).toLocaleString() }}
*Discount:* {{ $json.properties.discount_percent }}%
*Rep:* Owner ID {{ $json.properties.hubspot_owner_id }}
 
Approve or deny this discount request.

The node automatically adds Approve/Deny buttons and pauses execution until clicked.

n8n's Send and Wait

This is one of n8n's most powerful features. The workflow literally pauses (no credits consumed while waiting) and resumes when the manager clicks a button in Slack. The response is available as $json.response.

Step 5: Update HubSpot based on response

Add an IF node after the Slack wait:

  • If Approved: Update the deal's discount_approval property to "Approved" via HubSpot HTTP Request
  • If Denied: Update to "Denied" and optionally clear the discount_percent field

Add an HTTP Request node for each branch:

  • Method: PATCH
  • URL: https://api.hubapi.com/crm/v3/objects/deals/{{ $json.dealId }}
  • Body: {"properties": {"discount_approval": "Approved"}} (or "Denied")

Step 6: Notify the rep

Add a final Slack node to DM the rep with the decision:

{{ $json.approved ? '✅' : '❌' }} Your discount request for *{{ $json.dealName }}* was *{{ $json.approved ? 'approved' : 'denied' }}*.

Step 7: Add timeout handling

In the "Send and Wait" node settings, set a timeout (e.g., 24 hours). If no response within 24 hours:

  • Send a reminder to the manager
  • Or auto-escalate to the VP

Troubleshooting

Common questions

Does n8n consume credits while waiting for the manager's response?

No. The Send and Wait node pauses execution entirely. You're only billed for the initial trigger and the resumption when the manager clicks a button. A 24-hour wait costs nothing.

Can I route approvals to different managers based on discount size?

Yes. Add IF nodes before the Slack step to route by discount percentage — e.g., discounts over 25% go to the VP, 15-25% go to the direct manager. Each branch can target a different Slack channel or DM.

What happens if the HubSpot trigger fires on every deal edit?

The trigger fires when the discount_percent property specifically changes, not on all deal edits. However, if a rep updates the discount to the same value, it will still fire. The IF node in Step 3 handles this by only proceeding when the discount exceeds your threshold.

How do I test without creating real deals?

Create a test deal in HubSpot with a discount above your threshold. n8n's "Test Workflow" button lets you run the flow manually and inspect the output at each node. Use a test Slack channel to avoid spamming your real deal-desk channel.

Cost

  • n8n Cloud: 1 execution per approval request. The "waiting" period doesn't consume resources.
  • Self-hosted: Free.

Looking to scale your AI operations?

We build and optimize automation systems for mid-market businesses. Let's discuss the right approach for your team.