Saltar para o conteúdo principal
O External Agent está disponível nos planos YCloud Pro e superiores.
Conecte seu próprio agente de IA à YCloud como um External Agent. O seu agente é executado na sua infraestrutura e trabalha em conjunto com os seus atendentes humanos no Inbox: ele recebe mensagens de clientes, envia respostas, recupera o histórico da conversa e transfere conversas para a sua equipe. A YCloud envia eventos para a sua URL de webhook. O seu serviço processa esses eventos e chama a API REST do Inbox para responder ou gerenciar a conversa. A YCloud não chama a sua API de inferência de IA, e a resposta HTTP do seu webhook não é enviada ao cliente.

Antes de começar

Prepare:
  • Um endpoint HTTPS acessível publicamente que aceite solicitações JSON POST.
  • Um serviço que verifique assinaturas de webhook, armazene eventos, evite processamento duplicado e execute seu agente de IA.
  • Uma chave de API de conta YCloud normal, armazenada no seu servidor. Chaves de API de Aplicativos de Desenvolvedor não são suportadas por esses endpoints do Inbox.
  • Um número comercial do WhatsApp conectado à YCloud e uma equipe ou atendente humano para receber transferências.
Use https://api.ycloud.com como a URL base da API.

Conecte seu agente

1. Criar um External Agent

  1. No console da YCloud, acesse AI Agent > AI Agent.
  2. Selecione Create Agent > External Agent.
  3. Insira um Name e a sua Webhook URL, como https://agent.example.com/webhooks/ycloud.
  4. Selecione Save.
  5. Copie o Bot ID gerado nos detalhes do agente. Use esse valor como botId em solicitações à API; não é necessário fornecer um ID do seu próprio sistema de IA.
Formulário de criação de External Agent da YCloud com os controles Name, Webhook URL e Save.

Create an External Agent with a name and a webhook URL. This example shows the form before saving.

A página de detalhes exibe o endpoint de webhook, o seu Signing secret e os quatro tipos de evento. Use o signing secret para verificar eventos recebidos. Selecione View delivery logs para investigar o envio dos webhooks. O mesmo endpoint também está disponível na página Webhooks . Mantenha o signing secret do endpoint separado da sua chave de API. O secret verifica webhooks recebidos; X-API-Key autentica as suas solicitações REST de saída. Um Bot ID é um identificador, não uma credencial.

2. Atribuir um número do WhatsApp

Abra WhatsApp Manager > WhatsApp accounts, abra as configurações do número comercial e selecione Inbox > Assignment. Em Priority 3 Assign to, selecione AI Agent e, em seguida, escolha o seu agente na seção External Agent do seletor de agentes. Verifique a prioridade das regras: a atribuição ao responsável pelo cliente ou ao último atendente a cuidar do caso pode ter precedência. Consulte Conversation assignment rules. Um External Agent pode lidar com vários números. Cada número fica associado a um bot por vez. Gerencie essas associações nas configurações de atribuição do número.

3. Processar uma conversa

  1. Um cliente envia uma mensagem de WhatsApp para o seu número comercial.
  2. A YCloud abre ou continua um diálogo no Inbox e aplica as regras de atribuição do número.
  3. Quando o seu External Agent gerencia o diálogo, a YCloud entrega os eventos de webhook aplicáveis ao endpoint dele.
  4. Seu serviço verifica e armazena o evento, retorna 2xx e processa a entrada do cliente de forma assíncrona.
  5. Seu serviço chama a API do Inbox para responder, transferir ou encerrar o diálogo.
  6. Seu serviço monitora a entrega por meio de whatsapp.message.updated.

Entenda os identificadores

Os IDs são strings. Os carimbos de data/hora usam UTC RFC 3339. Use dialogId, não conversationId, nos caminhos da API de diálogo.

Receber eventos de webhook

Todos os quatro tipos de eventos chegam à mesma URL de webhook. Cada entrega dedicada do External Agent inclui id, type, apiVersion, createTime e externalBotContext, além do objeto de negócio correspondente.

Verificar, armazenar e confirmar

Verifique o cabeçalho YCloud-Signature usando o segredo de assinatura do endpoint e o corpo bruto da requisição HTTP, antes de analisar o JSON. O formato da assinatura é:
Use uma comparação de tempo constante e valide o timestamp com uma tolerância razoável, como cinco minutos. Consulte Implementar um receptor de webhook para ver exemplos de verificação de assinatura. Persista o evento e seu estado de desduplicação e, em seguida, retorne qualquer resposta 2xx bem-sucedida prontamente. Execute a inferência de IA e outros trabalhos lentos de forma assíncrona. Respostas que não sejam 2xx e tempos limites esgotados (timeouts) podem acionar um número limitado de novas tentativas. Desduplique por (botId, event.id), dentro da sua conta da YCloud. Uma alteração de atribuição pode notificar tanto o agente que sai quanto o que entra; usar apenas um ID de evento global pode descartar a notificação de um dos agentes. Mantenha o estado de processamento para que um evento repetido não envie uma segunda resposta.

