Skip to content
SlashClone
Made by@revopslab

Lead routing rules

@revopslab/lead-routing-rules

Design, test, and apply lead routing rules outside your CRM. Write ordered rules in a JSON file (existing-account match, partner, segment, region, junk filters), prove them with rule tests, then route a leads CSV with weighted round robin, out-of-office skips, and a fallback queue. Works with HubSpot, Salesforce, or any CSV.

SkillRevOpsv1.0.0 (latest)Tested
Activity
New: be the first to try it
  1. 1---
  2. 2name: lead-routing-rules
  3. 3description: Design, test, and apply lead routing rules. Turns a plain-English routing policy (existing customers to their account owner, partner leads to the partner team, enterprise vs mid-market vs SMB, regions, junk and personal-email filters) into an ordered rules file with tests, then routes a leads CSV with weighted round robin, out-of-office skips, and a fallback queue. Use when the user says "set up lead routing", "who should get these leads", "test our routing rules", "route this list from the trade show", "why did this lead go to the wrong rep", or "rebalance round robin". Works with exports from HubSpot, Salesforce, or any CSV.
  4. 4license: MIT
  5. 5---
  6. 6
  7. 7# Lead routing rules
  8. 8
  9. 9Routing logic usually lives in a CRM workflow nobody can read. This kit keeps it in one small JSON file with tests, so you can see every rule, prove it works on sample leads, and route a list the same way every time.
  10. 11## When to use
  11. 13- Designing or changing routing (new segment, new rep, new region).
  12. 14- Routing a one-off list (event, webinar, purchased list) before import.
  13. 15- Debugging: "why did this lead go to X?" Run the lead through the rules and read the `rule_id` and `reason`.
  14. 16- Not for scoring leads, and not for writing into the CRM. Import the routed CSV yourself, or rebuild the tested rules in your CRM's workflow tool.
  15. 18## Inputs
  16. 20- **Rules** at `data/routing-rules.json` (start from the kit's `examples/routing-rules.json`).
  17. 21- **Leads** CSV at `data/leads.csv`. Any columns; rules refer to them by name, lowercased with spaces as underscores (`Lead Source` becomes `lead_source`).
  18. 22- **Accounts** CSV (optional) with a domain or website column and an owner column, for existing-account matching.
  19. 24## Rules file
  20. 26- `rules`: checked in order, the **first match wins**. Each has `id`, `when` (all must match) and or `when_any` (one must match), `assign` (`owner`, `pool`, or `queue`), and a `reason`.
  21. 27- Ops: `==`, `!=`, `in`, `not_in`, `>`, `>=`, `<`, `<=`, `contains`, `starts_with`, `ends_with`, `exists`, `missing`. Text compares ignore case. Numbers use the first number in the cell, so `201-500` employees counts as 201.
  22. 28- Built-in fields: `email_domain`, `is_free_email` (common personal email providers), `company_domain`.
  23. 29- `pools`: round robin groups with optional `weights` (`"Rep C": 2` gets twice the leads). `out_of_office`: people to skip.
  24. 30- Existing accounts are checked before all rules when `--accounts` is given (skip with `"account_match": false`). Personal emails never match an account.
  25. 31- `fallback`: where unmatched leads go. Default queue `unassigned`.
  26. 32- `tests`: sample leads with `expect_rule` and optional `expect_to` (owner, pool name, or queue).
  27. 34## Steps
  28. 361. **Design.** Ask for the routing policy in plain words, then write the rules file. Put specific rules (junk, existing accounts, partners) before broad ones (segments). Write one test per rule plus edge cases (missing size, personal email, employee ranges).
  29. 372. **Test.**
  30. 39 ```bash
  31. 40 node scripts/route.mjs data/routing-rules.json --check
  32. 41 ```
  33. 43 Every test must pass. If one fails, show expected vs actual and fix the rule, not the test, unless the user agrees the test was wrong.
  34. 453. **Route.**
  35. 47 ```bash
  36. 48 node scripts/route.mjs data/routing-rules.json data/leads.csv --accounts data/accounts.csv --state data/rr-state.json --out out --name routed
  37. 49 ```
  38. 51 Routing refuses to run while any rule test fails. `--state` keeps the round robin position between runs so the next list continues where this one stopped.
  39. 534. **Report** from `out/routed-summary.json`: leads per rule, per person, how many hit the fallback, and `unused_rules`. A rule nobody hit may be dead or ordered too late.
  40. 55## Output to the user
  41. 57```markdown
  42. 58Routed 10 leads. 5/5 rule tests pass.
  43. 60| Rule | Leads |
  44. 61| --- | ---: |
  45. 62| existing-account | 2 |
  46. 63| enterprise | 2 |
  47. 64| smb | 2 |
  48. 65| fallback | 1 |
  49. 67Per person: Rep A 2, Rep F 2, Rep B 1, Rep C 1, Rep E 1, Partner Manager 1.
  50. 681 lead hit the fallback (UnknownCo: no employee count). Unused rule: spam-or-test.
  51. 69File to import: out/routed.csv (adds routed_to, route_type, rule_id, reason).
  52. 70```
  53. 72## Guardrails
  54. 74- Never import or assign in the CRM. The user imports `out/routed.csv`.
  55. 75- Keep a test for every rule you add. Do not delete a failing test to make routing run.
  56. 76- Do not route on protected or sensitive attributes (age, gender, ethnicity, religion, and similar), even if a column exists.
  57. 77- Lead data is personal data. Summarize in chat; do not paste the CSV.