

HubSpot + AI Presentation: Playbook per l'Automazione delle Sales Deck (2026)
Per i team di vendita su HubSpot nel 2026, il ROI dell'automazione delle sales deck per singolo account è misurabile: risparmio medio di tempo per AE di 2–4 ore a settimana, incremento del 12–18% nella progressione da meeting a meeting e riduzione del 30-60% della varianza nella preparazione delle deck in tutto il team. Il workflow HubSpot + 2Slides del 2026 genera una sales deck completamente personalizzata per qualsiasi account utilizzando i dati già presenti in HubSpot (azienda, fase della trattativa, interesse per il prodotto, contatto champion, alternative competitive) tramite tre percorsi di integrazione: HubSpot Workflow → Webhook → 2Slides API; HubSpot App Card personalizzata con pulsante Genera Deck; batch giornaliero programmato per tutte le trattative in una fase specifica. Questo playbook include l'esatto payload del webhook, il template di prompt che trasforma i campi HubSpot in contenuto per la deck e il flusso API 2Slides (generate → jobs/:id → download) utilizzato oggi da veri team RevOps in produzione.
Se gestisci le revenue operations per un team di vendita su HubSpot, conosci già il problema: ogni AE chiede a marketing o sales enablement "solo una piccola modifica" alla deck prima della prossima call. Moltiplica per quaranta rappresentanti e trecento trattative in corso, e avrai un lavoro a tempo pieno per incollare template di Google Slides ai dati CRM in stile Salesforce — tranne che sei su HubSpot, che non ha un equivalente nativo del modulo Document Generation di Salesforce.
Playbook: Connettere HubSpot all'API V1 di 2Slides
Questo playbook ti mostra come collegare HubSpot all'API V1 di 2Slides in modo che qualsiasi deal in qualsiasi fase possa generare un deck di vendita personalizzato, coerente con il brand e pronto per il canale — senza che un essere umano tocchi un template. I pattern qui sotto sono utilizzati dai team RevOps in aziende B2B SaaS, cybersecurity e AI enterprise per aumentare i valori medi dei contratti da $40K a $400K+.
Perché le Presentazioni Generate da HubSpot Vincono
Il business case per automatizzare le presentazioni di vendita da HubSpot deriva da tre leve misurabili.
Leva 1: Tempo recuperato degli AE. L'osservazione interna tra i clienti 2Slides con implementazioni da 20+ postazioni mostra che gli account executive dedicano 2–4 ore a settimana alla personalizzazione delle presentazioni — riscrivendo le slide introduttive, aggiornando i loghi, inserendo i punti deboli del concorrente, sostituendo i calcolatori di ROI. Con un costo complessivo per AE di $160K/anno, ciò equivale a $6.400–$12.800 per AE all'anno in puro lavoro sulle slide. Per un team di vendita di 40 persone, si parla di $256K/anno in capacità recuperata, secondo stime conservative.
Leva 2: Conversione da meeting a meeting. Le presentazioni generate da dati CRM in tempo reale — cioè la fascia di ricavi effettiva dell'azienda, il titolo reale del champion, il concorrente effettivamente elencato nel record del deal — convertono le prenotazioni del meeting successivo con un tasso superiore del 12–18% rispetto alle presentazioni template generiche. Il motivo è semplice: la specificità segnala preparazione, e la preparazione segnala che un venditore merita un secondo incontro.
Leva 3: Riduzione della varianza. Gli AE del quartile superiore creano presentazioni eccellenti. Quelli del quartile inferiore creano presentazioni mediocri che disperdono pipeline. L'automazione solleva il livello più basso. Nei dati di coorte, i team RevOps che utilizzano la generazione di presentazioni attivata da HubSpot riportano una riduzione del 30–60% nella varianza di qualità delle presentazioni, misurata tramite punteggi QA dei manager.
Pattern Comune a Tutti e Tre i Casi
Il pattern comune a tutti e tre: il deck non è il prodotto, la preparazione è il prodotto. Automatizzare la preparazione è la mossa ad alto impatto che i RevOps possono fare nel 2026. Per un approfondimento sul lato enablement, consulta la nostra guida su come creare sales enablement deck con AI.
L'Architettura HubSpot + 2Slides del 2026
Prima di approfondire ogni metodo, ecco l'architettura che ogni implementazione segue:
HubSpot CRM (deal, aziende, contatti) │ ├── Trigger (workflow, app card, cron) │ ▼ Transformer Layer (serverless fn / Zapier / Make) │ - Costruisce il prompt dai campi CRM │ - Chiama l'API V1 di 2Slides │ ▼ API V1 di 2Slides ├── POST /api/v1/slides/generate (restituisce jobId) ├── GET /api/v1/jobs/{id} (polling fino a status = success) └── GET /api/v1/slides/download-slides-pages-voices (URL degli asset) │ ▼ Delivery (ritorno a HubSpot deal come nota, email all'AE, Slack DM)
L'API di 2Slides è stateless per job, asincrona e misurata a crediti. Ti autentichi con un header di chiave API
x-api-key: sk-2slides-...jobId/api/v1/jobs/{id}pendingprocessingsuccessMetodo 1: Workflow HubSpot → Webhook → API 2Slides
Questo è il percorso di integrazione più comune. Un Workflow HubSpot monitora il cambio di fase nella pipeline delle trattative e attiva un webhook verso una funzione serverless che comunica con l'API 2Slides.
Step 1: Creare il Workflow HubSpot
In HubSpot, vai su Automazione → Workflow → Crea workflow → Basato su trattativa. Imposta il trigger di iscrizione:
- Filtro: è una qualsiasi tra
Fase trattativa,Discovery Complete,Demo ScheduledProposal Sent - Re-iscrizione: abilitata al cambio di fase
Aggiungi un'azione Invia webhook:
- Metodo:
POST - URL:
https://your-revops-fn.vercel.app/api/hubspot/generate-deck - Includi i gruppi di proprietà ,
dealeassociated companyprimary contact
Step 2: Funzione di Trasformazione
Distribuisci questo su Vercel, Cloudflare Workers o AWS Lambda. La funzione riceve il webhook HubSpot, compone il prompt 2Slides e avvia la generazione.
// /api/hubspot/generate-deck.ts export async function POST(req: Request) { const payload = await req.json() const deal = payload.properties const company = payload.associations?.company?.properties ?? {} const contact = payload.associations?.contact?.properties ?? {} const prompt = buildDeckPrompt({ deal, company, contact }) ```typescript const generateRes = await fetch('https://2slides.com/api/v1/slides/generate', { method: 'POST', headers: { 'Content-Type': 'application/json', 'x-api-key': process.env.TWOSLIDES_API_KEY!, }, body: JSON.stringify({ prompt, slide_count: 12, language: 'en', aspect_ratio: '16:9', theme_id: process.env.BRAND_THEME_ID, // il tuo tema brand bloccato metadata: { hubspot_deal_id: deal.hs_object_id, account: company.name, }, }), }) const { jobId } = await generateRes.json() // Persisti l'associazione jobId -> deal per ricerca successiva await kv.set(`deal:${deal.hs_object_id}:job`, jobId, { ex: 86400 }) return Response.json({ ok: true, jobId }) }
Passaggio 3: Polling e Consegna
Una seconda funzione (chiamata da un Vercel Cron ogni 90 secondi, o dal rientro ritardato del workflow HubSpot) effettua il polling di
/api/v1/jobs/{id}const jobRes = await fetch(`https://2slides.com/api/v1/jobs/${jobId}`, { headers: { 'x-api-key': process.env.TWOSLIDES_API_KEY! }, }) const job = await jobRes.json() if (job.status === 'success') { const assets = await fetch( `https://2slides.com/api/v1/slides/download-slides-pages-voices?jobId=${jobId}`, { headers: { 'x-api-key': process.env.TWOSLIDES_API_KEY! } } ).then(r => r.json()) ```javascript await hubspotClient.crm.objects.notes.basicApi.create({ properties: { hs_note_body: `Nuova presentazione pronta: ${assets.pptx_url}`, hs_timestamp: Date.now(), }, associations: [{ to: { id: deal.hs_object_id }, types: [{ category: 'HUBSPOT_DEFINED', typeId: 214 }] }], }) }
Si tratta dello stesso schema che utilizziamo nella nostra automazione dei report settimanali con Zapier — una chiamata di generazione, un polling, una consegna — solo che qui è collegato tramite HubSpot invece di Zapier.
Metodo 2: Scheda App HubSpot con Pulsante Genera Presentazione
Il Metodo 1 è automatico. Il Metodo 2 è su richiesta: l'AE apre una trattativa in HubSpot, vede una scheda personalizzata nella barra laterale destra, clicca su Genera Presentazione e la presentazione arriva nella sua casella di posta due minuti dopo.
Questo utilizza una UI Extension di HubSpot (parte della piattaforma Developer Projects).
Codice UI Extension
// src/app/extensions/DealDeckCard.tsx import { hubspot, Button, Flex, Text, Alert, LoadingSpinner, } from '@hubspot/ui-extensions' import { useState } from 'react' hubspot.extend(({ context, runServerlessFunction }) => ( <DeckCard context={context} runServerless={runServerlessFunction} /> )) function DeckCard({ context, runServerless }) { const [state, setState] = useState<'idle' | 'working' | 'done' | 'error'>('idle') const [deckUrl, setDeckUrl] = useState<string | null>(null) async function onClick() { setState('working') const { response } = await runServerless({ name: 'generateDeck', parameters: { dealId: context.crm.objectId }, }) if (response.deckUrl) { setDeckUrl(response.deckUrl) setState('done') } else { setState('error') } } ```markdown return ( <Flex direction="column" gap="sm"> <Text>Genera un deck di vendita personalizzato per questo account utilizzando 2Slides.</Text> {state === 'idle' && <Button onClick={onClick}>Genera Deck</Button>} {state === 'working' && <LoadingSpinner label="Creazione deck (90–120s)" />} {state === 'done' && deckUrl && ( <Alert title="Deck pronto"> <a href={deckUrl} target="_blank" rel="noreferrer">Apri deck</a> </Alert> )} {state === 'error' && <Alert variant="danger">Generazione fallita — controlla i log RevOps.</Alert>} </Flex> ) }
La Funzione Serverless Companion
La funzione serverless richiamata sopra (
generateDeck/api/v1/slides/generate/api/v1/jobs/{id}// src/app/app.functions/generateDeck.js exports.main = async (context) => { const { dealId } = context.parameters const deal = await hubspotFetchDeal(dealId) const prompt = buildDeckPrompt(deal)
const gen = await fetch('https://2slides.com/api/v1/slides/generate', { method: 'POST', headers: { 'Content-Type': 'application/json', 'x-api-key': process.env.TWOSLIDES_API_KEY }, body: JSON.stringify({ prompt, slide_count: 12, theme_id: process.env.BRAND_THEME_ID }), }).then(r => r.json()) // Polling fino a 3 minuti for (let i = 0; i < 36; i++) { await new Promise(r => setTimeout(r, 5000)) const job = await fetch(`https://2slides.com/api/v1/jobs/${gen.jobId}`, { headers: { 'x-api-key': process.env.TWOSLIDES_API_KEY }, }).then(r => r.json()) if (job.status === 'success') { return { deckUrl: job.result?.pptx_url } } if (job.status === 'failed') throw new Error(job.error || 'generation failed') } throw new Error('timeout') }
Questo schema — oggetto CRM → scheda estensione → chiamata API → risultato inline — è lo stesso approccio che i team di marketing utilizzano quando scalano la produzione di contenuti; vedi come i team di marketing eseguono presentazioni AI su larga scala.
Metodo 3: Generazione Batch Programmata
Non ogni presentazione deve essere generata su richiesta. Per revisioni di pipeline prevedibili — ogni lunedì mattina, ogni revisione trimestrale del business, ogni aggiornamento della fase MEDDPICC — un batch programmato tramite cron è più economico e affidabile rispetto ai webhook in tempo reale.
Il Pattern
Esegui un job notturno che interroga HubSpot per ogni deal in una fase target, genera una nuova presentazione per ciascuno e invia all'AE un digest mattutino via email.
// /api/cron/nightly-deck-refresh.ts export const runtime = 'nodejs' export const maxDuration = 300 export async function GET(req: Request) { // Vercel Cron protegge con CRON_SECRET if (req.headers.get('authorization') !== `Bearer ${process.env.CRON_SECRET}`) { return new Response('Unauthorized', { status: 401 }) } const deals = await hubspotClient.crm.deals.searchApi.doSearch({ filterGroups: [{ filters: [ { propertyName: 'dealstage', operator: 'EQ', value: 'proposal_sent' }, { propertyName: 'hs_lastmodifieddate', operator: 'GT', value: String(Date.now() - 86400000) }, ], }], properties: ['dealname', 'amount', 'competitor', 'product_interest', 'champion_title'], limit: 100, }) ```typescript const jobs = await Promise.all(deals.results.map(async (deal) => { const prompt = buildDeckPrompt(deal) const res = await fetch('https://2slides.com/api/v1/slides/generate', { method: 'POST', headers: { 'Content-Type': 'application/json', 'x-api-key': process.env.TWOSLIDES_API_KEY! }, body: JSON.stringify({ prompt, slide_count: 10, theme_id: process.env.BRAND_THEME_ID }), }).then(r => r.json()) return { dealId: deal.id, jobId: res.jobId, owner: deal.properties.hubspot_owner_id } })) await enqueueDeliveryJobs(jobs) // SQS / Upstash QStash / Trigger.dev return Response.json({ enqueued: jobs.length }) }
Pianifica in
vercel.json{ "crons": [ { "path": "/api/cron/nightly-deck-refresh", "schedule": "0 6 * * 1-5" } ] }
Alle sei del mattino, nei giorni feriali. L'account executive apre l'email, la presentazione è pronta.
Il Template di Prompt che Converte i Campi CRM in Contenuti per Presentazioni
Il singolo fattore più determinante della qualità di una presentazione è il prompt. I prompt efficaci codificano ciò che un Senior AE direbbe a un nuovo assunto: "quando l'azienda è X, con un champion nel ruolo Y, focalizzato sul risultato Z, costruisci la presentazione così." Template pronto all'uso:
function buildDeckPrompt({ deal, company, contact }: Ctx) { return ` Genera una presentazione commerciale di 10-12 slide per una valutazione software B2B. CONTESTO ACCOUNT - Azienda: ${company.name} - Settore: ${company.industry ?? 'non specificato'} - Fascia di fatturato annuo: ${company.annualrevenue ?? 'non specificato'} - Dipendenti: ${company.numberofemployees ?? 'non specificato'} - Sito web: ${company.domain} CONTESTO DEAL - Fase del deal: ${deal.dealstage} - Importo del deal: $${deal.amount} - Interesse per il prodotto: ${deal.product_interest} - Caso d'uso prioritario: ${deal.primary_use_case} - Shortlist competitor: ${deal.competitors /* separati da virgola */} - Timeline di valutazione: ${deal.close_date} CONTESTO CHAMPION - Nome: ${contact.firstname} ${contact.lastname} - Titolo: ${contact.jobtitle} - Priorità dichiarate: ${contact.priorities} # STRUTTURA DELLA PRESENTAZIONE 1. Slide titolo — "${company.name} × <Il Tuo Brand>: ${deal.primary_use_case}" 2. Il loro mondo oggi — 3 punti elenco, specifici per ${company.industry} 3. Il costo dell'immobilismo — quantificare usando la fascia ${company.annualrevenue} 4. Il nostro approccio — 3 pilastri allineati a ${deal.primary_use_case} 5. Prova — 2 case study da ${company.industry} (o settori adiacenti) 6. Differenziazione vs ${deal.competitors} — vedi sezione battlecard sotto 7. Piano di implementazione — 30/60/90 calibrato su ${deal.close_date} 8. Riepilogo commerciale — range ancorato a $${deal.amount} 9. Rischi e mitigazioni 10. Prossimi passi — allineati a ${deal.dealstage} TONO - Adeguarsi al pubblico: ${contact.jobtitle} - Formale se il titolo include VP, SVP, Chief, Director; conversazionale altrimenti. - Ogni slide: un'idea, un grafico o una citazione in evidenza, niente muri di testo. `.trim() }
Mantieni il template sotto controllo di versione. Quando il marketing aggiorna il framework di messaging, modifichi un solo file e il prossimo cron run lo recepisce.
Gestione delle Alternative Competitive
Il campo
deal.competitorsconst BATTLECARDS: Record<string, string> = { 'Competitor A': ` Competitor A si posiziona su <la loro affermazione>. Controbattuta: <il tuo punto di forza> + <tagline di 3 parole>. Domanda-tranello da inserire: "Quando è stato pubblicato il loro ultimo audit di sicurezza?" `, 'Competitor B': ` Competitor B parte con <il loro angolo>. Controbattuta: <la tua controbattuta> — fai riferimento al case study di <nome cliente> che è passato a voi. Tranello: "Chiedi dei loro limiti per postazione oltre i 500 utenti." `, } function battlecardSection(competitorsCsv: string) { const names = competitorsCsv.split(',').map(s => s.trim()).filter(Boolean) if (!names.length) return '' return ` BATTLECARD COMPETITIVE ${names.map(n => BATTLECARDS[n] ?? '').filter(Boolean).join('\n')} Usa questo per popolare la slide di Differenziazione. Non nominare mai il competitor più di due volte. `.trim() }
Aggiungi il risultato di
battlecardSection(deal.competitors)Conservare le schede di battaglia in una tabella del database anziché codificarle quando ne hai più di dieci. Il tuo Head of Product Marketing può modificarle senza creare una PR.
Quando il tuo stack di schede di battaglia per i competitor cresce oltre una manciata, codificarle nel codice diventa un collo di bottiglia. Ogni aggiornamento richiede l'intervento di uno sviluppatore, una pull request e un ciclo di deployment. Spostare le schede di battaglia in una tabella del database trasforma gli aggiornamenti dei contenuti in un'operazione self-service per il tuo team di product marketing.
Perché spostare le schede di battaglia in un database
Autonomia del marketing
Il tuo Head of Product Marketing dovrebbe essere in grado di aggiornare i punti di forza, le obiezioni e i messaggi dei competitor nel momento in cui il panorama competitivo cambia. Una tabella del database con un semplice pannello di amministrazione elimina la dipendenza dall'engineering per gli aggiornamenti dei contenuti.
Controllo delle versioni e audit trail
Le tabelle del database forniscono timestamp, informazioni sull'autore delle modifiche e la possibilità di ripristinare le versioni precedenti. Sai chi ha modificato cosa e quando, cosa difficile da tracciare quando le schede di battaglia sono sparse nel codice.
Ricerca e filtraggio
Quando hai 20+ competitor, le query del database ti permettono di filtrare per settore, categoria di prodotto o regione. I rappresentanti di vendita possono trovare rapidamente la scheda rilevante senza scorrere array codificati.
Integrazione multicanale
Una singola fonte di verità del database alimenta schede di battaglia su Slack, nel tuo CRM, nelle guide di onboarding delle vendite e negli strumenti di enablement. Codificare i contenuti in un repository li blocca in un unico contesto.
Schema di esempio della tabella
CREATE TABLE battlecards ( id SERIAL PRIMARY KEY, competitor_name VARCHAR(255) NOT NULL, slug VARCHAR(255) UNIQUE NOT NULL, tagline TEXT, strengths JSONB, weaknesses JSONB, objections JSONB, win_themes JSONB, pricing_notes TEXT, active BOOLEAN DEFAULT true, updated_by VARCHAR(255), updated_at TIMESTAMP DEFAULT NOW() );
Il campo
JSONBslug/battlecards/competitor-nameactiveCostruire un pannello di amministrazione leggero
Non hai bisogno di un CMS completo. Un semplice pannello CRUD consente al tuo team di marketing di:
- Aggiungere un nuovo competitor con un form
- Modificare bullet point in un editor di testo
- Attivare/disattivare la visibilità della scheda di battaglia
- Vedere chi ha apportato l'ultima modifica e quando
Framework come Django Admin, Rails Admin o Retool possono generare interfacce CRUD dalla struttura della tabella con poche righe di configurazione. Se preferisci costruire su misura, una pila React + API REST offre pieno controllo.
Quando codificare è ancora accettabile
Se hai meno di dieci competitor e le tue schede di battaglia cambiano raramente, i file Markdown versionati in Git funzionano bene. Ottieni revisioni gratuite, cronologia delle modifiche e la possibilità di rivedere gli aggiornamenti nei commenti delle PR. Ma una volta che superi i dieci, o quando i non-sviluppatori hanno bisogno di modificare frequentemente i contenuti, un database diventa più efficiente.
Migrazione da schede codificate
Inizia esportando le schede di battaglia esistenti in JSON o CSV. Scrivi uno script di migrazione che popola la tabella del database dagli export. Aggiungi un pannello di amministrazione di base, quindi concedi l'accesso al product marketing per i test. Una volta che confermano di poter gestire gli aggiornamenti, rimuovi le schede codificate e punta l'app al database.
Le schede di battaglia sono contenuti operativi, non codice. Trattarle come dati consente al team appropriato di possederle senza coinvolgere l'engineering in ogni modifica.
Domande Frequenti
Come faccio a impedire a HubSpot di generare deck duplicati ad ogni aggiornamento di proprietà?
Aggiungi una proprietà denominata
last_deck_generated_atlast_deck_generated_atQuanto costa in crediti 2Slides?
Ogni chiamata
/api/v1/slides/generatePosso generare il deck in una lingua diversa dall'inglese?
Sì. Passa
language: 'de'language: 'ja'language: 'es'/api/v1/slides/generateCome faccio a fissare il brand visivo in modo che ogni deck appaia identico?
Usa un
theme_idBRAND_THEME_IDCosa succede se il job di generazione fallisce?
Interroga
/api/v1/jobs/{id}statusfailederrorIl Punto Chiave
HubSpot non sta cercando di essere Salesforce, e va bene così — la sua semplicità è la funzionalità. Ma la semplicità significa anche che non include automazione nativa dei documenti. Il gap è una funzionalità, non un bug, perché significa che il team RevOps che collega HubSpot a un'API di presentazioni AI controlla la superficie più preziosa del proprio stack di strumenti di vendita: il deck che arriva davanti all'acquirente.
I tre metodi sopra elencati — webhook del workflow, pulsante della scheda app, batch programmato — coprono l'intera gamma di trigger di generazione di cui un team di vendita ha bisogno. Scegli quello che corrisponde alla fase del tuo funnel. Le fasi di Discovery e Demo quasi sempre richiedono l'on-demand (la scheda app). Le fasi di Proposta e Negoziazione beneficiano maggiormente dell'automazione al cambio di fase (il webhook del workflow). Le revisioni della pipeline e la preparazione dei QBR sono batch (il cron). Esegui tutti e tre e ogni deal nella pipeline avrà un deck fresco e fedele al CRM a portata di mano, ogni giorno.
Automatizza le tue presentazioni di vendita da HubSpot — ottieni una chiave API di 2Slides e collegala al tuo prossimo workflow in meno di un giorno.
About 2Slides
Create stunning AI-powered presentations in seconds. Transform your ideas into professional slides with 2slides AI Agent.
Try For Free