Pular para conteúdo

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:

  1. Gestão de Pipeline: Rastrear negócios em andamento com valor e probabilidade de fechamento
  2. Previsão de Receita: Projetar receita futura baseada em oportunidades no funil
  3. Métricas de Vendas: Acompanhar taxas de conversão, ciclo de vendas e performance
  4. Automação de Processos: Criar oportunidades automaticamente a partir de conversas qualificadas

Como funciona internamente?

Quando o SALESFORCE_OPPORTUNITY_CREATE é executado, o sistema:

  1. Recebe os dados: Coleta nome, estágio, data de fechamento e valor da oportunidade
  2. Processa variáveis: Substitui variáveis do contexto pelos valores reais
  3. Valida campos obrigatórios: Name, StageName e CloseDate são obrigatórios
  4. Converte valores numéricos: Amount e Probability são convertidos para float
  5. Monta payload: Cria objeto com todos os campos
  6. Autentica no Salesforce: Usa accessToken e instanceUrl
  7. Faz requisição POST: Envia para /services/data/v60.0/sobjects/Opportunity
  8. Retorna ID: Salesforce responde com ID da oportunidade criada
  9. 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

  1. Lead qualificado: Após qualificar lead, criar oportunidade com valor estimado
  2. Proposta comercial: Cliente solicita proposta formal via WhatsApp
  3. Renovação de contrato: Cliente atual manifesta interesse em renovação ou upgrade
  4. Venda consultiva: Após discovery via chat, criar oportunidade estruturada
  5. 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