Request discount approval in Slack for HubSpot deals using n8n
Prerequisites
- n8n instance (cloud or self-hosted)
- HubSpot private app token with
crm.objects.deals.readandcrm.objects.deals.writescopes - Slack app with Bot Token (
chat:write,chat:write.publicscopes) - 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 than15
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.
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_approvalproperty to "Approved" via HubSpot HTTP Request - If Denied: Update to "Denied" and optionally clear the
discount_percentfield
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.