Slack Assistant HubSpot CRM Integration
Context
The HubSpot CRM integration is the most-used data source in the Slack Assistant. It serves two purposes: (1) answer CRM queries about deals, companies, and contacts, and (2) resolve a Slack user’s identity to personalize responses. It uses the HubSpot CRM v3 API with both LIST and SEARCH endpoints.
Guidance
Dual API Pattern: LIST vs SEARCH
The integration uses two HubSpot API patterns depending on context:
LIST endpoints (/crm/v3/objects/{object}) — used by buildHubSpotContext() in the legacy assist flow. Fetches all recent records (50 limit) with prefixed property lists. Good for general queries like “what deals do we have.”
SEARCH endpoints (/crm/v3/objects/{object}/search, POST) — used by searchHubSpot(). Supports free-text query, filterGroups for amount/date constraints, and sorts. Used when the assistant extracts a deal name or company from the user’s message.
Pipeline Stage Resolution
Stage IDs (e.g., 1234567) are meaningless in responses. The integration:
- Fetches all pipelines from
/crm/v3/pipelines/dealson first call - Caches the ID → label map in-memory with 5-minute TTL
- Resolves
dealstageIDs to human labels during formatting
// Cache with TTL
let stageMapCache: Map<string, PipelineStage> | null = null;
let stageMapFetchedAt = 0;
const fetchPipelineStages = async (token: string) => {
if (stageMapCache && Date.now() - stageMapFetchedAt < 300_000) return stageMapCache;
// fetch and populate...
};Amount and Date Filter Parsing
The assistant extracts filters from natural language before calling HubSpot:
Query: "Show deals over $50K from this month"
→ minAmount: 50000
→ dateSince: "2026-04-01"
Amount parsing handles K/multiplier notation ($50K = 50,000), commas ($50,000), and various trigger words (over, above, >, exceeding, at least). Date parsing handles “this month”, “this week”, “last week”, “last month”, and ISO date strings.
Identity Resolution Pipeline
Slack User ID → Slack users.info API → email → HubSpot contacts/search → name + title + companyThe identity string is injected into the LLM system prompt so responses are personalized. This is the only integration that feeds into prompt construction rather than the context block.
Native https Module
HubSpot requests use Node’s https module (not fetch). This is a legacy choice from when the module was first written — https gives more control over timeouts and connection pooling. New integrations should use fetch for consistency with the rest of the codebase.
Formatting: Deals Get Special Treatment
Deals get richer formatting than contacts or companies:
- Human-readable stage labels
- Dollar-amount formatting with
toLocaleString() - Pipeline value summary: “50 records (35 open, total pipeline $12,500,000)”
- Amount → stage display:
• Deal Name — $50,000 (Closed Won)
Why This Matters
HubSpot is the most expensive API to call (pipelines + 3 object types per query). The LIST pattern fetches all records without filtering — the LLM is responsible for finding relevant results from the returned set. This is intentional: filtering at search time would miss context the LLM might need, and the 50-record limit keeps responses fast enough.
When to Apply
- Any assistant that needs CRM data (deals, contacts, companies)
- Identity-aware personalization in chat interfaces
- Systems where pipeline stage IDs need human-readable resolution
Examples
Filtered Deal Search
const result = await searchHubSpot({
accessToken: config.hubspotAccessToken,
object: 'deals',
query: 'Acme Corp',
minAmount: 50000,
dateSince: '2026-04-01',
limit: 50,
sorts: ['-createdate'],
});
// POST /crm/v3/objects/deals/search
// Body: { query: "Acme Corp", filterGroups: [{ filters: [
// { propertyName: "amount", operator: "GTE", value: "50000" },
// { propertyName: "createdate", operator: "GTE", value: "2026-04-01" }
// ]}]}Related
apps/slack-apps/brainforge-assistant/src/hubspot.tsapps/slack-apps/brainforge-assistant/src/assistant.ts(identity resolution flow)apps/slack-apps/brainforge-assistant/src/config.ts(env var loading)docs/solutions/architecture-patterns/slack-assistant-v2-hybrid-ai-pipeline-2026-04-28.md