Ir para o conteúdo

Validar e enriquecer registros antes de um upsert em CRM no Jitterbit Studio

Introdução

Escrever um registro em um CRM sem validar seu conteúdo corre o risco de criar entradas duplicadas, armazenar dados incompletos ou sobrescrever valores precisos com informações desatualizadas. Este guia mostra como construir um pipeline de pré-escrita em múltiplos estágios que valida campos obrigatórios, verifica registros existentes para decidir entre criar e atualizar, e opcionalmente enriquece os dados recebidos com informações de contato de terceiros antes do upsert final.

Um segundo padrão adiciona uma porta de aprovação por LLM para fluxos de trabalho agênticos. Quando um modelo de linguagem controla a escrita no CRM, o prompt do sistema impõe um fluxo de dois estágios confirmar-depois-executar para que o modelo sempre solicite aprovação explícita do usuário antes de criar ou atualizar um registro. Isso evita que uma frase do usuário como "adicione este contato" dispare uma escrita imediata sem confirmação.

Este guia usa Salesforce como destino do CRM e ZoomInfo como fonte de enriquecimento. Os padrões de validação de campo e verificação de existência se aplicam a qualquer conector de CRM ou API.

Padrão de design

O pipeline baseado em código é executado sequencialmente. Cada estágio continua para o próximo ou gera um erro antes de atingir a escrita:

