Guia para implementadores do agente Agentforce¶
Para quem configura, no Salesforce, o agente que recebe os handoffs do Trip. Descreve o que o Trip envia, o que ele espera receber e como a conversa termina. Detalhes de implementação do lado do Trip: Handoff Trip → Agentforce.
Termos usados neste guia¶
| Termo | O que é |
|---|---|
| Trip | O assistente de IA do site iFriend (Google ADK + Gemini). Atende o cliente no chat do site e busca produtos no catálogo iFriend. |
| Agentforce | A plataforma de agentes de IA do Salesforce. Nela roda o agente que recebe o cliente depois do handoff. |
| Agente Agentforce (ou agente SDR) | O agente configurado no Agentforce que qualifica a oportunidade: decide abrir um Case/oportunidade de vendas para o time comercial ou informar ao cliente que não há produto. É o agente que este guia ensina a configurar. |
| Agent API | A API REST do Salesforce (api.salesforce.com/einstein/ai-agent/v1) pela qual o Trip abre sessões e troca mensagens com o agente Agentforce. |
| Handoff | O momento em que o Trip passa o atendimento do cliente para o agente Agentforce. |
| Relay | O modo depois do handoff: o Trip só repassa mensagens entre o cliente e o agente Agentforce, sem responder por conta própria. |
1. Como funciona¶
- O cliente conversa com o Trip no chat do site.
- Em certos momentos (ver seção 2), o Trip oferece um especialista. Com o aceite do cliente, o Trip identifica a conta, abre uma sessão no agente Agentforce pela Agent API e envia o contexto da conversa.
- A partir daí, o Trip fica em modo relay: o cliente continua no chat do site, cada mensagem dele é repassada ao agente Agentforce, e cada resposta dele é mostrada ao cliente. O LLM do Trip não interfere.
- Quando o agente Agentforce sinaliza o fim (seção 5), o Trip volta a atender o cliente.
sequenceDiagram
participant C as Cliente (site)
participant T as Trip
participant A as Agente Agentforce (Agent API)
C->>T: conversa
T->>C: oferece especialista
C->>T: aceita e informa os dados de identificação
T->>A: POST /sessions
T->>A: POST /messages (seq 1, contexto e Sales_Case_Payload)
A-->>T: Inform
T-->>C: resposta do agente Agentforce
loop relay
C->>T: mensagem
T->>A: POST /messages (seq n)
A-->>T: Inform
T-->>C: resposta
end
A-->>T: SessionEnded (ou mensagem-marcador)
T-->>C: despedida e o Trip volta a atender
Não é A2A
Neste sentido (Trip → Agentforce), a integração usa a Agent API do Salesforce. O sentido inverso (Agentforce chamando o Trip, por exemplo no WhatsApp) usa A2A — ver a seção 7.
2. Quando o Trip faz o handoff¶
| Momento | Situação | handoff_reason |
O que o agente Agentforce recebe |
|---|---|---|---|
| M1 | Produto não encontrado no catálogo | produto_nao_encontrado |
Destino, datas, nº de pessoas, o que foi buscado |
| M2 | Cliente pediu explicitamente uma pessoa | pedido_humano ou orcamento |
Tópico e resumo; dados do pedido podem estar incompletos |
| M3 | Tour personalizado / orçamento de quem não gera o PDF sozinho | tour_personalizado ou orcamento |
Briefing estruturado + produtos do catálogo escolhidos (ID, nome, preço, moeda) |
| M4 | Agência montando uma proposta B2B encontrou uma pendência (item sem preço, dúvida comercial, erro) | orcamento |
O que já foi montado + a pendência no resumo |
O Trip não faz handoff em sites whitelabel (o atendimento é do parceiro), em canais fora da lista configurada e quando a conversa chegou ao Trip via A2A (outro agente chamando).
3. O que o agente Agentforce recebe¶
3.1 Abertura da sessão¶
- Uma sessão por handoff (
POST /einstein/ai-agent/v1/agents/{agent_id}/sessions). externalSessionKey={sessão do Trip}:{uuid8}— rastreável até a conversa no Trip.bypassUser: true; modo síncrono (chunkTypes: ["Text"]), sem streaming.
3.2 Primeira mensagem (seq 1): contexto em texto¶
Um resumo legível, para o agente Agentforce (e para quem ler o histórico) entender o caso sem abrir variável nenhuma:
[CONTEXTO DO TRIP — handoff automático do assistente do site iFriend]
Motivo do handoff: produto_nao_encontrado
Canal: site
Conta: Agência (B2B) — nova (não encontrada na iFriend)
Empresa: Agência Exemplo | CNPJ: 11222333000181
Contato: Fulano de Tal | fulano@exemplo.com | 5511900000000
Resumo: Procura passeio de balão na Capadócia para 2 pessoas em maio
Case: Cotação — Capadócia — 2 pax — 05/2026
Destino: Capadócia
Início da viagem: 2026-05-10
...
(Case completo, pronto para upsert, na variável de contexto Sales_Case_Payload)
A partir da próxima mensagem você conversa diretamente com o cliente
(as mensagens dele serão repassadas pelo Trip).
As mensagens seguintes (seq 2..n) são o texto do cliente, sem nenhum prefixo.
3.3 Identificação da conta¶
O Trip sempre identifica a conta antes de escalar, então o agente Agentforce não precisa perguntar de novo:
| Tipo | Dados que o Trip garante |
|---|---|
| Viajante (B2C) | nome, e-mail, telefone/WhatsApp |
| Agência/empresa (B2B) | nome do contato, e-mail, telefone/WhatsApp, nome da empresa e CNPJ válido (dígitos verificadores conferidos) |
- Cliente logado: o tipo da conta vem das permissões do login e é confiável.
- Conta existente / nova: o Trip consulta a base iFriend (somente leitura) e informa se a conta já existe e o ID iFriend. A conta nova é criada no Salesforce, nunca pelo Trip.
3.4 Variável de contexto Sales_Case_Payload¶
O Trip envia o Case "Fluxo de Vendas" pronto para o Composite Upsert do objeto Case, numa única variável de
contexto (nome padrão Sales_Case_Payload, configurável no Trip):
{
"allOrNone": true,
"records": [
{
"attributes": {"type": "Case"},
"RecordTypeId": "<Record Type do Fluxo de Vendas>",
"External_ID__c": "<sessão do Trip>:<uuid8>",
"Subject": "Cotação — Capadócia — 2 pax — 05/2026",
"Description": "Procura passeio de balão na Capadócia para 2 pessoas em maio",
"Reason": "Cotação",
"Origin": "Chat",
"Tipo_registro_conta__c": "B2B",
"Destino__c": "Capadócia",
"Data_da_Viagem__c": "2026-05-10",
"...": "..."
}
]
}
Para criar o Case, basta:
PATCH /services/data/v62.0/composite/sobjects/Case/External_ID__c
(corpo = conteúdo de Sales_Case_Payload)
- Idempotente:
External_ID__cé a mesma chave da sessão, então repetir o upsert não duplica o Case. - Completo ou parcial: em M1/M3/M4 os campos obrigatórios do fluxo vêm preenchidos; em M2 (pedido de pessoa) o Case pode vir parcial, com o que já se sabe.
- O que o Trip não envia: lookups (
AccountId,ContactId, solicitante, lead) e campos que dependem de regra do Salesforce (dono da conta, região, prioridade, qualificação). Esses ficam com o agente Agentforce ou com um Flow do Salesforce. - Lista completa de campos, API names e picklists: Handoff → Case "Fluxo de Ocorrência de Vendas".
3.5 Variáveis avulsas (opcional)¶
Se preferir variáveis separadas além do Case, o Trip mapeia estas chaves para os API names que você criar no agente (configuração do Trip, sem deploy):
| Chave no Trip | Conteúdo |
|---|---|
trip_session_id |
ID da conversa no Trip |
handoff_reason |
produto_nao_encontrado / pedido_humano / tour_personalizado / orcamento |
account_type |
viajante / agencia |
customer_name, customer_email, customer_phone |
Contato |
summary |
Resumo da conversa |
channel |
sse / webchat |
whitelabel |
URL do whitelabel, quando aplicável |
4. Como responder ao cliente¶
- Responda com mensagens
Inform. CadaInformvira uma mensagem no chat do site, na ordem recebida. - Só texto. O canal é configurado para texto; se o cliente enviar um arquivo durante o relay, o agente Agentforce recebe um aviso textual em vez do arquivo.
- Mensagens
Failuresão registradas em log e não são mostradas ao cliente. - O Trip aguarda cada resposta até o timeout HTTP configurado (padrão 60 s); depois disso trata como erro (seção 5.4).
5. Como encerrar o atendimento¶
O Trip só sai do relay quando recebe um sinal de fim. Sem ele, continua repassando tudo ao agente Agentforce até o tempo de inatividade (padrão 30 min) — o cliente fica preso no relay e a sessão fica aberta no Salesforce.
5.1 Preferido: tipo nativo SessionEnded¶
O agente Agentforce encerra a sessão, e a resposta traz uma mensagem com "type": "SessionEnded". O Trip mostra os textos
da mesma resposta e volta a atender.
{
"messages": [
{"type": "Inform", "message": "Pronto! Registrei seu pedido e nosso time vai te chamar no WhatsApp."},
{"type": "SessionEnded", "reason": "..."}
]
}
5.2 Alternativa: mensagem-marcador SessionEnded¶
Se o agente Agentforce não conseguir encerrar a sessão, ele deve enviar por último uma mensagem Inform cujo texto é somente
SessionEnded, opcionalmente com um motivo: SessionEnded:<motivo>. A despedida vai numa mensagem anterior.
{
"messages": [
{"type": "Inform", "message": "Pronto! Registrei seu pedido e nosso time vai te chamar no WhatsApp."},
{"type": "Inform", "message": "SessionEnded:case_criado"}
]
}
| Motivo | Quando usar |
|---|---|
case_criado |
Case/oportunidade aberto |
sem_produto |
Qualificado, mas não há produto/serviço para o pedido |
encerrado (padrão, sem motivo) |
Qualquer outro encerramento |
Ao receber o marcador, o Trip:
- não mostra o marcador ao cliente, só a despedida;
- sai do relay e volta a atender;
- registra o motivo na conversa;
- encerra a sessão com
DELETE /sessions/{id}(x-session-end-reason: UserRequest).
Regras:
- Texto exato, com maiúsculas e minúsculas como está. Espaços e quebras de linha nas pontas são ignorados.
- Sozinho: numa mensagem própria (preferido) ou como última linha, sozinha, de uma mensagem.
- Não encerra:
SessionEnd,/SessionEnd,sessionendedouSessionEndedno meio de uma frase — esses textos são mostrados ao cliente como mensagem comum.
5.3 Transferência para humano: Escalation¶
Se o agente Agentforce devolver "type": "Escalation", o Trip encerra a sessão (x-session-end-reason: Transfer) e oferece
ao cliente o atendimento humano pelo WhatsApp. Pedidos de atendente seguintes na mesma conversa vão direto ao
WhatsApp, sem abrir outra sessão.
5.4 Outros encerramentos (lado do Trip)¶
| Situação | O que o Trip faz |
|---|---|
| Inatividade do cliente (padrão 30 min) | DELETE com Timeout; a próxima mensagem do cliente é atendida pelo Trip |
| Erro da Agent API (4xx/5xx/timeout) no meio do relay | Sai do relay e avisa o cliente; novos pedidos de atendente vão para o WhatsApp |
| Erro ao abrir a sessão | Não entra em relay; o cliente recebe o formulário de WhatsApp |
6. Checklist de configuração do agente Agentforce¶
- [ ] Criar a variável de contexto
Sales_Case_Payload(texto longo) no agente Agentforce. - [ ] Ação/Flow que faz o Composite Upsert do Case com o conteúdo da variável, ao decidir abrir o fluxo de vendas.
- [ ] Usar os dados de identificação que vieram no contexto — não perguntar de novo nome, e-mail, telefone, CNPJ.
- [ ] Ao concluir, sinalizar o fim:
SessionEndednativo ou a mensagem-marcadorSessionEnded[:motivo]. - [ ] Para transferir a um humano, usar
Escalation. - [ ] Combinar com a iFriend o External Client App (client_credentials), o Agent ID e o My Domain de cada ambiente. Credenciais trafegam só por canal seguro e ficam no Secret Manager do Trip.
7. Sentido inverso: Agentforce chamando o Trip (A2A)¶
Em canais onde o primeiro atendimento é do Agentforce (por exemplo, WhatsApp), o agente Agentforce pode chamar o Trip
pelo servidor A2A para buscar produtos. Nesse caso o Trip não faz handoff e não pede de novo os dados do cliente
que o agente Agentforce enviar como contexto. Contrato do contexto do chamador (DataPart, extensão caller-context/v1):
Integração A2A → Para Parceiros.