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)

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

Cost

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

Need help implementing this?

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