Saltar para o conteúdo

Deep Dives

Deep diveArtigoAI AgentFunctionsIntegraçõesCanais — WhatsAppContexto ExternoResume

Quando o sinal chega, a conversa continua

Um cliente pede um aumento de limite no WhatsApp. Quem pode aprovar não está nesse chat. Com Contexto externo você pausa a execução e continua o mesmo fio quando a decisão chega.

Um cliente pede um aumento de limite no WhatsApp. O Agent reúne o histórico, mas quem pode aprovar a solicitação não está nesse chat: pode estar em outro time, outro sistema ou até outro horário.

A conversa chegou a um ponto em que ainda não existe uma resposta.

Se você obriga a pessoa a voltar depois e perguntar «já me aprovaram?», transformou a conversa num ticket. Com Contexto externo você pode fazer outra coisa: pausar a execução e continuar o mesmo fio quando a decisão chegar.

O Agent pausa, algo lá fora resolve, POST em Resume. O quadro do meio é um exemplo: e-mail, Slack, um pagamento ou um ticket.
O Agent espera. Algo lá fora acontece. Resume continua a conversa.

O que acontece no meio pode mudar. Pode ser uma aprovação por e-mail, uma mensagem no Slack, um pagamento confirmado ou o fechamento de um ticket. Para o Agent, o mecanismo é o mesmo.

A conversa pode ficar em pausa

Na aba Contexto do AI Agent está Adicionar contexto externo. Ali uma interação pode parar sem encerrar a execução.

AI Agent, aba Contexto: Adicionar contexto externo com o POST ao Resume, o header x-api-key e o corpo com executionId.
Aba Contexto · Adicionar contexto externo. O POST e o executionId estão ali.

A Jelou guarda o executionId dessa execução. Quando o sistema externo tiver uma resposta, pode usá-lo para continuar exatamente aquele fio.

Isso permite separar dois momentos que não precisam acontecer juntos:

  1. o usuário faz uma solicitação;
  2. algo lá fora a resolve.

A pessoa não precisa manter o chat aberto nem escrever de novo para o processo continuar.

Uma execução pausada pode ser retomada durante 24 horas. Depois desse prazo, o executionId deixa de estar disponível para o Resume.

Voltar exige um sinal

Para continuar a execução, o sistema externo faz esse POST.

executionId identifica a conversa que estava esperando. message entrega ao Agent o resultado que acabou de chegar.

A API key nunca deve viajar em um link, query param ou e-mail. Quem tiver essa chave pode retomar execuções.

Não importa quem origina o sinal. Se puder fazer o POST de Resume com o executionId certo, pode colocar a conversa de novo em movimento.

Um exemplo: aprovar por e-mail

Voltemos ao aumento de limite.

O Agent reúne a solicitação, envia um e-mail ao aprovador e pausa a interação. O e-mail tem duas ações: Aprovar e Rejeitar.

E-mail do Gmail: solicitação pendente de aprovação para compra de um carro, 10.000 USD, com links Aprovar e Rejeitar.
O e-mail leva a decisão e o executionId. A API key fica fora.

Neste exemplo, o clique chega a uma Function. A Function guarda a API key com segurança e faz a chamada ao Resume:

A Function chama o Resume
await fetch("https://gateway.jelou.ai/workflows/v1/skills/resume", {
  method: "POST",
  headers: {
    "x-api-key": apiKey,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    executionId,
    message: "A solicitação foi aprovada",
    pauseInteraction: false,
  }),
});

A Function não é parte obrigatória do padrão. Está aí porque um link de e-mail não deve levar a API key.

Se o sinal viesse de um gateway de pagamento, por exemplo, o webhook dele poderia fazer o mesmo POST direto.

A pessoa não precisa voltar

Quando o Resume chega, o Agent recebe o resultado e continua de onde parou.

Mesmo fio do WhatsApp: a pessoa pede um aumento de 10.000 USD, o Agent avisa que ficou pendente e às 10:10 a aprovação chega sem uma nova mensagem da pessoa.
A resposta chega no mesmo fio sem uma nova mensagem da pessoa.

No exemplo foi um e-mail. Poderia ter sido Slack, um CRM, uma aprovação interna, um webhook ou a confirmação de um pagamento.

O sistema externo muda. A conversa não precisa saber: espera um sinal e, quando ele chega, continua.

O usuário não deveria ter que voltar para o processo continuar.

Quer este exemplo no seu Brain?

O padrão já está. Se você quer o mesmo loop na sua conta, são duas peças: o workflow e a Function.

O workflow: use o template

O template já traz o AI Agent do exemplo (solicitações que precisam de aprovação), Gmail para enviar o e-mail com Aprovar e Rejeitar, e Contexto externo para pausar. Você instala no seu Brain e conecta sua conta do Gmail.

A Function: você cria

O clique do e-mail não pode levar a API key. Por isso o link aponta para uma Function sua: recebe executionId e decision, e faz o POST no Resume. Crie com o início rápido de Functions, deixe-a pública (um link do Gmail não envia token) e guarde a API key num secret.

A Function recebe o clique e chama o Resume
import { define, z } from "@jelou/functions";

export default define({
  name: "resume-aprovacao",
  description: "Recebe Aprovar ou Rejeitar e chama o Resume",
  input: z.object({
    executionId: z.string(),
    decision: z.enum(["approved", "rejected"]),
  }),
  config: {
    public: true,
    methods: ["GET"],
    mcp: false,
  },
  handler: async (input, ctx) => {
    const apiKey = ctx.env.get("JELOU_API_KEY");
    await fetch("https://gateway.jelou.ai/workflows/v1/skills/resume", {
      method: "POST",
      headers: {
        "x-api-key": apiKey,
        "Content-Type": "application/json",
      },
      body: JSON.stringify({
        executionId: input.executionId,
        message:
          input.decision === "approved"
            ? "A solicitação foi aprovada"
            : "A solicitação foi rejeitada",
        pauseInteraction: false,
      }),
    });
    return { ok: true };
  },
});

Faça o deploy, coloque essa URL nos links do e-mail e teste: o WhatsApp pede, o e-mail chega, Aprovar, o mesmo fio continua.

Suporte

Ficou alguma dúvida?

Abra pela sua conta.

Como nos escrever