SALESFORCE_OPPORTUNITY_CREATE - Criar Oportunidade no Salesforce
O que é este Node?
O SALESFORCE_OPPORTUNITY_CREATE é o node responsável por criar oportunidades de venda no Salesforce CRM, representando negócios em potencial com valor monetário e data de fechamento prevista.
Por que este Node existe?
Oportunidades são o coração do pipeline de vendas. O SALESFORCE_OPPORTUNITY_CREATE existe para:
- Gestão de Pipeline: Rastrear negócios em andamento com valor e probabilidade de fechamento
- Previsão de Receita: Projetar receita futura baseada em oportunidades no funil
- Métricas de Vendas: Acompanhar taxas de conversão, ciclo de vendas e performance
- Automação de Processos: Criar oportunidades automaticamente a partir de conversas qualificadas
Como funciona internamente?
Quando o SALESFORCE_OPPORTUNITY_CREATE é executado, o sistema:
- Recebe os dados: Coleta nome, estágio, data de fechamento e valor da oportunidade
- Processa variáveis: Substitui variáveis do contexto pelos valores reais
- Valida campos obrigatórios: Name, StageName e CloseDate são obrigatórios
- Converte valores numéricos: Amount e Probability são convertidos para float
- Monta payload: Cria objeto com todos os campos
- Autentica no Salesforce: Usa accessToken e instanceUrl
- Faz requisição POST: Envia para
/services/data/v60.0/sobjects/Opportunity - Retorna ID: Salesforce responde com ID da oportunidade criada
- Em caso de erro: Retorna mensagem detalhada
Código interno (salesforce-executor.service.ts:583-607):
private async createOpportunity(
nodeData: FlowNodeData,
credentials: SalesforceCredentials,
context: any,
): Promise<any> {
const { name, stageName, closeDate, amount, accountId, type, probability, description } = nodeData;
const opportunityData: any = {
Name: this.replaceVariables(name, context),
StageName: this.replaceVariables(stageName, context),
CloseDate: this.replaceVariables(closeDate, context),
};
if (amount) opportunityData.Amount = parseFloat(this.replaceVariables(amount, context));
if (accountId) opportunityData.AccountId = this.replaceVariables(accountId, context);
if (type) opportunityData.Type = this.replaceVariables(type, context);
if (probability) opportunityData.Probability = parseFloat(this.replaceVariables(probability, context));
if (description) opportunityData.Description = this.replaceVariables(description, context);
if (nodeData.additionalFields) {
Object.assign(opportunityData, this.processAdditionalFields(nodeData.additionalFields, context));
}
return this.salesforceApiRequest('POST', '/sobjects/Opportunity', credentials, opportunityData);
}
Quando você DEVE usar este Node?
Use SALESFORCE_OPPORTUNITY_CREATE sempre que precisar de registrar uma oportunidade de venda qualificada:
Casos de uso
- Lead qualificado: Após qualificar lead, criar oportunidade com valor estimado
- Proposta comercial: Cliente solicita proposta formal via WhatsApp
- Renovação de contrato: Cliente atual manifesta interesse em renovação ou upgrade
- Venda consultiva: Após discovery via chat, criar oportunidade estruturada
- Cross-sell/Up-sell: Cliente existente demonstra interesse em produtos adicionais
Quando NÃO usar SALESFORCE_OPPORTUNITY_CREATE
- Prospect não qualificado: Use SALESFORCE_LEAD_CREATE primeiro
- Oportunidade já existe: Use SALESFORCE_OPPORTUNITY_UPDATE
- Apenas informação: Use SALESFORCE_CONTACT_CREATE ou SALESFORCE_CASE_CREATE
Parâmetros Detalhados
name (string, obrigatório)
O que é: Nome descritivo da oportunidade. Deve identificar claramente o negócio.
Exemplo: "Empresa XYZ - Software ERP", "João Silva - Plano Enterprise", "{{company}} - {{product}}"
Flow completo para testar:
{
"name": "Teste Salesforce - Criar Oportunidade",
"nodes": [
{
"id": "start_1",
"type": "start",
"position": { "x": 100, "y": 100 },
"data": { "label": "Início" }
},
{
"id": "input_1",
"type": "input",
"position": { "x": 300, "y": 100 },
"data": {
"label": "Nome Oportunidade",
"parameters": {
"message": "Nome da oportunidade:",
"variableName": "opp_name"
}
}
},
{
"id": "salesforce_1",
"type": "salesforce",
"position": { "x": 500, "y": 100 },
"data": {
"label": "Criar Oportunidade",
"parameters": {
"resource": "opportunity",
"operation": "create",
"accessToken": "{{salesforce_token}}",
"instanceUrl": "https://sua-instancia.salesforce.com",
"name": "{{opp_name}}",
"stageName": "Prospecting",
"closeDate": "2025-03-31"
}
}
},
{
"id": "message_1",
"type": "message",
"position": { "x": 700, "y": 100 },
"data": {
"label": "Confirmar",
"parameters": {
"message": "Oportunidade criada! ID: {{salesforce_1.id}}"
}
}
},
{
"id": "end_1",
"type": "end",
"position": { "x": 900, "y": 100 },
"data": { "label": "Fim" }
}
],
"edges": [
{ "source": "start_1", "target": "input_1" },
{ "source": "input_1", "target": "salesforce_1" },
{ "source": "salesforce_1", "target": "message_1" },
{ "source": "message_1", "target": "end_1" }
]
}
Teste: Digite "Teste Negócio Empresa ABC" e a oportunidade será criada.
stageName (string, obrigatório)
O que é: Estágio atual da oportunidade no funil de vendas. Deve ser um valor válido configurado no Salesforce.
Valores comuns: "Prospecting", "Qualification", "Needs Analysis", "Value Proposition", "Id. Decision Makers", "Perception Analysis", "Proposal/Price Quote", "Negotiation/Review", "Closed Won", "Closed Lost"
Exemplo: "Prospecting", "Proposal/Price Quote", "{{stage}}"
closeDate (string, obrigatório)
O que é: Data prevista para fechamento da oportunidade. Formato: YYYY-MM-DD.
Exemplo: "2025-12-31", "2025-03-15", "{{expected_close}}"
Flow completo para testar:
{
"name": "Teste Salesforce - Oportunidade com Data",
"nodes": [
{
"id": "start_1",
"type": "start",
"position": { "x": 100, "y": 100 },
"data": { "label": "Início" }
},
{
"id": "date_1",
"type": "date",
"position": { "x": 300, "y": 100 },
"data": {
"label": "Data Fechamento",
"parameters": {
"message": "Qual a data prevista de fechamento? (DD/MM/AAAA)",
"variableName": "close_date",
"format": "YYYY-MM-DD"
}
}
},
{
"id": "salesforce_1",
"type": "salesforce",
"position": { "x": 500, "y": 100 },
"data": {
"label": "Criar Oportunidade",
"parameters": {
"resource": "opportunity",
"operation": "create",
"accessToken": "{{salesforce_token}}",
"instanceUrl": "https://sua-instancia.salesforce.com",
"name": "Oportunidade Teste Data",
"stageName": "Prospecting",
"closeDate": "{{close_date}}"
}
}
},
{
"id": "message_1",
"type": "message",
"position": { "x": 700, "y": 100 },
"data": {
"label": "Confirmar",
"parameters": {
"message": "Oportunidade criada para fechar em {{close_date}}"
}
}
},
{
"id": "end_1",
"type": "end",
"position": { "x": 900, "y": 100 },
"data": { "label": "Fim" }
}
],
"edges": [
{ "source": "start_1", "target": "date_1" },
{ "source": "date_1", "target": "salesforce_1" },
{ "source": "salesforce_1", "target": "message_1" },
{ "source": "message_1", "target": "end_1" }
]
}
Teste: Digite uma data futura e a oportunidade será criada com esta data de fechamento.
amount (number, opcional mas recomendado)
O que é: Valor monetário estimado da oportunidade. Usado para projeções de receita.
Exemplo: 50000, 120000.50, "{{deal_value}}"
accountId (string, opcional mas recomendado)
O que é: ID da Account (empresa) associada a esta oportunidade.
Exemplo: "0015g00000ABC123", "{{account_id}}"
type (string, opcional)
O que é: Tipo de oportunidade.
Valores comuns: "Existing Customer - Upgrade", "Existing Customer - Replacement", "Existing Customer - Downgrade", "New Customer"
probability (number, opcional)
O que é: Probabilidade de fechamento em percentual (0-100). Geralmente definido automaticamente pelo StageName.
Exemplo: 10, 50, 90, "{{win_probability}}"
description (string, opcional)
O que é: Descrição detalhada da oportunidade, necessidades do cliente, próximos passos.
Exemplo: "Cliente precisa de solução ERP para 50 usuários. Budget aprovado. Decisão em 60 dias."
additionalFields (object, opcional)
O que é: Campos customizados específicos do seu processo de vendas.
Exemplo:
{
"LeadSource": "WhatsApp",
"Next_Step__c": "Enviar proposta comercial",
"Competitor__c": "Concorrente XYZ",
"Decision_Maker__c": "João Silva - CEO"
}
Parâmetros
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
| resource | string | Sim | Deve ser "opportunity" |
| operation | string | Sim | Deve ser "create" |
| accessToken | string | Sim | Token OAuth do Salesforce |
| instanceUrl | string | Sim | URL da instância Salesforce |
| name | string | Sim | Nome da oportunidade |
| stageName | string | Sim | Estágio no funil de vendas |
| closeDate | string | Sim | Data prevista fechamento (YYYY-MM-DD) |
| amount | number | Não | Valor estimado |
| accountId | string | Não | ID da Account associada |
| type | string | Não | Tipo de oportunidade |
| probability | number | Não | Probabilidade de ganho (0-100) |
| description | string | Não | Descrição da oportunidade |
| additionalFields | object | Não | Campos customizados |
Exemplo 1: Oportunidade Completa de Venda
Objetivo: Criar oportunidade com todas informações principais após qualificação
JSON para Importar
{
"name": "Criar Oportunidade Completa - Salesforce",
"nodes": [
{
"id": "start_1",
"type": "start",
"position": { "x": 100, "y": 100 },
"data": { "label": "Início" }
},
{
"id": "message_1",
"type": "message",
"position": { "x": 300, "y": 100 },
"data": {
"label": "Qualificação",
"parameters": {
"message": "Ótimo! Vejo que você tem interesse real. Vamos registrar essa oportunidade no nosso sistema."
}
}
},
{
"id": "input_1",
"type": "input",
"position": { "x": 500, "y": 100 },
"data": {
"label": "Empresa",
"parameters": {
"message": "Nome da sua empresa:",
"variableName": "company"
}
}
},
{
"id": "input_2",
"type": "input",
"position": { "x": 700, "y": 100 },
"data": {
"label": "Produto",
"parameters": {
"message": "Qual solução interessa? (ERP/CRM/BI)",
"variableName": "product"
}
}
},
{
"id": "number_1",
"type": "number",
"position": { "x": 900, "y": 100 },
"data": {
"label": "Valor",
"parameters": {
"message": "Qual é o budget aproximado (em reais)?",
"variableName": "budget"
}
}
},
{
"id": "date_1",
"type": "date",
"position": { "x": 1100, "y": 100 },
"data": {
"label": "Data Decisão",
"parameters": {
"message": "Quando pretendem tomar a decisão? (DD/MM/AAAA)",
"variableName": "decision_date",
"format": "YYYY-MM-DD"
}
}
},
{
"id": "input_3",
"type": "input",
"position": { "x": 1300, "y": 100 },
"data": {
"label": "Necessidade",
"parameters": {
"message": "Resuma em uma frase a principal necessidade:",
"variableName": "need"
}
}
},
{
"id": "salesforce_1",
"type": "salesforce",
"position": { "x": 1500, "y": 100 },
"data": {
"label": "Criar Oportunidade",
"parameters": {
"resource": "opportunity",
"operation": "create",
"accessToken": "{{salesforce_token}}",
"instanceUrl": "https://sua-instancia.salesforce.com",
"name": "{{company}} - {{product}}",
"stageName": "Qualification",
"closeDate": "{{decision_date}}",
"amount": "{{budget}}",
"type": "New Customer",
"probability": 25,
"description": "Necessidade: {{need}}. Contato via WhatsApp.",
"additionalFields": {
"LeadSource": "WhatsApp",
"Product_Interest__c": "{{product}}",
"Next_Step__c": "Agendar reunião de discovery"
}
}
}
},
{
"id": "message_2",
"type": "message",
"position": { "x": 1700, "y": 100 },
"data": {
"label": "Confirmação",
"parameters": {
"message": "Perfeito! Oportunidade registrada. Nossa equipe comercial entrará em contato em até 24h para agendar uma reunião de apresentação."
}
}
},
{
"id": "end_1",
"type": "end",
"position": { "x": 1900, "y": 100 },
"data": { "label": "Fim" }
}
],
"edges": [
{ "source": "start_1", "target": "message_1" },
{ "source": "message_1", "target": "input_1" },
{ "source": "input_1", "target": "input_2" },
{ "source": "input_2", "target": "number_1" },
{ "source": "number_1", "target": "date_1" },
{ "source": "date_1", "target": "input_3" },
{ "source": "input_3", "target": "salesforce_1" },
{ "source": "salesforce_1", "target": "message_2" },
{ "source": "message_2", "target": "end_1" }
]
}
Saída esperada:
Sistema: Ótimo! Vejo que você tem interesse real. Vamos registrar essa oportunidade no nosso sistema.
Sistema: Nome da sua empresa:
Usuário: Tech Solutions LTDA
Sistema: Qual solução interessa? (ERP/CRM/BI)
Usuário: ERP
Sistema: Qual é o budget aproximado (em reais)?
Usuário: 100000
Sistema: Quando pretendem tomar a decisão? (DD/MM/AAAA)
Usuário: 30/06/2025
Sistema: Resuma em uma frase a principal necessidade:
Usuário: Integrar todos os departamentos em uma única plataforma
Sistema: Perfeito! Oportunidade registrada. Nossa equipe comercial entrará em contato em até 24h para agendar uma reunião de apresentação.
Exemplo 2: Renovação de Cliente
Objetivo: Cliente atual solicita renovação de contrato
JSON para Importar
{
"name": "Renovação Cliente - Salesforce Opportunity",
"nodes": [
{
"id": "start_1",
"type": "start",
"position": { "x": 100, "y": 100 },
"data": { "label": "Início" }
},
{
"id": "message_1",
"type": "message",
"position": { "x": 300, "y": 100 },
"data": {
"label": "Identificação",
"parameters": {
"message": "Olá! Vi que você está interessado em renovar o contrato. Vamos registrar isso!"
}
}
},
{
"id": "input_1",
"type": "input",
"position": { "x": 500, "y": 100 },
"data": {
"label": "Empresa",
"parameters": {
"message": "Confirme o nome da empresa:",
"variableName": "company_name"
}
}
},
{
"id": "switch_1",
"type": "switch",
"position": { "x": 700, "y": 100 },
"data": {
"label": "Tipo Renovação",
"parameters": {
"message": "Deseja:\n1 - Renovar no mesmo plano\n2 - Fazer upgrade\n3 - Adicionar mais usuários",
"variableName": "renewal_type",
"cases": [
{ "value": "1", "label": "Mesmo plano" },
{ "value": "2", "label": "Upgrade" },
{ "value": "3", "label": "Mais usuários" }
]
}
}
},
{
"id": "number_1",
"type": "number",
"position": { "x": 900, "y": 100 },
"data": {
"label": "Valor",
"parameters": {
"message": "Valor estimado da renovação:",
"variableName": "renewal_value"
}
}
},
{
"id": "salesforce_1",
"type": "salesforce",
"position": { "x": 1100, "y": 100 },
"data": {
"label": "Criar Oportunidade Renovação",
"parameters": {
"resource": "opportunity",
"operation": "create",
"accessToken": "{{salesforce_token}}",
"instanceUrl": "https://sua-instancia.salesforce.com",
"name": "{{company_name}} - Renovação 2025",
"stageName": "Proposal/Price Quote",
"closeDate": "2025-12-31",
"amount": "{{renewal_value}}",
"type": "Existing Customer - Upgrade",
"probability": 75,
"description": "Cliente solicitou renovação via WhatsApp. Tipo: {{renewal_type}}"
}
}
},
{
"id": "message_2",
"type": "message",
"position": { "x": 1300, "y": 100 },
"data": {
"label": "Confirmação",
"parameters": {
"message": "Oportunidade de renovação criada! Seu gerente de conta entrará em contato para preparar a proposta."
}
}
},
{
"id": "end_1",
"type": "end",
"position": { "x": 1500, "y": 100 },
"data": { "label": "Fim" }
}
],
"edges": [
{ "source": "start_1", "target": "message_1" },
{ "source": "message_1", "target": "input_1" },
{ "source": "input_1", "target": "switch_1" },
{ "source": "switch_1", "target": "number_1" },
{ "source": "number_1", "target": "salesforce_1" },
{ "source": "salesforce_1", "target": "message_2" },
{ "source": "message_2", "target": "end_1" }
]
}
Saída esperada:
Sistema: Olá! Vi que você está interessado em renovar o contrato. Vamos registrar isso!
Sistema: Confirme o nome da empresa:
Usuário: ABC Corporation
Sistema: Deseja:
1 - Renovar no mesmo plano
2 - Fazer upgrade
3 - Adicionar mais usuários
Usuário: 2
Sistema: Valor estimado da renovação:
Usuário: 80000
Sistema: Oportunidade de renovação criada! Seu gerente de conta entrará em contato para preparar a proposta.
Resposta do Node
{
"id": "0065g00000DEF456",
"success": true,
"errors": []
}
Boas Práticas
✅ SIM:
- Sempre associar oportunidade a uma Account (accountId) quando possível
- Definir valor (amount) mesmo que seja estimado
- Usar StageName consistente com seu processo de vendas
- Definir closeDate realista baseada no ciclo de vendas
- Incluir descrição com contexto e próximos passos
- Usar campos customizados para rastrear origem e métricas importantes
- Definir Type corretamente (novo cliente vs cliente existente)
- Salvar ID retornado para atualizações futuras
❌ NÃO:
- Criar oportunidades sem qualificação mínima
- Usar nomes genéricos como "Oportunidade 1"
- Definir closeDate no passado
- Ignorar o amount - crucial para previsão de receita
- Criar duplicatas - verificar existência antes
- Usar estageName incorreto para o momento da venda
- Esquecer de associar à Account
Dicas
💡 Dica 1: Combine com SALESFORCE_TASK_CREATE para criar tarefas automáticas de follow-up quando a oportunidade for criada.
💡 Dica 2: Use CONDITION após criar oportunidade para rotear baseado no valor - oportunidades grandes podem disparar notificação para gestores.
💡 Dica 3: Implemente regra de negócio: se amount > 100.000, definir automaticamente probability mais conservadora e stage inicial de "Qualification".
💡 Dica 4: Use campos customizados para rastrear competitor, decision maker, pain points - informações valiosas para o time de vendas.
💡 Dica 5: Após criar oportunidade, use SALESFORCE_OPPORTUNITY_UPDATE para atualizar conforme a conversa avança e mais informações são coletadas.
Próximos Nodes
→ SALESFORCE_OPPORTUNITY_UPDATE - Atualizar oportunidade existente → SALESFORCE_OPPORTUNITY_GET - Buscar dados de oportunidade → SALESFORCE_TASK_CREATE - Criar tarefa associada à oportunidade → SALESFORCE_ACCOUNT_CREATE - Criar Account antes da oportunidade