Back to Projects
AI IntegrationWorkflowGoAWSCRM
March 2025

AI CRM / Sales Workflow Engine

Event-driven workflow engine that enriches sales data with AI summaries and automatically writes back to HubSpot.

10k+ users99.9% uptime
GoAWSPostgreSQLRedisSQSHubSpot APIOpenAIECS Fargate

AI CRM / Sales Workflow Engine

What this solves

Sales and customer data was coming in from multiple places — forms, emails, transcripts, chat, product events, and HubSpot webhooks — but the CRM was always behind. Reps were wasting time cleaning records, writing summaries, and deciding who to follow up with. The goal was to build a backend workflow engine that ingested those events, enriched them with AI, and wrote useful outputs back into HubSpot automatically.

Stack

  • Go
  • AWS
  • PostgreSQL
  • Redis
  • SQS or Kafka
  • HubSpot API
  • OpenAI or Anthropic
  • ECS Fargate
  • CloudWatch

High-level architecture

flowchart LR
    SRC[Forms / Emails / Transcripts / Product Events / HubSpot Webhooks] --> API[Go API]
    API --> PG[(PostgreSQL)]
    API --> REDIS[Redis]
    API --> Q[Queue]

    Q --> NORM[Normaliser Worker]
    NORM --> PG
    NORM --> Q

    Q --> AI[AI Enrichment Worker]
    AI --> LLM[LLM Provider]
    AI --> PG
    AI --> Q

    Q --> CRM[HubSpot Writeback Worker]
    CRM --> HUB[HubSpot API]
    CRM --> PG

    ADMIN[Admin UI] --> API

How it worked

  1. An event arrived from a form, transcript, email, product action, or HubSpot webhook
  2. The backend stored the raw event first
  3. A worker normalised it into a common internal format
  4. An AI worker generated:
    • summary
    • intent / lead quality
    • next action
    • follow-up draft
  5. A writeback worker updated HubSpot with notes, tasks, or property changes
  6. Everything was logged for replay, audit, and debugging

Main flow

flowchart TD
    A[Incoming Event] --> B[Store Raw Payload]
    B --> C[Deduplicate]
    C --> D[Normalise Event]
    D --> E[AI Enrichment]
    E --> F[Generate Summary / Score / Follow-up]
    F --> G[Write Back to HubSpot]
    G --> H[Store Audit + Result]

Core services

api-service

  • receives inbound events
  • authenticates internal users
  • exposes admin and replay endpoints

normaliser-worker

  • maps raw payloads into a stable internal model
  • links event to contact, company, or deal

enrichment-worker

  • builds prompts
  • calls the LLM
  • stores summaries, scores, and follow-up drafts

hubspot-writeback-worker

  • creates notes, tasks, and property updates in HubSpot
  • handles retries and idempotency

Data model

Table Purpose
raw_events Original payloads
normalised_events Clean internal event model
crm_entities Contact / company / deal mappings
enrichment_outputs AI summary, score, next step
crm_actions Planned HubSpot updates
crm_action_results Writeback success/failure
audit_logs Replay and operator history

Key decisions

  • raw events were always stored first
  • AI never wrote directly to HubSpot
  • every writeback was idempotent
  • low-confidence or broken events could be reviewed manually
  • prompt inputs included CRM context, not just raw text

Example output

For a sales call transcript, the system might generate:

  • short summary
  • buyer intent: high
  • objections: security, budget
  • recommended next action
  • follow-up email draft
  • lead score change

Small code example

func (w *EnrichmentWorker) Handle(ctx context.Context, eventID string) error {
    event, err := w.Events.GetByID(ctx, eventID)
    if err != nil {
        return err
    }

    prompt := w.Prompts.BuildSalesPrompt(event)

    result, err := w.LLM.Generate(ctx, prompt)
    if err != nil {
        return err
    }

    if err := w.Enrichments.Store(ctx, eventID, result.Text); err != nil {
        return err
    }

    return w.Queue.PublishCRMWriteback(ctx, eventID)
}