Round-robin route HubSpot leads and notify reps in Slack using Zapier

low complexityCost: $20-50/mo

Prerequisites

Prerequisites
  • Zapier account (Professional plan or higher for Code by Zapier)
  • HubSpot account connected to Zapier via OAuth
  • Slack workspace connected to Zapier
  • A mapping of HubSpot owner IDs to Slack user IDs

Step 1: Set up the HubSpot trigger

Create a new Zap. Choose HubSpot as the trigger:

  • Trigger event: New Contact
  • Additional Properties to Retrieve: firstname, lastname, email, company, jobtitle, hubspot_owner_id
Don't forget additional properties

HubSpot's Zapier trigger returns minimal fields by default. Without adding properties to retrieve, your Slack notification will be blank.

Step 2: Filter out already-assigned contacts

Add a Filter step:

  • Condition: hubspot_owner_id → Does not exist

This prevents re-assigning contacts that were already routed by another workflow or manually assigned.

Step 3: Round-robin with Storage by Zapier

Add a Storage by Zapier step to track the round-robin counter:

  • Action: Get Value
  • Key: round_robin_index
  • Default: 0

Then add a Code by Zapier step to calculate the assignment:

  • Language: JavaScript
  • Input Data:
    • currentIndex -> Value from Storage step
const reps = [
  { name: "Alice", hubspotOwnerId: "12345678", slackUserId: "U01AAAA" },
  { name: "Bob",   hubspotOwnerId: "23456789", slackUserId: "U02BBBB" },
  { name: "Carol", hubspotOwnerId: "34567890", slackUserId: "U03CCCC" },
  { name: "Dave",  hubspotOwnerId: "45678901", slackUserId: "U04DDDD" },
];
 
const index = parseInt(inputData.currentIndex || '0');
const rep = reps[index % reps.length];
const nextIndex = (index + 1) % reps.length;
 
output = [{
  repName: rep.name,
  hubspotOwnerId: rep.hubspotOwnerId,
  slackUserId: rep.slackUserId,
  nextIndex: nextIndex,
}];

Then add another Storage by Zapier step:

  • Action: Set Value
  • Key: round_robin_index
  • Value: {{nextIndex}} from the Code step
Why Storage by Zapier?

Zapier Zaps are stateless -- each run is independent. Storage by Zapier provides a simple key-value store that persists across runs, perfect for tracking which rep is next.

Step 4: Update the contact owner in HubSpot

Add a HubSpot action:

  • Action event: Update Contact
  • Contact: Use the contact ID from the trigger step
  • Contact Owner: {{hubspotOwnerId}} from the Code step

Step 5: Send a Slack DM to the assigned rep

Add a Slack action:

  • Action event: Send Direct Message
  • User: {{slackUserId}} from the Code step
  • Message Text:
🆕 *New Lead Assigned to You*
*{{firstname}} {{lastname}}* — {{jobtitle}} at {{company}}
Email: {{email}}
<https://app.hubspot.com/contacts/YOUR_PORTAL_ID/contact/{{hs_object_id}}|View in HubSpot>

Step 6: Test and publish

  1. Click Test on each step
  2. Verify the HubSpot contact owner was updated
  3. Verify the Slack DM was received by the correct rep
  4. Turn the Zap On

Limitations

  • Polling delay: Zapier polls HubSpot every 1-15 minutes depending on your plan. Not truly instant.
  • Race conditions: If two contacts arrive in the same polling cycle, both Code steps may read the same counter value before either writes back. In practice this is rare and self-corrects on the next assignment.
  • Storage by Zapier counts as a step, so this is a 5-step Zap (trigger + filter + storage read + code + storage write + HubSpot update + Slack = 7 tasks).

Cost

  • Professional plan: $29.99/mo minimum. Each new lead = 7 tasks (one per step).
  • Team plan: $69.99/mo if you need more tasks or faster polling.

Need help implementing this?

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