Exemplo: mensagem do cliente

Leia o conteúdo do cliente a partir de inboxMessage.inbound. Eventos de criação de saída usam inboxMessage.outbound. Mantenha tipos de mensagens e campos desconhecidos para compatibilidade, em vez de tratá-los como texto.

Decidir se deve responder

externalBotContext é um snapshot criado quando a notificação é gerada. Seu botId identifica o bot receptor; assignee identifica o manipulador real nesse snapshot. Eles podem diferir após um transbordo. actionable=true significa que o bot receptor estava manipulando um diálogo aberto naquele momento. Ele também pode ser true em um evento de criação de saída ou em um recibo de entrega.
Não acione uma resposta de IA apenas com base em actionable. Verifique o tipo de evento e a direção da mensagem. Um evento atrasado não prova que seu agente ainda manipula o diálogo. Consulte o diálogo atual quando necessário e trate erros de propriedade em todas as requisições de gravação.
Os eventos podem chegar mais de uma vez ou fora de ordem. Não há campo de sequência de eventos. Agrupe o trabalho por dialogId e evite processar a mesma entrada do cliente duas vezes. Um evento inicial de atribuição não deve acionar de forma independente uma segunda resposta à mensagem inicial do cliente.

O que acontece após um transbordo ou encerramento?

Novas mensagens do cliente e respostas humanas não são mais entregues ao External Agent anterior assim que o diálogo passa a ser manipulado por um humano, entra na fila, fica não atribuído ou é encerrado. O agente anterior ainda recebe sua notificação aplicável de saída de atribuição ou encerramento. Notificações de criação e recibos de entrega de mensagens que ele já enviou continuam associados a esse agente remetente, mesmo após um transbordo ou reatribuição de número. Notificações geradas anteriormente podem chegar com atraso. Cancele o trabalho pendente quando a titularidade mudar ou quando o diálogo for encerrado, e não o retome apenas porque um evento antigo contém actionable=true. Endpoints de webhook comuns mantêm seu comportamento de assinatura e formato de payload existentes. A entrega dedicada do External Agent adiciona externalBotContext; não exija esse campo em entregas comuns de whatsapp.message.updated.

Usar a API Inbox

Envie X-API-Key em todas as requisições e Content-Type: application/json em requisições POST. Todos os exemplos abaixo usam IDs de espaço reservado. Substitua-os pelos valores do seu agente e dos eventos recebidos. As respostas com sucesso retornam o objeto de negócios diretamente, sem um wrapper data. As operações de gravação verificam se a caixa de diálogo está aberta e sendo tratada atualmente pelo bot especificado. A YCloud determina o remetente e o cliente a partir da caixa de diálogo; não envie tenantId, from, to, recipient, operatorId ou source para substituí-los.

Obter a caixa de diálogo atual

Verifique status, assignee e canAct. O campo bot pode fazer referência ao último bot externo associado e não é uma prova de propriedade atual. canAct reflete a permissão do bot consultado no momento da solicitação; uma gravação posterior ainda realiza suas próprias verificações.

Recuperar o histórico de conversas

A resposta contém items e nextCursor. Cada item inclui uma mensagem do Inbox id, direction, type, content e createTime. Para uma mensagem de texto, leia content.text.body. O histórico inclui mensagens visíveis para o cliente da mesma conversa, potencialmente abrangendo caixas de diálogo anteriores. O próprio dialogId de uma mensagem pode ser diferente da caixa de diálogo solicitada ou estar ausente em históricos mais antigos. Notas internas, resumos de transferência privada e mensagens internas do sistema são excluídos. As mensagens são retornadas em ordem crescente de ID de mensagem, da mais antiga para a mais recente. Omita after na primeira solicitação; transmita nextCursor inalterado como after em solicitações subsequentes até que seja null. O padrão de limit é 50, com um intervalo de 1 a 100. A lista de alvos de transferência usa o mesmo padrão de paginação.

Enviar uma resposta

botId e message são obrigatórios. sourceEventId e replyToMessageId são opcionais. A referência de resposta é um ID de mensagem do Inbox, como inboxMessage.id; não é um wamid.
Verifique status mesmo quando o HTTP retornar 200. accepted significa que a mensagem entrou no pipeline de envio, e não que chegou ao cliente. Uma resposta 200 também pode relatar failed; channelMessageId pode ainda não estar disponível. Use whatsapp.message.updated para acompanhar estados subsequentes, incluindo sent, delivered, read, failed, expired ou deleted. Correlacione o externalBotContext.inboxMessageId da confirmação com o inboxMessageId da resposta de envio. Inspecione whatsappMessage.errorCode e errorMessage em caso de falhas.

Tipos de mensagem

