| Projeto | Integração PetLove × HubSpot × Zenvia |
| Documento | Análise Técnica V2 — Integração Zenvia × HubSpot (Forms API) |
| Versão | 2.0 (evolução da v1.0 — apenas Path C: Forms API) |
| Data | 06/03/2026 |
| Autor | Epic Digital — Equipe Técnica |
| Objetivo | Documentar a arquitetura definitiva: bot Zenvia → Chamada de API → HubSpot Forms API, sem middleware e sem servidor externo |
Este documento apresenta a arquitetura definitiva de integração entre o atendimento via WhatsApp (Zenvia) e o HubSpot CRM da PetLove. A solução escolhida e o Path C — Forms API: o bot da Zenvia usa a funcionalidade nativa "Chamada de API" para enviar dados diretamente para a HubSpot Forms API.
Sem middleware. Sem servidor externo. Sem Operations Hub. O contato e criado automaticamente no HubSpot (mesmo que nunca tenha existido), e workflows disparam a partir da submissao do formulário.
PoC validada em producao: 34 propriedades criadas, formulário configurado, 6 contatos criados com sucesso em 7 cenarios E2E.
O middleware (Fluxo A da v1.0) permanece como evolução futura (V2) para cenarios que exijam regras de ownership, busca de dados complementares na Zenvia, ou tratamento de dados sensiveis.
Tres caminhos foram analisados para integrar Zenvia → HubSpot. O Path C (Forms API) foi escolhido como arquitetura definitiva para a V1:
| Criterio | Fluxo AMiddleware | Fluxo BOps Hub Direto | Path C (Recomendado)Forms API |
|---|---|---|---|
| Precisa Ops Hub? | Não | Sim (já contratado) | Não |
| Precisa servidor? | Sim (Node.js) | Não | Não |
| Contato novo? | Cria | Ignorado | Cria automaticamente |
| Autenticação? | API key | Webhook URL | Nenhuma (público) |
| Tempo dev (full) | 46-60 dias uteis | 15-25 dias uteis | 15-20 dias uteis |
| Prazo V1 | 26/03/2026 | 26/03/2026 | 26/03/2026 (15 dias uteis) |
| Quem implementa? | EPIC (código) | EPIC (workflow) | Time Zenvia/PetLove (builder) + EPIC (workflow) |
Passo a passo para configurar a "Chamada de API" no Construtor do Bot da Zenvia Conversion.
No Construtor do Bot, crie um novo bloco após a coleta de dados do lead. Nomeie-o como EnviarParaHubSpot ou similar.
Clique nos tres pontinhos do bloco → Adicionar conteudo → Chamada de API.
| Campo | Valor |
|---|---|
| Método | POST |
| URL | https://api.hsforms.com/submissions/v3/integration/submit/50501903/a5edb59a-d033-4905-84d4-c00cbed2403e |
Content-Type: application/json
Não e necessário nenhum token de autenticação. A Forms API e pública por design.
No campo Corpo, cole o JSON da Seção 5. Substitua os valores fixos pelas variáveis do bot usando a sintaxe <? $nome_variável ?>.
A resposta fica disponível em <? $resposta_api.body ?>. No bloco seguinte:
$resposta_api.code == 200, seguir fluxo normal| Parametro | Valor |
|---|---|
| URL completa | https://api.hsforms.com/submissions/v3/integration/submit/50501903/a5edb59a-d033-4905-84d4-c00cbed2403e |
| Portal ID | 50501903 |
| Form ID | a5edb59a-d033-4905-84d4-c00cbed2403e |
| Método | POST |
| Content-Type | application/json |
| Autenticação | Nenhuma — Forms API e pública |
| Rate Limit | 100 submissoes / 10 segundos por formulário |
| Dedup | Por email — mesmo email atualiza contato existente |
| Protocolo | HTTPS (obrigatório) |
Copiar e colar no campo Corpo da Chamada de API. Substituir valores fixos por variáveis do bot.
// ---- DADOS DO CONTATO (coletados pelo bot) ---- { "fields": [ { "name": "email", "value": "<? $email_lead ?>" }, { "name": "firstname", "value": "<? $primeiro_nome ?>" }, { "name": "lastname", "value": "<? $sobrenome ?>" }, { "name": "phone", "value": "<? $telefone ?>" }, // ---- DADOS DO PET ---- { "name": "pet_name", "value": "<? $nome_pet ?>" }, { "name": "pet_species", "value": "<? $especie_pet ?>" }, // ---- DADOS ZENVIA CORE ---- { "name": "zenvia_conversation_id", "value": "<? $conversation_id ?>" }, { "name": "zenvia_channel", "value": "whatsapp" }, { "name": "first_message", "value": "<? $primeira_mensagem ?>" }, { "name": "zenvia_event_id", "value": "<? $event_id ?>" }, { "name": "zenvia_subscription_id", "value": "sub_petlove_whatsapp" }, { "name": "zenvia_event_type", "value": "MESSAGE" }, { "name": "zenvia_message_id", "value": "<? $message_id ?>" }, { "name": "zenvia_direction", "value": "IN" }, { "name": "zenvia_from", "value": "<? $telefone_lead ?>" }, { "name": "zenvia_to", "value": "551140042500" }, { "name": "zenvia_content_type", "value": "text" }, { "name": "zenvia_timestamp", "value": "<? $timestamp ?>" }, { "name": "zenvia_message_status", "value": "delivered" }, { "name": "zenvia_whatsapp_name", "value": "<? $whatsapp_name ?>" }, { "name": "zenvia_bot_flow_id", "value": "<? $flow_id ?>" }, { "name": "zenvia_metadata", "value": "<? $metadata_json ?>" }, // ---- REFERRAL / CLICK-TO-WHATSAPP ADS ---- { "name": "zenvia_referral_headline", "value": "<? $referral_headline ?>" }, { "name": "zenvia_referral_source_type", "value": "<? $referral_type ?>" }, { "name": "zenvia_referral_source_url", "value": "<? $referral_url ?>" }, { "name": "zenvia_referral_ctwa_id", "value": "<? $ctwa_id ?>" }, { "name": "zenvia_contact_id", "value": "<? $zenvia_contact_id ?>" }, { "name": "zenvia_flow_response_data", "value": "<? $flow_response ?>" }, // ---- STATUS & ERROS ---- { "name": "zenvia_visitor_picture", "value": "<? $visitor_picture ?>" }, { "name": "zenvia_status_description", "value": "<? $status_desc ?>" }, { "name": "zenvia_status_error_code", "value": "<? $error_code ?>" }, { "name": "zenvia_status_error_reason", "value": "<? $error_reason ?>" }, { "name": "zenvia_channel_provider", "value": "<? $channel_provider ?>" }, { "name": "zenvia_message_payload", "value": "<? $msg_payload ?>" } ], "context": { "pageUri": "https://api.zenvia.io/whatsapp", "pageName": "Zenvia WhatsApp - PetLove" } }
email e obrigatório. Se algum campo não estiver disponível no bot, remova a linha do JSON ou envie com valor vazio (""). Campos não reconhecidos sao ignorados silenciosamente.
| # | HubSpot Property | Fonte Zenvia | Variável Bot | Obrig. |
|---|---|---|---|---|
| 1 | email | Coletado pelo bot / metadata | <? $email_lead ?> | Sim |
| 2 | firstname | Coletado / metadata.contactName | <? $primeiro_nome ?> | Não |
| 3 | lastname | Coletado / metadata.contactName | <? $sobrenome ?> | Não |
| 4 | phone | message.from / metadata | <? $telefone ?> | Não |
| # | HubSpot Property | Fonte | Variável Bot |
|---|---|---|---|
| 5 | pet_name | Coletado pelo bot | <? $nome_pet ?> |
| 6 | pet_species | Coletado pelo bot | <? $especie_pet ?> |
| # | HubSpot Property | Fonte | Tipo |
|---|---|---|---|
| 7 | zenvia_conversation_id | metadata.conversationId | text |
| 8 | zenvia_channel | fixo: "whatsapp" | text |
| 9 | first_message | message.contents[0].text | text |
| 10 | zenvia_event_id | id | text |
| 11 | zenvia_subscription_id | subscriptionId | text |
| 12 | zenvia_event_type | type (MESSAGE, MESSAGE_STATUS) | text |
| 13 | zenvia_message_id | message.id | text |
| 14 | zenvia_direction | direction (IN/OUT) | text |
| 15 | zenvia_from | message.from | text |
| 16 | zenvia_to | message.to | text |
| 17 | zenvia_content_type | message.contents[0].type | text |
| 18 | zenvia_timestamp | timestamp | text |
| 19 | zenvia_message_status | messageStatus.code | text |
| 20 | zenvia_whatsapp_name | message.visitor.name | text |
| 21 | zenvia_bot_flow_id | metadata (custom) | text |
| 22 | zenvia_metadata | metadata (JSON string) | text |
| # | HubSpot Property | Fonte | Uso |
|---|---|---|---|
| 23 | zenvia_referral_headline | message.referral.headline | Headline do anuncio CTWA |
| 24 | zenvia_referral_source_type | message.referral.source.type | Tipo: ad, post |
| 25 | zenvia_referral_source_url | message.referral.source.url | URL do anuncio |
| 26 | zenvia_referral_ctwa_id | message.referral.ctwaId | ID do Click-to-WhatsApp Ad |
| 27 | zenvia_contact_id | conversation.contactId | ID do contato na Zenvia |
| 28 | zenvia_flow_response_data | flow_response.data | Dados do WhatsApp Flow (JSON) |
| # | HubSpot Property | Fonte | Uso |
|---|---|---|---|
| 29 | zenvia_visitor_picture | message.visitor.picture | URL foto perfil WhatsApp |
| 30 | zenvia_status_description | messageStatus.description | Descrição do status |
| 31 | zenvia_status_error_code | messageStatus.causes[].channelErrorCode | Código de erro do canal |
| 32 | zenvia_status_error_reason | messageStatus.causes[].reason | Razao do erro |
| 33 | zenvia_channel_provider | message.channel.provider | Provider do canal |
| 34 | zenvia_message_payload | message.contents[].payload | Payload de botao clicado |
POST https://api.hsforms.com/submissions/v3/integration/submit/50501903/{FORM_ID}
Content-Type: application/json
{
"fields": [
{ "name": "email", "value": "teste.zenvia@petlove.com" },
{ "name": "firstname", "value": "Teste" },
{ "name": "phone", "value": "+5511999887766" },
{ "name": "zenvia_channel", "value": "whatsapp" },
{ "name": "first_message", "value": "Teste de integração" }
],
"context": {
"pageUri": "https://api.zenvia.io/whatsapp",
"pageName": "Zenvia WhatsApp - PetLove"
}
}
Form ID: a5edb59a-d033-4905-84d4-c00cbed2403e — Copiar para Postman ou terminal como cURL POST.
| HTTP | Causa | Ação |
|---|---|---|
| 200 | Sucesso. Contato criado/atualizado. | Nenhuma. |
| 400 | Campo obrigatório ausente ou validação falhou. | Verificar errors[].message. Não reenviar. |
| 404 | Form ID ou Portal ID incorreto. | Verificar IDs na URL. |
| 429 | Rate limit (100 req/10s). | Backoff exponencial. Esperar 10s. |
| 5xx | Erro interno HubSpot. | Retry com backoff. Se persistir, contatar HubSpot. |
Após a submissao via Forms API, o HubSpot dispara automaticamente workflows com trigger "Contact submits a form" filtrado pelo formulário Zenvia.
| # | Ação | Detalhes |
|---|---|---|
| 1 | Criar Deal | Pipeline de vendas PetLove, estagio inicial |
| 2 | Atribuir vendedor | Baseado em round-robin ou regra de territorio |
| 3 | Enviar notificação | Email/Slack para vendedor atribuido |
| 4 | Setar lifecycle stage | Lead ou MQL conforme criterios |
knWv****cyBp) retorna HTTP 401 (Unauthorized) ao testar contra a API v2 da Zenvia. Isso significa que o token pode estar expirado, revogado, ou sem os escopos necessários.https://app.zenvia.com/home/api e compartilhar com a EPIC.| # | Tarefa | Quem | Status |
|---|---|---|---|
| 0 | BLOCKER: Gerar novo token Zenvia API v2 (atual retorna 401). Deadline: 10/03/2026 | PetLove / Zenvia | Bloqueado |
| 1 | 34 properties customizadas criadas no grupo "Integração Zenvia" | EPIC | Feito |
| 2 | Formulário criado com 34 campos (4 categorias) | EPIC | Feito |
| 3 | PoC validada em producao (6 contatos, 7 cenarios E2E) | EPIC | Feito |
| 4 | Documento de integração (este documento) | EPIC | Feito |
| 5 | Configurar "Chamada de API" no builder do bot (Seção 3) | Zenvia / PetLove | Pendente |
| 6 | Mapear variáveis do bot para campos HubSpot (Seção 6) | Zenvia / PetLove | Pendente |
| 7 | Garantir coleta de email no fluxo do bot (obrigatório) |
Zenvia / PetLove | Pendente |
| 8 | Testar via Postman/cURL (Seção 7) | Zenvia / PetLove | Pendente |
| 9 | Implementar retry para erros 429/5xx | Zenvia / PetLove | Pendente |
| 10 | Workflow de atribuicao de vendedor | EPIC | Pendente |
| 11 | Desenvolvimento e testes (validação técnica do fluxo completo) | EPIC | Pendente |
| 12 | Homologação e validação dos eventos | EPIC | Pendente |
A V2 (Middleware) e opcional e sera iniciada somente após a conclusao da V1, se aprovada pela PetLove como plano de melhoria futuro.
| Limitação da V1 (Forms API) | Como o middleware resolve |
|---|---|
| Não busca dados complementares do contato na Zenvia | GET /contacts/{id} na Zenvia API para enriquecer o contato |
| Não aplica regras de ownership (vendedor dono) | Mapeia userId Zenvia → email → ownerId HubSpot |
| Não aplica regras de negocio (janela 24h, carteira 15 dias) | Lógica customizada antes de gravar no HubSpot |
| Não cria Deal, Communication e Atendimento automaticamente | Cria todos os objetos e associações via HubSpot API |
| Sem fila de retry e idempotencia | Bull/Redis com Dead Letter Queue, processamento idempotente |
| Dados sensiveis trafegam direto para o HubSpot | Middleware intercepta, sanitiza e transforma ANTES de gravar no CRM |
| Item | V1 (Forms API) | V2 (Middleware) |
|---|---|---|
| Criação de contato | Automatico | Automatico |
| Dados do bot (34 campos) | Sim | Sim + enriquecidos |
| Busca dados complementares Zenvia | Não | GET /contacts/{id} |
| Regras de ownership | Não | userId → ownerId |
| Regras de negocio (janela 24h) | Não | Lógica customizada |
| Cria Deal automaticamente | Via workflow | Via API (middleware) |
| Fila com retry / DLQ | Não | Bull/Redis |
| Tratamento dados sensiveis | Sem tratamento | Mascaramento, LGPD |