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

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:

  1. Fetches all pipelines from /crm/v3/pipelines/deals on first call
  2. Caches the ID → label map in-memory with 5-minute TTL
  3. Resolves dealstage IDs 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 + company

The 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

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" }
// ]}]}
  • apps/slack-apps/brainforge-assistant/src/hubspot.ts
  • apps/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