O objeto message usa o modelo padrão de mensagens do WhatsApp: type mais o campo de conteúdo correspondente. Exemplos incluem text, image, video, audio, document, sticker, location, contacts, interactive, template e reaction. Os requisitos existentes de envio e de modelo de mensagem do WhatsApp continuam sendo aplicados. Por exemplo, substitua o objeto message por:
Para mídia, forneça id ou link. Para estruturas de corpo de mensagem, consulte Enviar uma mensagem do WhatsApp. Envie a resposta por meio do endpoint do Inbox acima para que ele utilize as verificações de manipulador da caixa de diálogo e o contexto do Inbox. Não envie nem dependa de filterUnsubscribed ou filterBlocked nesta solicitação de mensagem do Inbox. As respostas do cliente podem incluir interactive.button_reply, interactive.list_reply, interactive.nfm_reply ou button. O campo response_json de uma resposta de Flow é uma string JSON. O tipo de entrada button não é um tipo de mensagem de saída para este endpoint.

Transferir para um atendente humano

Primeiro, liste as equipes ou agentes disponíveis para o número de negócios da caixa de diálogo:
Em vez disso, use type=agent para listar os membros. Cada destino retornado fornece o id e o type para a solicitação de transferência. O campo opcional online de um agente descreve a presença; ele não garante a atribuição imediata.
Você deve especificar um target com type (team ou agent) e id. Não há fallback humano padrão. O campo opcional reason aceita até 256 caracteres; o campo opcional summary aceita até 4.000 caracteres e não faz parte do histórico de mensagens visível para o cliente. A resposta contém outcome e o dialog atualizado. Os resultados são assigned, queued, team_unassigned ou unassigned. Verifique o resultado real em vez de presumir que um atendente humano aceitou a conversa. Uma transferência mantém o mesmo dialogId. Assim que seu agente perder a propriedade, pare de responder ou de tentar fechar essa caixa de diálogo.

Fechar uma caixa de diálogo resolvida

A resposta contém dialog com status=closed e canAct=false. Seu agente não pode continuar enviando mensagens ou transferindo essa caixa de diálogo fechada. Uma mensagem de cliente válida subsequente inicia uma nova caixa de diálogo e executa as regras de atribuição do número novamente.

Tratar erros e novas tentativas

As respostas de erro usam um objeto error com status, code, message e requestId. Guarde o ID da solicitação ao entrar em contato com o suporte da YCloud.
sourceEventId e X-Request-Id oferecem suporte ao rastreamento; nenhum deles é uma chave de idempotência. A API não oferece desduplicação entre solicitações. Uma nova tentativa cega após um resultado incerto pode enviar uma mensagem duplicada.
Monitore Exibir logs de entrega para falhas de Webhook. Mantenha IDs de eventos, IDs de diálogos, IDs de mensagens, IDs de solicitações e resultados de processamento. As novas tentativas de Webhook são limitadas; portanto, use consultas de diálogo e histórico para recuperar o contexto quando necessário.

Perguntas frequentes

Posso conectar um agente criado com meu próprio framework de IA?

Sim. Seu serviço deve receber e verificar os webhooks da YCloud e chamar a API REST do Inbox. Você controla como seu serviço gera respostas, acessa o conhecimento e chama suas próprias ferramentas.

Meu agente receberá todas as conversas do Inbox?

Não. Seu endpoint dedicado recebe eventos dentro do seu escopo de tratamento, juntamente com notificações relevantes de atribuição e encerramento e confirmações de suas próprias mensagens enviadas. Novas mensagens após uma transferência para um atendente humano não são encaminhadas para o agente anterior. Eventos gerados anteriormente ainda podem chegar com atraso.

Meu agente pode usar mensagens de diálogos anteriores?

Sim. O endpoint de histórico retorna o histórico visível ao cliente para a conversa, incluindo diálogos anteriores. Use o dialogId da própria mensagem quando disponível; não presuma que todas as mensagens retornadas pertencem à sessão de atendimento atual.

O que acontece se eu alterar o agente atribuído a um número?

Os diálogos abertos atualmente gerenciados por um bot são reatribuídos de forma assíncrona de acordo com o comportamento de roteamento do número. O agente que está saindo recebe assignmentRole=outgoing e deve interromper seu trabalho. O novo agente recebe reason=phone_binding_changed com assignmentRole=incoming; ele deve consultar o diálogo atual e o histórico antes de continuar. O ID do diálogo e o histórico permanecem inalterados. Os diálogos atendidos atualmente por um humano não são transferidos para o novo bot por meio dessa reatribuição de número. Depois que outro bot o substitui, o bot antigo não pode mais consultar esse diálogo por meio desses endpoints.

A resposta do meu webhook se torna a resposta para o cliente?

Não. Retorne 2xx para confirmar o recebimento do evento e, em seguida, envie a resposta ao cliente por meio de POST /v2/inbox/dialogs/{dialogId}/messages.

Por que meu agente recebe actionable=true para sua própria resposta?

O campo descreve quem estava gerenciando o diálogo aberto quando o evento foi gerado. Eventos de criação de saída e confirmações de entrega podem, portanto, ter actionable=true. Acione uma resposta normal de IA apenas para um evento inbox.message.created de entrada e considere as alterações no responsável pelo diálogo em tempo real.