Sincronizar envios de formulário do HubSpot com Salesforce no Jitterbit Studio
Introdução
Os envios de formulário do HubSpot chegam como uma lista paginada em que cada envio contém um array de pares nome/valor (um par por campo do formulário) em vez de um registro simples com propriedades nomeadas. Este guia mostra como recuperar esses envios usando a API de Envios de Formulários do HubSpot por meio do conector HTTP v2, despachá-los um de cada vez através do padrão de loop SelectNodes do Studio, extrair o endereço de email, nome e sobrenome do array de valores, verificar o Salesforce para um lead existente e criar ou atualizar um registro de Lead com base no resultado.
Este guia utiliza:
- O conector HTTP v2 para chamar a API de Envios de Formulários do HubSpot.
- Armazenamento temporário do Studio para manter o lote completo de envios entre a etapa de busca e o loop de despacho por registro.
SelectNodeseReadFilepara iterar através de registros XML armazenados.SfLookupAllpara detectar leads duplicados por endereço de email.- As atividades Create e Update do conector Salesforce para gravar o registro de Lead.
Este guia pressupõe uma conta HubSpot com um aplicativo privado e um token de acesso. É necessário o GUID do formulário cujos envios você deseja sincronizar. Cada formulário do HubSpot tem um GUID único visível na URL do editor de formulários ou por meio da API de Formulários do HubSpot.
Padrão de design
A integração é executada em dois estágios: uma busca em lote que recupera todos os envios de um formulário e os armazena como XML, e um loop por registro que processa cada envio individualmente.
Initialize variables
Set form path"] --> B["HTTP v2 GET
HubSpot submissions
for [$hubspot.form.guid]"] B --> C["Transformation
Write to
temp storage (batch)"] C --> D["Script
ReadFile + SelectNodes
loop over submissions"] D --> E["Per-record operation
(transformation + scripts)"] E --> F{"Email found
in Salesforce?"} F -- Yes --> G["Salesforce
Update Lead"] F -- No --> H["Salesforce
Create Lead
+ optional ZoomInfo enrich"]
A busca em lote é executada uma vez por sincronização de formulário. O loop por registro é executado uma vez por envio.
Parte 1: Configurar variáveis de projeto e a conexão HTTP v2
Etapa 1: Criar variáveis de projeto
Armazene o token de acesso do HubSpot e o GUID do formulário como variáveis de projeto para que possam ser atualizadas sem editar scripts. Abra o menu de ações do projeto e selecione Project Variables. Em seguida, adicione:
| Nome | Valor padrão | Descrição |
|---|---|---|
hubspot.access.token |
(seu token de acesso do aplicativo privado HubSpot) | Token Bearer usado para autenticar todas as chamadas de API |
hubspot.form.guid |
(seu GUID de formulário HubSpot) | GUID do formulário cujos envios devem ser sincronizados |
Marque hubspot.access.token como oculto. Para orientações sobre como armazenar credenciais com segurança, consulte Manage endpoint credentials.
Etapa 2: Configurar a conexão HTTP v2
-
No Studio, abra seu projeto e clique na aba Project endpoints and connectors na paleta de componentes de design.
-
Clique no conector HTTP v2 para abrir a tela de configuração de conexão.
-
Connection Name: Digite
HubSpot API. -
Base URL: Digite
https://api.hubapi.com. -
Authorization: Selecione Bearer Token e digite
[$hubspot.access.token]como o valor do token. -
Clique em Test para verificar a conexão e, em seguida, clique em Save Changes.
Etapa 3: Criar a atividade GET Form Submissions
-
A partir da conexão HubSpot API, arraste uma atividade GET para a tela de design.
-
Name: Digite
HubSpot - GET Form Submissions. -
Path: Digite
/form-integrations/v1/submissions/forms/[$hubspot.form.guid].O Studio substitui
[$hubspot.form.guid]pelo valor da variável de projeto em tempo de execução. Para sincronizar um formulário diferente, atualize a variável de projeto sem modificar a configuração da atividade. -
Na aba Request, adicione um cabeçalho:
- Key:
Content-Type - Value:
application/json
- Key:
-
Clique em Concluído.
Parte 2: Recuperar envios e gravá-los no armazenamento temporário
Etapa 1: Criar a operação de busca
Crie uma operação chamada HubSpot - Fetch Form Submissions com estas etapas em ordem:
-
Script: Inicialize as variáveis usadas no processamento por registro:
// Reset per-run staging variables $hubspot.email = ""; $hubspot.firstName = ""; $hubspot.lastName = ""; WriteToOperationLog("Starting HubSpot form submission sync for form: " + [$hubspot.form.guid]); -
Atividade GET: Coloque a atividade
HubSpot - GET Form Submissionscomo etapa de origem. -
Transformação: Adicione uma transformação após a atividade GET com uma atividade Temporary Storage Write como destino. Mapeie o esquema JSON de origem para o esquema de destino nos níveis de loop
results/itemeresults/item/values/itempara que todos os registros de envio sejam gravados no armazenamento temporário em uma única passagem.Nomeie a transformação
HubSpot - Write Submissions to Temp Storagee nomeie a atividade Temporary Storage Write comoWrite HubSpot Submissions.
A atividade Temporary Storage Write armazena os registros de envio como XML. O Studio grava cada item no nível de loop mais interno como um elemento DocInfo, que é o formato que o loop de distribuição lê na Parte 3.
Etapa 2: Tratar o caso em que nenhum envio é encontrado
Adicione uma etapa Script após a transformação. Verifique a contagem de envios antes de distribuir o loop:
$count = Length(SelectNodes(
ReadFile("<TAG>activity:tempstorage/HubSpot Temp Storage/tempstorage_read/Read HubSpot Submissions</TAG>"),
"//DocInfo"
));
If($count == 0,
WriteToOperationLog("No HubSpot submissions found. Exiting.");
CancelOperation("<TAG>operation:HubSpot - Fetch Form Submissions</TAG>");
,
WriteToOperationLog("Found " + $count + " submission(s) to process.");
);
CancelOperation cancela a operação atual de forma limpa sem gerar um erro quando nenhum envio está presente.
Parte 3: Distribuir envios um de cada vez
Etapa 1: Adicionar o script de distribuição
Adicione uma etapa Script à operação HubSpot - Fetch Form Submissions após a verificação de contagem. Este script lê o lote armazenado, extrai registros de envio individuais usando SelectNodes e chama uma operação por registro uma vez por envio:
data = ReadFile("<TAG>activity:tempstorage/HubSpot Temp Storage/tempstorage_read/Read HubSpot Submissions</TAG>");
nodes = SelectNodes(data, "//DocInfo");
counts = Length(nodes);
WriteToOperationLog("Dispatching " + counts + " submission(s).");
i = 0;
While(i < counts,
node = nodes[i];
// Wrap the single node so the per-record operation has a valid XML source
xml = "<SubmissionBatch><Submissions>" + String(node) + "</Submissions></SubmissionBatch>";
WriteFile(
"<TAG>activity:tempstorage/HubSpot Temp Storage 2/tempstorage_write/Write Single HubSpot Submission</TAG>",
xml
);
FlushFile(
"<TAG>activity:tempstorage/HubSpot Temp Storage 2/tempstorage_write/Write Single HubSpot Submission</TAG>"
);
RunOperation("<TAG>operation:HubSpot - Process Single Submission</TAG>");
i = i + 1;
);
O wrapper <SubmissionBatch><Submissions> é um contêiner externo fixo que fornece à transformação de origem da operação por registro um elemento raiz previsível. O nó DocInfo extraído se torna o elemento interno que a transformação mapeia.
FlushFile força a conclusão da gravação antes que RunOperation chame a operação por registro. Sem liberar, a operação pode ler os dados do registro anterior.
Importante
RunOperation está sujeito a um limite de nível de agente em chamadas síncronas feitas dentro de um único loop While (50 por padrão). Se um lote tiver mais de 50 envios, este loop de distribuição atinge esse limite no meio do caminho: RunOperation retorna false para o 51º envio em diante, e os envios restantes no lote não são processados. Consulte a nota em RunOperation para saber como configurar ou substituir esse limite para GUIDs de formulário que recebem regularmente mais de 50 envios por sincronização.
Etapa 2: Configurar armazenamento temporário para distribuição por registro
Configure um segundo endpoint de Temporary Storage (por exemplo, HubSpot Temp Storage 2) com:
- Uma atividade Write chamada
Write Single HubSpot Submission. - Uma atividade Read chamada
Read Single HubSpot Submission, usada como origem na operação por registro.
Os dois endpoints mantêm o lote completo e o buffer por registro separados para que o loop de distribuição não sobrescreva os dados de origem pelos quais está iterando.
Parte 4: Extrair valores de campo do envio
Os envios de formulário do HubSpot armazenam valores de campo como uma matriz values de objetos nome/valor. O nome do campo (email, firstname, lastname) está no campo name, e o valor enviado está no campo value. A transformação deve iterar ambos os níveis (results/item para cada envio e o values/item aninhado para cada campo) e ler o campo name para saber qual variável preencher.
Etapa 1: Criar a operação por registro
Crie uma operação chamada HubSpot - Process Single Submission. Sua fonte é a atividade Read Single HubSpot Submission Temporary Storage Read.
Etapa 2: Criar a transformação de extração de campos
Adicione uma transformação à operação por registro chamada HubSpot - Extract Submission Fields. Defina dois níveis de loop na transformação:
- Loop externo:
results/itemna fonte, mapeando para o caminho de destino correspondente. - Loop interno:
results/item/values/itemna fonte, aninhado dentro do loop externo.
No loop interno, adicione estes scripts de mapeamento:
Para o nó de destino values/item/name:
$hubspot.fieldName = json$results$item.values$item.name$
Para o nó de destino values/item/value:
If($hubspot.fieldName == "email",
$hubspot.email = json$results$item.values$item.value$
);
If($hubspot.fieldName == "firstname",
$hubspot.firstName = json$results$item.values$item.value$
);
If($hubspot.fieldName == "lastname",
$hubspot.lastName = json$results$item.values$item.value$
);
Para o nó de destino externo results/item/pageUrl (que é acionado após o loop interno ser concluído para cada envio), chame a operação de verificação do Salesforce:
If(Length(Trim($hubspot.email)) > 0,
$hubspot.email = ToLower(Trim($hubspot.email));
RunOperation("<TAG>operation:HubSpot - Check Salesforce Lead</TAG>");
,
WriteToOperationLog("Submission missing email field. Skipping.");
);
O mapeamento pageUrl é executado uma vez por registro de envio, após todos os seus filhos values/item terem sido processados. Este é o local correto para acionar a operação Salesforce downstream. Normalizar o email para minúsculas antes da busca evita incompatibilidades sensíveis a maiúsculas/minúsculas com registros do Salesforce.
Parte 5: Verificar o Salesforce para um lead existente
Etapa 1: Criar a operação de verificação do Salesforce
Crie uma operação chamada HubSpot - Check Salesforce Lead. Adicione uma etapa Script como a única etapa de operação:
$sf.existingLeadId = "";
$result = SfLookupAll(
"<TAG>endpoint:salesforce/Salesforce</TAG>",
"SELECT Id FROM Lead WHERE Email = '"
+ $hubspot.email
+ "' AND IsConverted = false LIMIT 1"
);
If(Length($result) > 0,
$sf.existingLeadId = $result[0][0];
WriteToOperationLog("Existing lead found: " + $sf.existingLeadId);
RunOperation("<TAG>operation:HubSpot - Update Salesforce Lead</TAG>");
,
WriteToOperationLog("No existing lead for: " + $hubspot.email);
RunOperation("<TAG>operation:HubSpot - Create Salesforce Lead</TAG>");
);
SfLookupAll retorna um array bidimensional: cada array interno é uma linha de resultado, e cada elemento é um valor de campo na ordem listada na cláusula SELECT. $result[0][0] é o campo Id da primeira (e única) linha retornada. LIMIT 1 evita que múltiplas correspondências causem um erro de índice de array quando o mesmo email aparece em mais de um registro de lead.
IsConverted = false exclui leads que já foram convertidos em contatos, oportunidades ou contas. Atualizar um lead convertido no Salesforce gera um erro, portanto é mais seguro ignorá-los e deixar o caminho de criação lidar com o caso extremo separadamente, se necessário.
Para o padrão de consulta SOQL, consulte Consultar registros do Salesforce usando SOQL.
Parte 6: Criar ou atualizar o Lead do Salesforce
Etapa 1: Criar o registro de Lead
Crie uma operação chamada HubSpot - Create Salesforce Lead. Adicione uma etapa Transformation que mapeie as variáveis de staging para uma atividade Create do Salesforce direcionada ao objeto Lead:
| Expressão de origem | Campo Salesforce Lead |
|---|---|
$hubspot.firstName |
FirstName |
$hubspot.lastName |
LastName |
$hubspot.email |
Email |
"HubSpot" (literal) |
LeadSource |
Defina um valor literal para LeadSource para marcar todos os leads criados por esta integração para fins de relatório.
A atividade Create do Salesforce retorna o novo ID de registro. Capture-o para uso na etapa de enriquecimento opcional:
$sf.newLeadId = TrimChars(
GetJSONString($jitterbit.response, "/id"),
"\""
);
WriteToOperationLog("Created Salesforce lead: " + $sf.newLeadId);
Após capturar o ID, chame a operação de enriquecimento ZoomInfo para preencher campos adicionais (consulte Parte 7):
If(Length($sf.newLeadId) > 0,
RunOperation("<TAG>operation:ZoomInfo - Enrich Lead</TAG>")
);
Etapa 2: Atualizar o registro de Lead existente
Crie uma operação chamada HubSpot - Update Salesforce Lead. Adicione uma etapa Transformation que mapeie para uma atividade Update do Salesforce direcionada ao objeto Lead. A atividade Update requer o campo Id para identificar o registro:
| Expressão de origem | Campo Salesforce Lead |
|---|---|
$sf.existingLeadId |
Id |
$hubspot.firstName |
FirstName |
$hubspot.lastName |
LastName |
$hubspot.email |
Email |
Mapeie apenas os campos que a integração possui. Omitir campos da transformação preserva os valores existentes no registro do Salesforce.
Parte 7: Enriqueça novos leads com ZoomInfo
Após criar um novo lead no Salesforce, uma etapa de enriquecimento opcional usa o ZoomInfo para preencher o cargo atual, empresa e número de telefone direto do contato. A operação de enriquecimento chama o endpoint de enriquecimento do ZoomInfo usando o email do lead e o nome da empresa como chaves de busca, depois atualiza o lead do Salesforce com os dados retornados.
Para a configuração da conexão da API do ZoomInfo e o padrão de roteador de recursos usado por esta etapa, consulte Enriqueça dados de contato usando ZoomInfo.
Verifique a integração
-
No HubSpot, abra o formulário que você está sincronizando e envie uma entrada de teste com um endereço de email único que não existe no Salesforce. Execute
HubSpot - Fetch Form Submissionsmanualmente e verifique os logs de operação. Confirme que o log mostra a contagem correta de envios e queHubSpot - Create Salesforce Leadfoi executado para o envio de teste. -
No Salesforce, procure o registro de Lead pelo endereço de email de teste. Confirme que
FirstName,LastNameeEmailestão preenchidos e queLeadSourceestá definido comoHubSpot. -
Envie uma segunda entrada de teste usando o mesmo endereço de email. Execute a operação de busca novamente e confirme que
HubSpot - Update Salesforce Leadfoi executado em vez da operação de criação, e que o lead do Salesforce existente foi atualizado em vez de duplicado. -
Teste o caso de envio vazio executando a operação em um formulário sem envios. Confirme que os logs de operação mostram "No HubSpot submissions found" e que nenhuma operação do Salesforce foi chamada.
-
Para testar um envio sem o campo de email, adicione temporariamente um envio de teste sem email. Confirme que o log mostra "Submission missing email field. Skipping." e que nenhuma operação do Salesforce foi executada para esse registro.
-
Se a atividade GET retornar um erro 401, confirme que
[$hubspot.access.token]está definido e que o token de acesso do aplicativo privado não expirou. Os tokens de aplicativo privado do HubSpot não expiram por padrão, mas podem ser rotacionados. Verifique o token nas configurações do aplicativo privado do HubSpot. -
Se
SelectNodesretornar zero nós apesar da atividade GET retornar dados, confirme que a transformação na Parte 2 está fazendo loop no nívelresults/iteme que a atividade Temporary Storage Write foi concluída antes do script de dispatch ser executado.