Swirls

SWIRLS_

  • How it works
  • Pricing

56 matches

OverviewDeliver client operations10Win and grow accounts8Resolve customer issues6Create and distribute content9Run people and operations5Review money and agreements3Monitor systems and data9Compose dependable work6

56 matches

OverviewDeliver client operations10Win and grow accounts8Resolve customer issues6Create and distribute content9Run people and operations5Review money and agreements3Monitor systems and data9Compose dependable work6
← Sales & MarketingFormView on GitHub

Sales Call Summarizer

Summarizes sales call transcripts and extracts deal signals.

ai

Source

/**
 * Summarizes sales call transcripts and extracts deal signals.
 */

webhook call_transcript {
  label: "Call Transcript"
  schema: @json {
    {
      "type": "object",
      "required": ["rep_name", "prospect_company", "transcript"],
      "properties": {
        "rep_name": { "type": "string" },
        "prospect_company": { "type": "string" },
        "transcript": { "type": "string" },
        "call_duration_minutes": { "type": "number" }
      }
    }
  }
}

workflow summarize_call {
  label: "Summarize Sales Call"

  root {
    type: code
    label: "Extract transcript"
    code: @ts { return context.nodes.root.input }
    outputSchema: @json {
      {
        "type": "object",
        "properties": {
          "rep_name": { "type": "string" },
          "prospect_company": { "type": "string" },
          "transcript": { "type": "string" },
          "call_duration_minutes": { "type": "number" }
        }
      }
    }
  }

  node analyze {
    type: ai
    label: "Analyze call"
    kind: object
    model: "google/gemini-2.5-flash"
    prompt: @ts {
      const call = context.nodes.root.output
      return "Analyze this sales call transcript.\n\nRep: " + call.rep_name + "\nProspect: " + call.prospect_company + "\nDuration: " + (call.call_duration_minutes || "unknown") + " minutes\n\nTranscript:\n" + call.transcript
    }
    schema: @json {
      {
        "type": "object",
        "required": ["summary", "deal_stage", "next_steps", "sentiment", "deal_probability"],
        "properties": {
          "summary": { "type": "string" },
          "deal_stage": { "type": "string", "enum": ["discovery", "demo", "proposal", "negotiation", "closed_won", "closed_lost"] },
          "buying_signals": { "type": "array", "items": { "type": "string" } },
          "objections": { "type": "array", "items": { "type": "string" } },
          "next_steps": { "type": "array", "items": { "type": "string" } },
          "sentiment": { "type": "string", "enum": ["positive", "neutral", "negative"] },
          "deal_probability": { "type": "number", "minimum": 0, "maximum": 100 }
        }
      }
    }
  }

  node result {
    type: code
    label: "Format result"
    code: @ts {
      const call = context.nodes.root.output
      const analysis = context.nodes.analyze.output
      return {
        rep: call.rep_name,
        company: call.prospect_company,
        summary: analysis.summary,
        stage: analysis.deal_stage,
        probability: analysis.deal_probability,
        sentiment: analysis.sentiment,
        next_steps: analysis.next_steps
      }
    }
  }

  flow {
    root -> analyze
    analyze -> result
  }
}

stream call_summaries {
  label: "Call summaries"
  workflow: summarize_call
  version: v1

  versions: {
    v1 {
      schema: @json {
        {
          "type": "object",
          "required": ["rep", "company", "summary", "stage", "probability", "sentiment"],
          "properties": {
            "rep": { "type": "string" },
            "company": { "type": "string" },
            "summary": { "type": "string" },
            "stage": { "type": "string" },
            "probability": { "type": "number" },
            "sentiment": { "type": "string" },
            "next_steps": { "type": "array", "items": { "type": "string" } }
          }
        }
      }

      condition: @ts { return context.output.result != null }

      prepare: @ts { return context.output.result }
    }
  }
}

trigger on_transcript {
  webhook:call_transcript -> summarize_call
  enabled: true
}

Flow

Trigger to workflow

call_transcriptwebhook
summarize_call
Press enter or space to select a node. You can then use the arrow keys to move the node around. Press delete to remove it and escape to cancel.
Press enter or space to select an edge. You can then press delete to remove it or escape to cancel.

Workflow nodes

CODE
Code Node
Extract transcript
AI
AI Node
Analyze call
CODE
Code Node
Format result
Press enter or space to select a node. You can then use the arrow keys to move the node around. Press delete to remove it and escape to cancel.
Press enter or space to select an edge. You can then press delete to remove it or escape to cancel.