%%{init: {"themeVariables": {"lineColor": "#6b7280", "edgeLabelBackground": "#f5f5f5"}}}%% flowchart LR A["Validate
required fields"] --> B["Check for
existing record
(SfLookupAll)"] B --> C{"Record
exists?"} C -- Yes --> D["Enrich
(ZoomInfo)"] C -- No --> D D --> E{"Create or
update?"} E -- Create --> F["Salesforce
Create activity"] E -- Update --> G["Salesforce
Update activity"]

A porta de aprovação por LLM envolve o estágio de execução em fluxos de trabalho agênticos:

%%{init: {"themeVariables": {"lineColor": "#6b7280", "edgeLabelBackground": "#f5f5f5"}}}%% flowchart LR A["User request
(create/update)"] --> B["LLM checks
conversation history"] B --> C{"Prior approval
request made?"} C -- No --> D["confirm_create_contact
(ask for approval)"] C -- "Yes + approved" --> E["execute_create_contact
(write to Salesforce)"] C -- "Yes + rejected" --> F["process_response
(inform user)"]

Parte 1: Validar campos obrigatórios

Antes de consultar ou escrever no Salesforce, confirme que o registro recebido possui os campos mínimos necessários para identificar e criar um contato. Para um Salesforce Lead, os campos obrigatórios são normalmente email, nome e sobrenome. Rejeite imediatamente registros que não possuem nenhum desses campos para evitar escritas parciais ou não identificáveis.

Etapa 1: Escrever o script de validação de campo

Adicione uma etapa de Script no início da operação de pré-escrita. O script verifica cada campo obrigatório, acumula mensagens de campo faltante e gera um erro se o registro não puder prosseguir:

// Validate required fields before any CRM operation
$errors = "";

If(Length(Trim($lead.email)) == 0,
    $errors = $errors + "Email is required. ";
);
If(Length(Trim($lead.firstName)) == 0,
    $errors = $errors + "First name is required. ";
);
If(Length(Trim($lead.lastName)) == 0,
    $errors = $errors + "Last name is required. ";
);

If(Length($errors) > 0,
    RaiseError("Record validation failed: " + $errors)
);

// Normalize the email address before the lookup
$lead.email = ToLower(Trim($lead.email));

WriteToOperationLog("Required field validation passed for: " + $lead.email);

Trim remove espaços em branco no início e fim. Normalizar o email para minúsculas antes da consulta evita incompatibilidades sensíveis a maiúsculas/minúsculas ao comparar com registros do Salesforce.

Etapa 2: Verificar o formato do email

Para detectar endereços malformados antes de chegar ao Salesforce, adicione uma verificação de formato usando RegExMatch:

If(!RegExMatch($lead.email, "^[^@]+@[^@]+\\.[^@]+$"),
    RaiseError("Invalid email format: " + $lead.email)
);

Esta verificação detecta erros óbvios de formatação (símbolo @ faltante, domínio faltante) sem rejeitar endereços válidos que contenham caracteres incomuns.

Parte 2: Verificar registros existentes

Após a validação, consulte o Salesforce para determinar se um registro com o mesmo email já existe. O resultado controla se a operação downstream cria um novo registro ou atualiza o existente.

Etapa 1: Consultar Salesforce por um lead correspondente

Use SfLookupAll para procurar um lead com o mesmo endereço de email. SfLookupAll retorna um array bidimensional: cada array interno é uma linha correspondente, e cada elemento é um valor de campo na ordem especificada na consulta.

Adicione uma etapa de Script após o script de validação:

// Query Salesforce for an existing lead by email
$sf.existingLeadId = "";
$result = SfLookupAll(
    "<TAG>endpoint:salesforce/Salesforce</TAG>",
    "SELECT Id FROM Lead WHERE Email = '" + $lead.email + "' AND IsConverted = false LIMIT 1"
);

If(Length($result) > 0,
    // Row 0, column 0 is the Id field
    $sf.existingLeadId = $result[0][0];
    WriteToOperationLog("Existing lead found: " + $sf.existingLeadId);
,
    WriteToOperationLog("No existing lead found for: " + $lead.email);
);

LIMIT 1 evita que o array de resultado contenha múltiplas correspondências se o mesmo email aparecer mais de uma vez, o que pode acontecer em dados de CRM com duplicatas históricas. Para o padrão de consulta SOQL, consulte Consultar registros do Salesforce usando SOQL.

Etapa 2: Definir a variável de roteamento

Após a consulta, defina uma variável que as operações downstream usem para ramificar para a atividade de escrita correta:

If(Length($sf.existingLeadId) > 0,
    $sf.operation = "update";
,
    $sf.operation = "create";
);

No script do controlador ou na cadeia de operações downstream, verifique sf.operation para chamar a atividade Salesforce apropriada. Para orientação sobre como criar ramificações entre operações com base em uma variável, consulte Gerenciar workflows usando scripts do controlador.

Parte 3: Enriquecer o registro antes de fazer a escrita

Com os campos obrigatórios validados e a decisão de criar ou atualizar tomada, opcionalmente enriqueça o registro recebido com dados de contato adicionais de uma fonte terceirizada antes da escrita. Esta etapa preenche campos ausentes e sinaliza valores que podem ter mudado desde a última sincronização.

Etapa 1: Chamar enriquecimento ZoomInfo

Se o registro tiver um nome de empresa associado, use ZoomInfo para recuperar o cargo atual do contato, número de telefone direto e e-mail. Para a configuração completa da integração ZoomInfo, incluindo autenticação e roteador de recursos, consulte Enriquecer dados de contato usando ZoomInfo.

Depois que a operação de enriquecimento ZoomInfo é executada, aplique os valores retornados às variáveis de preparação, preservando quaisquer valores já presentes no registro recebido:

// Apply enrichment results — fill gaps only, do not overwrite existing values
If(Length(Trim($zoom.enriched.phone)) > 0 && Length(Trim($lead.phone)) == 0,
    $lead.phone = $zoom.enriched.phone
);
If(Length(Trim($zoom.enriched.title)) > 0 && Length(Trim($lead.title)) == 0,
    $lead.title = $zoom.enriched.title
);

O If protege a preservação de qualquer valor que o sistema de origem já forneceu. O enriquecimento ZoomInfo preenche lacunas em vez de sobrescrever dados.

Etapa 2: Detectar valores de campo obsoletos em registros existentes

Ao atualizar um registro Salesforce existente, compare valores enriquecidos com os valores armazenados para identificar campos que foram alterados. Registre quaisquer discrepâncias para que operações downstream possam decidir se devem aplicar o valor atualizado:

// Compare enriched title against the Salesforce stored value
If($sf.operation == "update"
    && Length(Trim($zoom.enriched.title)) > 0
    && $zoom.enriched.title != $sf.existing.title,
    WriteToOperationLog(
        "Title change detected for " + $lead.email
        + ": Salesforce has [" + $sf.existing.title + "]"
        + ", ZoomInfo has [" + $zoom.enriched.title + "]"
    );
    $lead.titleChanged = true;
);

Aplicar o novo valor ou sinalizá-lo para análise manual depende de suas regras de negócio. O princípio fundamental é comparar antes de sobrescrever para que uma fonte de enriquecimento não substitua silenciosamente dados precisos.

Etapa 3: Executar a operação de escrita

Passe o registro validado e enriquecido para a operação de escrita Salesforce. Use sf.operation para chamar a operação correta:

If($sf.operation == "create",
    RunOperation("<TAG>operation:Salesforce - Create Lead</TAG>");
,
    RunOperation("<TAG>operation:Salesforce - Update Lead</TAG>");
);

Para ambas as operações, use uma transformação que mapeie as variáveis $lead.* para os campos Lead do Salesforce correspondentes. Para a operação de atualização, também mapeie sf.existingLeadId para o campo Id para que o Salesforce possa identificar qual registro atualizar.

Parte 4: Implementar uma porta de aprovação LLM

Em workflows de agentes em que um modelo de linguagem processa solicitações de usuários e faz roteamento para operações de escrita CRM, adicione um fluxo explícito de confirmação-depois-execução em dois estágios. A porta de aprovação garante que a intenção de um usuário de criar ou atualizar um contato sempre seja confirmada antes da escrita ocorrer. Uma declaração como "adicionar este contato" não conta como aprovação por si só.

Este padrão usa chamada de função LLM para fazer roteamento entre estágios. Para uma introdução à chamada de função no Studio, consulte Rotear respostas LLM para operações Studio usando chamada de função.

Etapa 1: Definir as regras de aprovação no prompt do sistema

Adicione uma seção de regras de aprovação ao prompt do sistema que instrua o modelo como determinar se aprovação explícita foi dada. Inclua este texto como um bloco distinto dentro da mensagem do sistema, antes da descrição das funções disponíveis:

Approval rules (important):
- A user request to "clean", "update", "create", "add", or "insert" contacts does NOT
  count as approval by itself.
- Approval is valid ONLY IF:
  a) The assistant explicitly asked for confirmation to create or update a contact
     in a previous message, AND
  b) The user responded with a clear approval phrase such as: "yes", "proceed",
     "approved", or "go ahead".
