Skip to main content

Scenario

Sales reps mention competitor names in opportunity notes and custom fields, but that intelligence never reaches marketing. This job queries a custom “Competitor” field on Opportunities, aggregates which competitors appear most in active and lost deals, then feeds competitor names plus deal context into Mave Agent. The output is AI-generated competitive battle cards.

Architecture

Code

import os, requests
from collections import Counter

SF   = os.environ["SALESFORCE_INSTANCE"]
SF_T = os.environ["SALESFORCE_ACCESS_TOKEN"]
MV_K = os.environ["MAVERA_API_KEY"]
SF_H = {"Authorization": f"Bearer {SF_T}"}

opps = requests.get(
    f"https://{SF}/services/data/v66.0/query", headers=SF_H,
    params={"q": "SELECT Name, StageName, Amount, Competitor__c, Description FROM Opportunity WHERE Competitor__c != null ORDER BY CloseDate DESC LIMIT 100"},
).json()["records"]

comp_deals = {}
for opp in opps:
    comp = (opp.get("Competitor__c") or "").strip()
    if comp:
        comp_deals.setdefault(comp, []).append(opp)

for comp_name, deals in sorted(comp_deals.items(), key=lambda x: -len(x[1]))[:5]:
    won  = [d for d in deals if d["StageName"] == "Closed Won"]
    lost = [d for d in deals if d["StageName"] == "Closed Lost"]
    deal_ctx = "\n".join(f"- {d['Name']} ({d['StageName']}): {(d.get('Description') or '')[:120]}" for d in deals[:10])

    prompt = f"""Generate a competitive battle card for {comp_name}.

CRM DATA: {len(deals)} mentions | Won: {len(won)} | Lost: {len(lost)}

DEAL CONTEXT
{deal_ctx}

Produce: 1) Overview 2) Their strengths 3) Their weaknesses (where we win) 4) Common objections 5) Killer questions for reps 6) Landmine questions to watch 7) Why customers switch to us"""

    card = requests.post(
        "https://app.mavera.io/api/v1/mave/chat",
        headers={"Authorization": f"Bearer {MV_K}", "Content-Type": "application/json"},
        json={"message": prompt},
    ).json()

    win_rate = f"{len(won)}/{len(won)+len(lost)}" if (won or lost) else "N/A"
    print(f"\n{'='*50}")
    print(f"BATTLE CARD: {comp_name} | Mentions: {len(deals)} | Win rate: {win_rate}")
    print(f"{'='*50}")
    print(card.get("content", "")[:800])

Example Output

==================================================
BATTLE CARD: CompetitorX | Mentions: 23 | Win rate: 14/19
==================================================

### Overview
Series C startup ($45M raised) positioning as "all-in-one revenue platform."
Strong in SMB, weaker in enterprise.

### Their Strengths
- Lower entry price ($99/seat vs our $149/seat)
- Faster self-serve onboarding
- Strong Slack community and developer advocacy

### Where We Win
- No SSO/SCIM below Enterprise tier — dealbreaker for InfoSec
- Dashboard-only reporting; no API export for BI tools
- No dedicated CSM below $50K ACV

### Killer Questions
- "How important is SSO to your security team?"
- "Do you need to pipe data into your existing BI stack?"

### Why Customers Switch
Compliance gaps (SOC 2, SSO) and reporting limitations that
surface 3-6 months after purchase.

Sources: 3
Competitor__c is a common custom field. If your org uses a different name, run GET /services/data/v66.0/sobjects/Opportunity/describe to discover your schema.

Salesforce Overview

Back to all 8 Salesforce jobs

Customer Success Interview Prep

Next: QBR prep from Account health and Cases