Route new HubSpot leads to a sales territory and ping Slack
When a HubSpot contact lands with a street address, figure out the sales territory, write it back to HubSpot, and post the lead to the right Slack channel.
Build an agent workflow that auto-routes new HubSpot contacts to a sales territory and posts a heads-up in Slack the moment they land.
Trigger: a HubSpot webhook on the contact.creation event. The webhook should hand the agent the new contact's ID so it can fetch the full record.
Integrations:
1. HubSpot (Get Contact, Update Contact).
2. OpenStreetMap Nominatim (Search / Forward Geocode).
3. Slack (Send a Message).
What the agent should do, in order:
Step 1. Read the contact. Pull the contact from HubSpot by ID and read firstname, lastname, email, company, address, city, state, zip, and country.
Step 2. Bail early if there is no usable street address. If only a country is present, or every address field is empty, do not geocode. Clear the territory property by writing an empty string and exit without posting to Slack.
Step 3. Geocode with Nominatim. Build a one-line address string from the available fields and call Search (Forward Geocode) with format=jsonv2 and limit=1. Send a descriptive User-Agent identifying this workflow (Nominatim rejects generic library defaults). Make exactly one Nominatim call per contact, never in parallel: the public instance is capped at one request per second. If you get HTTP 429 or 403, sleep at least 1500ms and retry once before giving up.
Step 4. Decide the territory from the geocoded country_code and state. Use this default matrix (edit to fit the team):
- West Coast: country=us AND state in California, Oregon, Washington. Slack channel #sales-west.
- East Coast: country=us AND state in New York, Massachusetts, New Jersey, Connecticut, Pennsylvania. Slack channel #sales-east.
- US Central: country=us AND everything else. Slack channel #sales-central.
- Canada: country=ca. Slack channel #sales-canada.
- EMEA: country in gb, ie, fr, de, nl, es, it, se, dk, no, fi, pl, pt, be, at, ch. Slack channel #sales-emea.
- APAC: country in jp, au, nz, sg, hk, in, kr, tw, my, th, id, ph, vn. Slack channel #sales-apac.
- LATAM: country in br, mx, ar, cl, co, pe, uy. Slack channel #sales-latam.
- Anything that doesn't match (or geocode returned no country) is treated as unmatched.
Step 5. Write the territory back to HubSpot. Use Update Contact to set a custom single-line-text contact property (default name: territory). On a match, set it to the territory name (e.g. West Coast). On unmatched or skipped-geocode cases, set it to an empty string so reporting cleanly surfaces 'no territory yet'.
Step 6. Post to Slack (only on a confident match). Use Send a Message to post into the territory's channel. Keep it short and scannable:
🆕 New {territory} lead: {first} {last} ({company if present})
📍 {full address}
🗺️ <https://www.google.com/maps/search/?api=1&query={lat},{lon}|View on Google Maps>
đź”— <https://app.hubspot.com/contacts/{portal_id}/contact/{contact_id}|Open in HubSpot>
Build the Google Maps link from the geocoded lat,lon. Format the message in Slack's mrkdwn (single asterisks for bold, <url|text> for links).
Step 7. On unmatched results, do not post to the territory channels. Either skip the post entirely or post a single-line note to a fallback channel like #sales-unrouted naming the country and state we did get, so a human can route it by hand. Make the fallback channel configurable.
Failure modes the agent should handle:
- HubSpot returns 404 (contact already deleted): log and exit cleanly.
- Nominatim returns an empty array or a result with no country: treat as unmatched.
- Slack returns channel_not_found for the territory's channel: fall back to the unrouted channel and mention the expected territory.
- HubSpot Update Contact fails because the territory property doesn't exist: surface a clear setup message ('Create a single-line text contact property named territory in HubSpot, then re-run') and exit.
Configuration knobs the user should be able to edit without touching code:
- The territory matrix (country/state → territory name + Slack channel).
- The HubSpot property name to write back to (default: territory).
- The fallback Slack channel for unrouted leads.
- Whether to include the contact's email and HubSpot owner mention in the Slack post.
What does this prompt do?
- The moment a new contact with a street address lands in HubSpot, look up where they are in the world using free OpenStreetMap data.
- Use that location to decide which sales territory or region the lead belongs to, based on a matrix you control.
- Write the matched territory back onto the HubSpot contact so reporting and routing stay in sync.
- Post a short heads-up in the right territory's Slack channel with the lead's name, address, and a clickable map link.
What do I need to use this?
- A HubSpot account with permission to read and update contact properties.
- A single-line text contact property in HubSpot (the workflow will write the territory name here).
- A Slack workspace with one channel per sales territory, plus a fallback channel for unrouted leads.
- Your team's territory rules (which countries and states map to which channel).
How can I customize it?
- Edit the territory rules: which countries, states, or regions map to which Slack channel.
- Choose what to include in the Slack post (contact name, company, email, owner mention, map link).
- Decide what happens on a vague or international address that doesn't match any rule (clear the field, post to a fallback channel, or both).
- Swap to your own Slack channel naming so it matches your existing #sales workspace setup.
FAQs
Does this work if the contact has no street address?
Does the geocoding cost anything?
Will this work for international leads?
What happens if the address is too vague to place on a map?
Can I run this on contacts that already exist in HubSpot?
Related templates
Every weekday at 10am, an AI voice agent phones your most overdue Xero accounts, logs what each customer promised, and reports back to finance in Slack.
Every couple of hours we find the chats your team never answered, email those visitors a real reply, and hand the sensitive ones to a support lead.
Twice a day we spot the people clicking your pricing and demo pages, create a follow-up task for their owner, and post a ranked recap to Slack.
Build every text campaign in one screen: check who is actually reachable, see a realistic send plan, then watch delivery land row by row.
Score last week's finished live chats against one rubric, let an AI grader draft the notes with quotes, and send coaching straight to the agent.
Every proposal you have ever submitted in one searchable archive, with the closest past answers lined up against each question in a new RFP.
Stop manually routing inbound leads.
Connect HubSpot and Slack once, and Geni geocodes every new contact, tags the territory, and posts the lead to the right channel automatically.