- If the assistant has NOT asked for confirmation previously, you MUST select
  "confirm_create_contact" or "confirm_update_contact" depending on whether the
  action is a create or an update.
- If the assistant previously asked for confirmation and the user responds with
  "no", "not approved", or "do not create", route to "process_response".

A distinção entre "solicitado" e "aprovado" é a regra principal. O modelo verifica o histórico da conversa para determinar qual caso se aplica a cada turno.

Etapa 2: Definir as funções de roteamento

Registre quatro funções de roteamento no manifesto de ferramentas passado para o LLM:

Nome da função Quando chamar
confirm_create_contact Usuário solicitou criação, mas o modelo ainda não pediu confirmação nesta conversa.
confirm_update_contact Usuário solicitou atualização, mas o modelo ainda não pediu confirmação nesta conversa.
execute_create_contact Modelo perguntou anteriormente por confirmação E o usuário deu aprovação explícita.
execute_update_contact Modelo perguntou anteriormente por confirmação E o usuário deu aprovação explícita.

Descreva cada função claramente no manifesto. As descrições de função têm o mesmo peso que as regras do prompt do sistema quando o modelo decide qual função chamar.

Etapa 3: Mapear respostas de roteamento para operações do Studio

No script do controlador que é executado após cada resposta do LLM, extraia o function_name da chamada de ferramenta e execute a operação correspondente:

$route = TrimChars(
    GetJSONString($jitterbit.response, "/choices/[0]/message/tool_calls/[0]/function/name"),
    "\""
);

Case(
    $route == "confirm_create_contact",
        RunOperation("<TAG>operation:LLM - Confirm Create Contact</TAG>");
    ,
    $route == "confirm_update_contact",
        RunOperation("<TAG>operation:LLM - Confirm Update Contact</TAG>");
    ,
    $route == "execute_create_contact",
        RunOperation("<TAG>operation:Validate and Enrich Lead</TAG>");
        RunOperation("<TAG>operation:Salesforce - Create Contact</TAG>");
    ,
    $route == "execute_update_contact",
        RunOperation("<TAG>operation:Validate and Enrich Lead</TAG>");
        RunOperation("<TAG>operation:Salesforce - Update Contact</TAG>");
    ,
    true,
        RunOperation("<TAG>operation:LLM - Process Response</TAG>");
);

A operação Validate and Enrich Lead executa o pipeline de validação e enriquecimento de campos (Partes 1–3) antes da gravação no Salesforce. Separar a validação do script de roteamento torna a etapa de validação reutilizável fora do contexto do agente.

Etapa 4: Incluir histórico de conversa em cada chamada de LLM

A porta de aprovação depende do modelo saber se já solicitou confirmação na conversa atual. Para que as regras de aprovação funcionem corretamente, cada chamada de LLM deve incluir o histórico de conversa completo no array messages, não apenas a mensagem do usuário atual.

Para o padrão usado para acumular e armazenar histórico de conversa entre execuções de operação, consulte Criar um chat LLM de múltiplas voltas com histórico de conversa.

Verificar a integração

  1. Execute o pipeline pré-gravação com um registro de teste que está faltando o endereço de email. Confirme que o script de validação gera um erro e que a operação de gravação no Salesforce nunca é chamada. Verifique os logs de operação para a mensagem de erro.

  2. Execute o pipeline com um endereço de email válido que corresponda a um lead existente no Salesforce. Confirme que sf.existingLeadId é preenchido e que sf.operation é definido como update.

  3. Execute o pipeline com um endereço de email que não tem registro correspondente no Salesforce. Confirme que sf.existingLeadId está vazio e que sf.operation é definido como create.

  4. Se usar enriquecimento do ZoomInfo: execute a etapa de enriquecimento para um contato conhecido e confirme que zoom.enriched.phone e zoom.enriched.title são preenchidos antes da operação de gravação no Salesforce ser executada.

  5. Para testar a porta de aprovação do LLM: envie uma mensagem ao agente como "create a contact for Jane Smith at Acme Corp". Confirme que o modelo é roteado para confirm_create_contact em vez de execute_create_contact.

  6. Responda ao prompt de confirmação com "yes, go ahead" e confirme que o modelo é roteado para execute_create_contact na próxima volta.

  7. Para testar rejeição: depois que o modelo solicita confirmação, responda com "no, don't create it". Confirme que o modelo é roteado para process_response e que a operação de gravação no Salesforce não é chamada.