Table of Contents

Workers de IA

Os workers do gateway de IA são recursos do Gateways de IA que permitem controlar o comportamento de seus recursos remotamente através de eventos.

Com um controlador externo configurado, eventos são enviados para ele, e a resposta do seu controlador define se aquela ação deve continuar, ser abortada ou configurada.

Quando um evento é acionado no lado da AIVAX, uma requisição POST é disparada ao worker configurado com informações do evento disparado. Com base em sua resposta, a ação pode ser anulada ou configurada. Não há nenhum cache - a requisição é feita em todos os eventos que ocorrem no seu gateway de IA.

O tempo de processamento da resposta acrescenta uma latência entre toda ação do gateway, no entanto, adiciona uma camada de controle e moderação que você pode controlar à qualquer momento.

Funcionamento

Quando um evento é acionado, uma requisição POST é disparada ao seu worker seguindo o formato abaixo:

{
    "gatewayId": "019a6afb-5a03-7b83-a1a2-760bd1ecd11c",
    "moment": "2025-12-29T17:04:39",
    "event": {
        "name": "message.received",
        "data": {
            "messages": [
                {
                    "role": "system",
                    "content": "User local date is Monday, December 29, 2025 (timezone is America/Sao_Paulo)"
                },
                {
                    "role": "user",
                    "content": "bom dia"
                },
                {
                    "role": "assistant",
                    "content": "Bom dia! 😊 Como posso te ajudar hoje?"
                },
                {
                    "role": "user",
                    "content": "tudo bem?"
                }
            ],
            "origin": [
                "SessionsApi"
            ],
            "externalUserId": "mini-app-session@hse075q0q5gftm6jmitvi5",
            "metadata": {}
        }
    }
}

O exemplo acima ilustra uma mensagem do evento message.received com os seus argumentos do evento.

Tipos de resposta

Após o envio da requisição, a AIVAX aguarda a resposta do seu worker. Existem três tipos de resposta possíveis:

Resposta Comportamento
Resposta OK (2xx) Continua e prossegue com a execução normal do evento.
Outras respostas Aborta e interrompe a execução do evento.
Content-Type application/json+worker-action Executa as ações especificadas na resposta e continua com a execução.

Eventos

Atualmente, os eventos que podem ser enviados para seu worker são:

message.received

Enviado quando uma mensagem é recebida pelo gateway. Esse evento é acionado com todo o histórico de mensagens da conversa.

{
    "name": "message.received",
    "data": {
        "messages": [],
        "origin": ["SessionsApi"],
        "externalUserId": "mini-app-session@lot1xc9k03g2my3j4w2y1",
        "metadata": {}
    }
}

Ações disponíveis

Para executar ações no evento message.received, retorne uma resposta com o header Content-Type: application/json+worker-action e o corpo no formato:

{
    "type": "message.received.response",
    "data": {
        "rewrites": [
            // lista de ações
        ]
    }
}

As ações disponíveis para o campo rewrites são:

Ação Descrição Parâmetros
clear Remove todas as mensagens do contexto. Nenhum
add-message Adiciona uma mensagem ao contexto. message: objeto de mensagem OpenAI-compatível (ex: role e content)
remove-message Remove uma mensagem do contexto pelo índice. index: índice da mensagem a ser removida
add-system Adiciona uma instrução de sistema. message: texto da instrução
add-tool Adiciona uma ferramenta ao contexto. tool: objeto JSON da ferramenta
add-protocol-tool Adiciona uma definição de protocol function ao contexto. tool: objeto definição da protocol function
Exemplos de ações

Limpar e adicionar mensagem:

{
    "type": "message.received.response",
    "data": {
        "rewrites": [
            {
                "type": "clear"
            },
            {
                "type": "add-message",
                "message": {
                    "role": "user",
                    "content": "Mensagem substituída pelo worker."
                }
            }
        ]
    }
}

Adicionar instrução de sistema:

{
    "type": "message.received.response",
    "data": {
        "rewrites": [
            {
                "type": "add-system",
                "message": "Responda sempre em português formal."
            }
        ]
    }
}

Remover mensagem por índice:

{
    "type": "message.received.response",
    "data": {
        "rewrites": [
            {
                "type": "remove-message",
                "index": 0
            }
        ]
    }
}

Exemplos

Bloqueando usuários não autorizados

O exemplo abaixo ilustra um Cloudflare Worker que autentica uma conversa no Telegram com base no nome de usuário:

export default {
  async fetch(request, env, ctx) {
    const CHECKING_GATEWAY_ID = "0197dda5-985f-7c76-96e5-0d0451c596e5";
    const ALLOWED_USERNAMES = ["myusername"];

    if (request.method == "POST") {
      const requestData = await request.json();
      const { event, gatewayId } = requestData;

      if (gatewayId === CHECKING_GATEWAY_ID &&
        event.name == "message.received" &&
        event.data.externalUserId?.startsWith("zp_telegram:")) {
        
        const telegramUsername = event.data.externalUserId.split(':')[0].split('@')[0];

        if (!ALLOWED_USERNAMES.includes(telegramUsername)) {
          return new Response("User is not authed", { status: 400 });
        }
      }
    }

    return new Response();
  }
};

Interceptando e modificando mensagens

O exemplo abaixo demonstra como interceptar uma mensagem e substituí-la por outra quando o usuário não está autorizado:

export default {
  async fetch(request, env, ctx) {
    const CHECKING_GATEWAY_ID = "0197dda5-985f-7c76-96e5-0d0451c596e5";

    if (request.method == "POST") {
      const requestData = await request.json();
      const { event, gatewayId } = requestData;

      if (gatewayId === CHECKING_GATEWAY_ID && event.name == "message.received") {
        const userIsPaid = await checkUserSubscription(event.data.externalUserId);

        if (!userIsPaid) {
          return new Response(JSON.stringify({
            type: "message.received.response",
            data: {
              rewrites: [
                { type: "clear" },
                {
                  type: "add-message",
                  message: {
                    role: "user",
                    content: "O usuário enviou uma mensagem mas ela foi excluída pelo sistema. Informe ao usuário que ele não pagou sua assinatura mensal para continuar."
                  }
                }
              ]
            }
          }), {
            headers: { "Content-Type": "application/json+worker-action" }
          });
        }
      }
    }

    return new Response();
  }
};

async function checkUserSubscription(externalUserId) {
  // Implemente sua lógica de verificação de assinatura aqui
  return true;
}