{
  "name": "MEDDPICC Demo \u2014 Manual Trigger \u2192 Claude Extraction",
  "nodes": [
    {
      "id": "sticky-trigger",
      "name": "TRIGGER + TEST DATA",
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        -40,
        60
      ],
      "parameters": {
        "content": "## 1. Trigger + Dummy Data\nManual trigger with a realistic Gong call transcript.\nIn production this would be a Gong webhook + SF API calls.",
        "width": 560,
        "height": 180,
        "color": 4
      }
    },
    {
      "id": "sticky-llm",
      "name": "LLM EXTRACTION",
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        560,
        60
      ],
      "parameters": {
        "content": "## 2. Claude MEDDPICC Extraction\nSonnet extracts signals with evidence quotes,\nconfidence scores, and field mapping.",
        "width": 560,
        "height": 180,
        "color": 7
      }
    },
    {
      "id": "sticky-output",
      "name": "OUTPUT & REVIEW",
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        1160,
        60
      ],
      "parameters": {
        "content": "## 3. Output\nFiltered proposals formatted for AE review.\nIn production: upsert to SF + Slack notification.",
        "width": 560,
        "height": 180,
        "color": 3
      }
    },
    {
      "id": "manual-trigger",
      "name": "Start Demo",
      "type": "n8n-nodes-base.manualTrigger",
      "typeVersion": 1,
      "position": [
        0,
        300
      ],
      "parameters": {}
    },
    {
      "id": "dummy-transcript",
      "name": "Dummy Gong Call Transcript",
      "type": "n8n-nodes-base.set",
      "typeVersion": 3.4,
      "position": [
        220,
        300
      ],
      "parameters": {
        "assignments": {
          "assignments": [
            {
              "id": "t1",
              "name": "callId",
              "value": "demo-call-98421",
              "type": "string"
            },
            {
              "id": "t2",
              "name": "gongUrl",
              "value": "https://app.gong.io/call?id=demo-call-98421",
              "type": "string"
            },
            {
              "id": "t3",
              "name": "callDate",
              "value": "2026-04-16",
              "type": "string"
            },
            {
              "id": "t4",
              "name": "duration",
              "value": "1920",
              "type": "string"
            },
            {
              "id": "t5",
              "name": "participants",
              "value": "Alex Rivera (AE, Internal), James Chen (VP Operations, External), Lisa Park (CFO, External), David Okafor (IT Director, External)",
              "type": "string"
            },
            {
              "id": "t6",
              "name": "transcript",
              "value": "[0:00] Alex Rivera (AE): Thanks for making time today, James. I know you've got Lisa and David joining as well \u2014 really appreciate having the full team here.\n\n[0:15] James Chen (VP Ops): Absolutely, Alex. We've been dealing with this warehouse throughput issue for months and after your last demo, I wanted to loop in Lisa and David to see if this is something we should seriously pursue.\n\n[0:32] Alex Rivera: Great to hear. Maybe we can start with what's driving the urgency right now?\n\n[0:40] James Chen: Sure. So our current fulfillment system \u2014 we're on SAP EWM \u2014 is bottlenecking at about 2,200 orders per day. Our target is 3,500 by Q4 to support the new retail partnerships we signed. We did some internal analysis and estimated that every week we're under target is costing us roughly $180,000 in delayed revenue and penalty fees. Over the year that's close to $9.4 million in exposure.\n\n[1:15] Alex Rivera: That's significant. And you mentioned penalty fees \u2014 are those contractual with the retail partners?\n\n[1:22] James Chen: Yes. The Nordstrom and Target contracts both have SLA clauses around fulfillment windows. We've already been hit with two penalty notices totaling $340,000 last quarter.\n\n[1:38] Lisa Park (CFO): And that's exactly why I'm here. James and I have been discussing the budget implications. We've allocated up to $850,000 for this initiative, but I need to see a clear ROI before I approve anything over $500K. Any spend above $500K needs my sign-off and a board-level summary.\n\n[2:05] Alex Rivera: Understood, Lisa. What does the approval process look like from your side?\n\n[2:12] Lisa Park: Below $500K, James can approve with my acknowledgment. Above that, I sign off, and then our General Counsel Rebecca Torres needs to review the MSA. Legal review typically takes 3 to 4 weeks \u2014 Rebecca runs a tight ship but she's thorough. After legal, procurement does a final vendor check which is about a week.\n\n[2:40] David Okafor (IT Director): I should add from the technical side \u2014 whatever we pick needs to integrate with our SAP EWM stack and our Snowflake data warehouse. We also need SOC 2 Type II certification. That's non-negotiable for our compliance team. And I'd strongly prefer an API-first architecture because we're planning to build a real-time dashboard on top of the data.\n\n[3:10] Alex Rivera: All of those are supported. We have a certified SAP EWM connector, native Snowflake integration, and we completed SOC 2 Type II last year. David, if I send you our integration spec sheet, would that help you evaluate?\n\n[3:28] David Okafor: Definitely. That would actually be the deciding factor for me. If the integration is clean, I'm fully on board.\n\n[3:38] James Chen: I want to be transparent \u2014 we're also evaluating K\u00f6rber and Manhattan Associates. K\u00f6rber gave us a proposal last month, but their implementation timeline was 9 months which is way too long. Manhattan is still in early conversations. And honestly, there's a faction internally that thinks we should just hire more warehouse staff and stick with what we have.\n\n[4:05] Alex Rivera: I appreciate the transparency. What would make us the clear winner in your evaluation?\n\n[4:12] James Chen: Speed to value. If you can show me a 90-day implementation plan that gets us to 3,000 orders per day within the first quarter, that would be huge. The other thing is we need white-glove onboarding \u2014 our warehouse managers are not technical, so change management support matters.\n\n[4:35] Lisa Park: From my side, it's the ROI model. Show me payback within 8 months and I'll champion this at the board level.\n\n[4:45] James Chen: Actually, Lisa's being modest \u2014 she's already been pushing for this internally. She presented the business case to our CEO last week and got preliminary buy-in. Lisa's really the one driving this forward.\n\n[5:00] Alex Rivera: That's great to know. And David, any concerns from IT?\n\n[5:05] David Okafor: My main pain point is our current system requires 15 hours per week of manual data reconciliation between SAP and our reporting tools. If your platform can automate that, you'll have my full support.\n\n[5:22] James Chen: So in terms of next steps, we'd like to do a technical proof of concept in the next 2 weeks. David will lead that from our side. If the POC goes well, we'll move to contract negotiation. Lisa mentioned the legal timeline. Ideally we'd want to have a signed contract by end of July so we can start implementation in August and hit our Q4 targets.\n\n[5:50] Alex Rivera: That timeline works perfectly. I'll get the POC environment set up this week and send David the integration docs. James, I'll also prepare a 90-day value realization plan and an ROI model for Lisa. Sound good?\n\n[6:05] James Chen: Sounds great. One more thing \u2014 please don't mention our Nordstrom and Target SLAs in any external materials. That's confidential.\n\n[6:15] Alex Rivera: Of course, that stays between us. Thanks everyone, really productive call.",
              "type": "string"
            }
          ]
        },
        "options": {}
      }
    },
    {
      "id": "dummy-sf-data",
      "name": "Dummy SF Opportunity Data",
      "type": "n8n-nodes-base.set",
      "typeVersion": 3.4,
      "position": [
        220,
        480
      ],
      "parameters": {
        "assignments": {
          "assignments": [
            {
              "id": "s1",
              "name": "sfOpportunityId",
              "value": "006DEMO000001",
              "type": "string"
            },
            {
              "id": "s2",
              "name": "oppName",
              "value": "Nexora Logistics \u2014 Warehouse Optimization Platform",
              "type": "string"
            },
            {
              "id": "s3",
              "name": "accountName",
              "value": "Nexora Logistics Inc.",
              "type": "string"
            },
            {
              "id": "s4",
              "name": "industry",
              "value": "Supply Chain / Logistics",
              "type": "string"
            },
            {
              "id": "s5",
              "name": "employees",
              "value": "1200",
              "type": "string"
            },
            {
              "id": "s6",
              "name": "stage",
              "value": "Discovery",
              "type": "string"
            },
            {
              "id": "s7",
              "name": "amount",
              "value": "650000",
              "type": "string"
            },
            {
              "id": "s8",
              "name": "closeDate",
              "value": "2026-07-31",
              "type": "string"
            },
            {
              "id": "s9",
              "name": "currentMeddpicc",
              "value": "{ \"Metrics\": null, \"Economic_Buyer\": null, \"Decision_Criteria\": \"Must integrate with existing systems\", \"Decision_Process\": null, \"Paper_Process\": null, \"Identify_Pain\": \"Warehouse throughput issues\", \"Champion\": null, \"Competition\": null }",
              "type": "string"
            }
          ]
        },
        "options": {}
      }
    },
    {
      "id": "merge-demo-data",
      "name": "Merge Transcript + SF Data",
      "type": "n8n-nodes-base.merge",
      "typeVersion": 3,
      "position": [
        460,
        380
      ],
      "parameters": {
        "mode": "combine",
        "combinationMode": "mergeByPosition",
        "options": {}
      }
    },
    {
      "id": "build-prompt",
      "name": "Build MEDDPICC Extraction Prompt",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        680,
        380
      ],
      "parameters": {
        "jsCode": "const item = $input.first().json;\n\nconst currentMeddpicc = JSON.parse(item.currentMeddpicc || '{}');\n\nconst systemPrompt = `You are a MEDDPICC qualification analyst. Given a sales call transcript, the current MEDDPICC fields on the Opportunity, and the opportunity context, extract proposed updates to MEDDPICC fields.\n\nRULES:\n- Only propose an update if the transcript contains direct evidence.\n- Every proposal MUST cite an exact verbatim quote from the transcript and its timestamp.\n- Confidence (0-1) reflects: quote clarity, speaker authority, specificity.\n- If the current value is already correct or more specific, do NOT propose an update.\n- Never invent names, titles, or dollar amounts not present in the transcript.\n- For Competition, only list vendors explicitly named or strongly implied.\n- If no signals found for a field, omit it entirely.\n\nMEDDPICC FIELDS:\n- MEDDPICC_Metrics__c: Quantified business impact (revenue, cost savings, efficiency gains with specific numbers)\n- MEDDPICC_Economic_Buyer__c: Person with budget authority (name + title + budget details)\n- MEDDPICC_Decision_Criteria__c: Criteria for vendor selection (technical, business, compliance requirements)\n- MEDDPICC_Decision_Process__c: Steps, timeline, approvers in buying process\n- MEDDPICC_Paper_Process__c: Legal, procurement, contracting steps and timeline\n- MEDDPICC_Identify_Pain__c: Core pain driving the purchase (with quantified impact)\n- MEDDPICC_Champion__c: Internal advocate (name + title + evidence of advocacy)\n- MEDDPICC_Competition__c: Competing vendors or 'do nothing' scenario\n\nOUTPUT: Return ONLY valid JSON matching this schema, no additional text:\n{\n  \"proposals\": [\n    {\n      \"field\": \"<SF field API name>\",\n      \"proposed_value\": \"<extracted value>\",\n      \"current_value\": \"<current value or null>\",\n      \"confidence\": <0.0-1.0>,\n      \"evidence_quote\": \"<verbatim quote from transcript>\",\n      \"evidence_timestamp\": \"<MM:SS format>\",\n      \"reasoning\": \"<one sentence explaining why this is a valid signal>\"\n    }\n  ]\n}\n\nIf no MEDDPICC signals are found, return: { \"proposals\": [] }`;\n\nconst userPrompt = `OPPORTUNITY CONTEXT:\n- Account: ${item.accountName} (${item.industry}, ${item.employees} employees)\n- Opportunity: ${item.oppName}\n- Stage: ${item.stage}\n- Amount: $${item.amount}\n- Close Date: ${item.closeDate}\n- Participants on call: ${item.participants}\n\nCURRENT MEDDPICC VALUES:\n${JSON.stringify(currentMeddpicc, null, 2)}\n\nTRANSCRIPT:\n${item.transcript}`;\n\nreturn [{\n  json: {\n    systemPrompt,\n    userPrompt,\n    sfOpportunityId: item.sfOpportunityId,\n    callId: item.callId,\n    gongUrl: item.gongUrl,\n    oppName: item.oppName,\n    accountName: item.accountName,\n    currentMeddpicc\n  }\n}];"
      }
    },
    {
      "id": "call-claude",
      "name": "Claude Sonnet: Extract MEDDPICC",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        900,
        380
      ],
      "parameters": {
        "method": "POST",
        "url": "https://api.anthropic.com/v1/messages",
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "x-api-key",
              "value": "={{ $env.ANTHROPIC_API_KEY }}"
            },
            {
              "name": "anthropic-version",
              "value": "2023-06-01"
            },
            {
              "name": "Content-Type",
              "value": "application/json"
            }
          ]
        },
        "sendBody": true,
        "contentType": "json",
        "body": "={{ JSON.stringify({ model: 'claude-sonnet-4-5-20250514', max_tokens: 4096, system: [{ type: 'text', text: $json.systemPrompt, cache_control: { type: 'ephemeral' } }], messages: [{ role: 'user', content: $json.userPrompt }] }) }}",
        "options": {
          "timeout": 120000
        }
      },
      "onError": "continueErrorOutput"
    },
    {
      "id": "parse-proposals",
      "name": "Parse & Filter Proposals",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        1120,
        380
      ],
      "parameters": {
        "jsCode": "const item = $input.first().json;\nconst prevData = $('Build MEDDPICC Extraction Prompt').first().json;\n\nlet proposals = [];\ntry {\n  const content = item.content?.[0]?.text || '';\n  // Try direct parse first\n  const parsed = JSON.parse(content);\n  proposals = parsed.proposals || [];\n} catch (e) {\n  // Extract JSON from mixed response\n  const text = item.content?.[0]?.text || '';\n  const match = text.match(/\\{[\\s\\S]*\\}/);\n  if (match) {\n    try { proposals = JSON.parse(match[0]).proposals || []; } catch (e2) { proposals = []; }\n  }\n}\n\n// Filter: confidence >= 0.6\nconst filtered = proposals.filter(p => p.confidence >= 0.6);\n\nreturn [{\n  json: {\n    proposalCount: filtered.length,\n    proposals: filtered,\n    sfOpportunityId: prevData.sfOpportunityId,\n    callId: prevData.callId,\n    gongUrl: prevData.gongUrl,\n    oppName: prevData.oppName,\n    accountName: prevData.accountName,\n    tokenUsage: {\n      input_tokens: item.usage?.input_tokens,\n      output_tokens: item.usage?.output_tokens,\n      cache_read: item.usage?.cache_read_input_tokens || 0,\n      cache_creation: item.usage?.cache_creation_input_tokens || 0\n    }\n  }\n}];"
      }
    },
    {
      "id": "split-proposals",
      "name": "Split Into Individual Proposals",
      "type": "n8n-nodes-base.splitOut",
      "typeVersion": 1,
      "position": [
        1340,
        380
      ],
      "parameters": {
        "fieldToSplitOut": "proposals",
        "options": {}
      }
    },
    {
      "id": "format-output",
      "name": "Format Proposal for Display",
      "type": "n8n-nodes-base.set",
      "typeVersion": 3.4,
      "position": [
        1560,
        380
      ],
      "parameters": {
        "assignments": {
          "assignments": [
            {
              "id": "f1",
              "name": "MEDDPICC_Field",
              "value": "={{ $json.field.replace('MEDDPICC_', '').replace('__c', '').replace('_', ' ') }}",
              "type": "string"
            },
            {
              "id": "f2",
              "name": "Proposed_Value",
              "value": "={{ $json.proposed_value }}",
              "type": "string"
            },
            {
              "id": "f3",
              "name": "Current_Value",
              "value": "={{ $json.current_value || '(empty)' }}",
              "type": "string"
            },
            {
              "id": "f4",
              "name": "Confidence",
              "value": "={{ Math.round($json.confidence * 100) + '%' }}",
              "type": "string"
            },
            {
              "id": "f5",
              "name": "Evidence_Quote",
              "value": "={{ $json.evidence_quote }}",
              "type": "string"
            },
            {
              "id": "f6",
              "name": "Timestamp",
              "value": "={{ $json.evidence_timestamp }}",
              "type": "string"
            },
            {
              "id": "f7",
              "name": "Reasoning",
              "value": "={{ $json.reasoning }}",
              "type": "string"
            },
            {
              "id": "f8",
              "name": "SF_Field_API",
              "value": "={{ $json.field }}",
              "type": "string"
            }
          ]
        },
        "options": {}
      }
    }
  ],
  "connections": {
    "Start Demo": {
      "main": [
        [
          {
            "node": "Dummy Gong Call Transcript",
            "type": "main",
            "index": 0
          },
          {
            "node": "Dummy SF Opportunity Data",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Dummy Gong Call Transcript": {
      "main": [
        [
          {
            "node": "Merge Transcript + SF Data",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Dummy SF Opportunity Data": {
      "main": [
        [
          {
            "node": "Merge Transcript + SF Data",
            "type": "main",
            "index": 1
          }
        ]
      ]
    },
    "Merge Transcript + SF Data": {
      "main": [
        [
          {
            "node": "Build MEDDPICC Extraction Prompt",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Build MEDDPICC Extraction Prompt": {
      "main": [
        [
          {
            "node": "Claude Sonnet: Extract MEDDPICC",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Claude Sonnet: Extract MEDDPICC": {
      "main": [
        [
          {
            "node": "Parse & Filter Proposals",
            "type": "main",
            "index": 0
          }
        ],
        []
      ]
    },
    "Parse & Filter Proposals": {
      "main": [
        [
          {
            "node": "Split Into Individual Proposals",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Split Into Individual Proposals": {
      "main": [
        [
          {
            "node": "Format Proposal for Display",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "settings": {
    "executionOrder": "v1"
  },
  "staticData": null,
  "tags": [
    {
      "name": "skaled"
    },
    {
      "name": "meddpicc"
    },
    {
      "name": "demo"
    }
  ]
}