image

Investimento único e acesso para sempre

84
%OFF
Article image
Walakys Providello
Walakys Providello05/10/2026 10:27
Compartir

Reconstruindo conversas do Salesforce Data Cloud com SQL

    Como relacionar sessões, participantes e mensagens em uma única consulta

    Em projetos envolvendo atendimento digital, uma necessidade bastante comum é conseguir responder perguntas simples:

    Qual foi a conversa daquele cliente? Quando a sessão começou? Quem enviou cada mensagem? Foi o cliente, um bot ou um atendente? Qual era o conteúdo da mensagem?

    Recentemente trabalhei em uma consulta relativamente simples no Salesforce Data Cloud para justamente reconstruir esse histórico.

    O objetivo era transformar diferentes objetos relacionados a Messaging em uma visão única da conversa.

    O cenário

    No Salesforce, uma conversa não necessariamente está armazenada inteira dentro de uma única tabela.

    As informações podem estar distribuídas entre estruturas responsáveis por:

    • sessão de atendimento;
    • relacionamento entre sessão e mensagens;
    • entradas da conversa;
    • participantes;
    • usuários;
    • conteúdo das mensagens.

    Para reconstruir a conversa, precisamos relacionar esses dados.

    A lógica ficou aproximadamente assim:

    Messaging Session
         ↓
    Related Record
         ↓
    Conversation Entry
         ↓
    Conversation Participant
         ↓
    Salesforce User
    

    O resultado é uma estrutura semelhante a:

    Sessão
    Cliente
    Canal
    CPF/CNPJ
    Classificação
    Status
    
    ↓
    Mensagem 1 - Cliente
    Mensagem 2 - Atendente
    Mensagem 3 - Cliente
    Mensagem 4 - Atendente
    

    1. Começando pela sessão

    A consulta parte da sessão de Messaging:

    FROM MessagingSession_Home__dlm s
    

    A partir dela recuperamos informações importantes sobre o atendimento:

    s.Name__c AS nome_sessao,
    s.CreatedDate__c AS data_criacao,
    s.ChannelName__c AS nome_canal,
    s.telefoneCliente_c__c AS telefone_cliente,
    s.CPF_CNPJ_c__c AS cpf_cnpj,
    s.Classificacao_c__c AS classificacao,
    s.Status__c AS status
    

    Com isso conseguimos trazer o contexto da conversa junto com cada mensagem.

    Por exemplo:

    Sessão: MS-001245
    Canal: WhatsApp Safra
    Telefone: 14999999999
    Classificação: Negociação
    Status: Encerrado
    

    2. Relacionando a sessão às mensagens

    O próximo passo é descobrir quais mensagens pertencem àquela sessão.

    Para isso utilizamos uma tabela intermediária:

    JOIN RELATED_RECORD ... r
      ON LEFT(s.Id__c, 15) = r.record_id__c
    

    Nesse ponto existe um detalhe interessante.

    Utilizamos:

    LEFT(s.Id__c, 15)
    

    porque alguns relacionamentos no ecossistema Salesforce podem aparecer utilizando versões diferentes do identificador.

    O Salesforce normalmente trabalha com IDs de 15 ou 18 caracteres.

    Então normalizar o identificador durante o JOIN pode ser necessário dependendo da estrutura do Data Cloud.

    3. Recuperando as mensagens

    Depois relacionamos o registro encontrado com as entradas da conversa:

    JOIN CONVERSATION_ENTRY ... e
      ON r.conversation_entry_id__c = e.id__c
    

    Assim conseguimos acessar:

    e.id__c AS mensagem_id,
    e.created_at__c AS data_mensagem,
    e.conversation_participant_role__c AS tipo_remetente,
    e.entry_payload__c AS conteudo_json
    

    Agora já temos algo parecido com:

    10:21 - Cliente
    "Gostaria de negociar minha dívida"
    
    10:22 - Atendente
    "Olá, vou verificar as condições disponíveis."
    
    10:24 - Cliente
    "Obrigado."
    

    4. Mas quem realmente enviou a mensagem?

    Essa foi uma das partes mais interessantes.

    A própria mensagem possui:

    e.conversation_participant_display_name__c
    

    Mas nem sempre esse campo é suficiente para identificar o participante corretamente.

    Por isso relacionamos também:

    ssot__ConversationEntry__dlm
    

    com:

    ConversationParticipant_Home__dll
    

    e posteriormente:

    ssot__User__dlm
    

    A lógica permite tentar identificar o nome do usuário Salesforce responsável pela mensagem.

    5. Utilizando COALESCE para encontrar o remetente

    Para aumentar a confiabilidade do resultado utilizei:

    COALESCE(
      u_sender.ssot__FullName__c,
      cp.ParticipantDisplayName__c,
      e.conversation_participant_display_name__c
    ) AS remetente
    

    O COALESCE retorna o primeiro campo que não estiver nulo.

    Na prática, a prioridade fica:

    1. Nome do usuário Salesforce
          ↓
    2. Nome do participante
          ↓
    3. Nome informado na própria mensagem
    

    Isso evita depender exclusivamente de uma única fonte.

    O resultado pode ficar assim:

    Remetente: João Silva
    Tipo: Agent
    
    Remetente: Cliente
    Tipo: EndUser
    
    Remetente: Bot Atendimento
    Tipo: Bot
    

    6. Filtrando apenas mensagens reais

    Outro filtro importante foi:

    AND e.entry_type__c = 'Message'
    

    Uma conversa pode possuir outros tipos de eventos além de mensagens.

    Por exemplo:

    entrada na sessão
    mudança de participante
    evento de sistema
    status
    mensagem
    

    Como o objetivo era reconstruir o transcript, mantivemos apenas:

    Message
    

    7. Trabalhando com período

    Também delimitamos o período analisado:

    WHERE s.CreatedDate__c >=
    TIMESTAMP WITH TIME ZONE '2026-09-01 00:00:00-03:00'
    
    AND s.CreatedDate__c <
    TIMESTAMP WITH TIME ZONE '2026-10-01 00:00:00-03:00'
    

    Prefiro trabalhar utilizando:

    >= início
    < próximo período
    

    em vez de tentar definir manualmente:

    23:59:59
    

    Isso deixa o filtro mais previsível.

    8. Filtrando uma operação específica

    Nesse exemplo também queremos analisar somente sessões relacionadas a um determinado canal.

    AND LOWER(s.ChannelName__c) LIKE '%safra%'
    

    O LOWER() ajuda a evitar problemas com diferenças de maiúsculas e minúsculas.

    Assim valores como:

    SAFRA
    Safra
    safra_whatsapp
    WhatsApp Safra
    

    podem ser encontrados pelo mesmo filtro.

    9. Colocando a conversa na ordem correta

    Por fim:

    ORDER BY
      s.CreatedDate__c DESC,
      e.created_at__c ASC
    

    Aqui temos duas ordenações.

    As sessões mais recentes aparecem primeiro:

    s.CreatedDate__c DESC
    

    Mas dentro de cada sessão as mensagens aparecem cronologicamente:

    e.created_at__c ASC
    

    Assim conseguimos ler a conversa na mesma sequência em que ela aconteceu.

    A consulta

    Para uma publicação pública, recomendo substituir identificadores específicos do ambiente por nomes genéricos.

    A estrutura principal fica assim:

    SELECT
      s.Name__c AS nome_sessao,
      s.CreatedDate__c AS data_criacao,
      s.ChannelName__c AS nome_canal,
      s.telefoneCliente_c__c AS telefone_cliente,
      s.CPF_CNPJ_c__c AS cpf_cnpj,
      s.Classificacao_c__c AS classificacao,
      s.Status__c AS status,
    
      r.record_id__c AS sessao_vinculada,
    
      e.id__c AS mensagem_id,
      e.created_at__c AS data_mensagem,
    
      COALESCE(
          u_sender.ssot__FullName__c,
          cp.ParticipantDisplayName__c,
          e.conversation_participant_display_name__c
      ) AS remetente,
    
      e.conversation_participant_role__c AS tipo_remetente,
      e.entry_payload__c AS conteudo_json
    
    FROM MessagingSession_Home__dlm s
    
    JOIN RELATED_RECORD_<DATA_SOURCE>__dll r
      ON LEFT(s.Id__c, 15) = r.record_id__c
    
    JOIN CONVERSATION_ENTRY_<DATA_SOURCE>__dll e
      ON r.conversation_entry_id__c = e.id__c
    
    LEFT JOIN ssot__ConversationEntry__dlm ce
      ON e.id__c = ce.ssot__Id__c
    
    LEFT JOIN ConversationParticipant_Home__dll cp
      ON ce.ssot__EngagementParticipantId__c = cp.Uuid__c
    
    LEFT JOIN ssot__User__dlm u_sender
      ON LEFT(cp.ParticipantEntityId__c, 15)
         = LEFT(u_sender.ssot__Id__c, 15)
    
    WHERE
      s.CreatedDate__c >=
      TIMESTAMP WITH TIME ZONE '2026-09-01 00:00:00-03:00'
    
      AND s.CreatedDate__c <
      TIMESTAMP WITH TIME ZONE '2026-10-01 00:00:00-03:00'
    
      AND e.entry_type__c = 'Message'
    
      AND LOWER(s.ChannelName__c) LIKE '%canal%'
    
    ORDER BY
      s.CreatedDate__c DESC,
      e.created_at__c ASC;
    

    Resultado

    Apesar de ser uma consulta relativamente pequena, ela permite transformar diversos objetos do Salesforce em uma visão muito mais simples:

    SESSÃO
    │
    ├── Cliente
    ├── Telefone
    ├── CPF/CNPJ
    ├── Canal
    ├── Classificação
    └── Status
    
          ↓
    
    CONVERSA
    │
    ├── 09:01 Cliente: Olá
    ├── 09:02 Bot: Como posso ajudar?
    ├── 09:03 Cliente: Quero negociar
    ├── 09:05 João Silva: Vou verificar
    └── 09:07 Cliente: Obrigado
    

    E isso abre diversas possibilidades.

    Podemos utilizar esse resultado para:

    • geração de transcripts;
    • auditoria de atendimentos;
    • análises de qualidade;
    • classificação de conversas;
    • indicadores operacionais;
    • integrações externas;
    • alimentação de bases internas;
    • utilização futura com IA e análise conversacional.

    O que esse pequeno SQL me ensinou

    Uma consulta não precisa ter centenas de linhas para resolver um problema relevante.

    Nesse caso utilizamos principalmente:

    JOIN para conectar os objetos.

    LEFT JOIN para manter mensagens mesmo quando determinada informação complementar não existir.

    LEFT() para normalizar IDs Salesforce.

    COALESCE() para melhorar a identificação do remetente.

    TIMESTAMP WITH TIME ZONE para trabalhar corretamente com períodos.

    LOWER() + LIKE para filtros mais flexíveis.

    ORDER BY para reconstruir a sequência cronológica da conversa.

    No final, o SQL apenas conecta os pontos.

    O verdadeiro valor está em transformar dados distribuídos em uma informação que a operação consegue utilizar.

    Conclusão

    Esse foi um exemplo simples de como utilizei SQL dentro do Salesforce Data Cloud para reconstruir conversas de atendimento.

    Partimos de objetos separados de Messaging e chegamos a uma visão contendo:

    sessão + cliente + atendente + mensagem + horário + conteúdo.

    É uma consulta pequena, mas que pode se tornar a base para projetos muito maiores de dados conversacionais, automação, analytics e inteligência artificial.

    Tecnologias: Salesforce • Data Cloud • Messaging • SQL • WhatsApp • Dados Conversacionais

    Compartir
    Recomendado para ti
    Reclame AQUI - Dados e IA na Prática
    CI&T - Java AI Copilot
    Itaú - Java com Inteligência Artificial
    Comentarios (0)