Principal Recursos avançados explicados Como configurar uma conexão WebSocket?

Como configurar uma conexão WebSocket?

Última atualização em Jan 14, 2026

Como configurar uma conexão WebSocket?

Os WebSockets estabelecem uma conexão contínua entre o cliente e o servidor, permitindo a comunicação bidirecional. O PortoMicro utiliza essa conexão para fornecer atualizações em tempo real sobre eventos da plataforma. Para se conectar ao WebSocket do PortoMicro, basta fornecer um token e seguir as instruções de configuração descritas neste guia.

Observação : Este recurso é experimental e a documentação pode ser alterada a cada versão. Além disso, a compatibilidade com versões anteriores não pode ser garantida, portanto, é importante certificar-se de que está usando a versão mais recente da implementação.

Por que devo usar uma conexão WebSocket?

Uma conexão WebSocket permite atualizações de dados em tempo real, sendo ideal para clientes como o SDK do PortoMicro para Android ou iOS. Isso ajuda a atualizar o painel sem a necessidade de recarregar a página. Consequentemente, pode melhorar a experiência do usuário e aumentar a produtividade do agente.

Como configurar uma conexão WebSocket com o PortoMicro?

Para configurar uma conexão WebSocket com o PortoMicro, você precisa iniciar uma conexão com o token de autenticação PubSub fornecido pelo PortoMicro. A URL para a conexão é  wss://<your-installation-url>/cable. Se você estiver usando o PortoMicro Cloud, pode usar **wss://app.chatwoot.com/cable**como URL.

Um token PubSub é um token usado para autenticar um cliente ao se conectar a um serviço PubSub (publicação e assinatura). O cliente deve apresentar esse token ao serviço para estabelecer uma conexão e começar a publicar ou assinar mensagens.

Existem dois tipos de tokens PubSub disponíveis no PortoMicro, conforme listado abaixo.

  1. Token PubSub do usuário : Este token possui os privilégios de um agente/administrador e receberá todos os eventos listados posteriormente nesta página. Você pode obter o token PubSub chamando a  API de Perfil .

  2. Token PubSub de Contato : O PortoMicro gera um token PubSub exclusivo para cada sessão de um contato. Esse token pode ser usado para conectar-se ao WebSocket e receber atualizações em tempo real para a mesma sessão. Quando um contato é criado por meio das APIs públicas, o token **pubsub_token**é incluído na resposta. Esse token concede acesso apenas a eventos relacionados à sessão atual, como conversation.createdupdate   conversation.status_changed,  message.createdupdate,  message.updatedupdate,   **conversation_typing_on**update e  **conversation_typing_off** update  presence.update.

Consulte  as APIs do cliente  para criar integrações em tempo real voltadas para o cliente usando o PortoMicro.

Observação : Este token pode ser alterado periodicamente dependendo do seu tipo de instalação. Certifique-se de estar usando o token mais recente.

Como conectar-se ao WebSocket do PortoMicro?

Para se conectar ao WebSocket do PortoMicro, use o comando **subscribe**e inclua seu pubSubToken, **accountId**e userId(se estiver usando um token de usuário) na solicitação de conexão. Aqui está um exemplo de como você pode se conectar ao PortoMicro.

// Add a helper method to convert JSON to a string
const stringify = (payload = {}) => JSON.stringify(payload);

const pubSubToken = "<contact/user-pub-sub-token>";
const accountId = "<your-account-id-in-integer>";
const userId = "<user-id-in-integer-if-using-user-token>";
const connection = new WebSocket(
  "wss://app.chatwoot.com/cable"
);

connection.send(
  stringify({
    command: "subscribe",
    identifier: stringify({
      channel: "RoomChannel",
      pubsub_token: pubSubToken,
      account_id: accountId,
      user_id: userId,
    }),
  })
);

// The expected string in connection.send is of the format:
// {"command":"subscribe","identifier":"{\\"channel\\":\\"RoomChannel\\",\\"pubsub_token\\":\\"your-pubsub-token\\",\\"account_id\\": account_id_integer,\\"user_id\\":user_id_integer }"}

Publicando presença no servidor WebSocket

Para manter o status dos seus usuários online no PortoMicro, você pode enviar um evento de atualização de presença para o PortoMicro a cada 30 segundos. Essa ação manterá o status do agente/contato online.

Como atualizar a presença de um agente/administrador?

Para atualizar a presença de um agente ou administrador, envie a seguinte carga útil para o servidor:

const userPayload = stringify({
  command: "message",
  identifier: stringify({
    channel: "RoomChannel",
    pubsub_token: "<user-pubsub-token>",
    account_id: accountId,
    user_id: userId,
  }),
  data: stringify({ action: "update_presence" }),
});

connection.send(userPayload);
// The expected string in connection.send is of the format:
// {"command":"message","identifier":"{\\"channel\\":\\"RoomChannel\\",\\"pubsub_token\\":\\"your-pubsub-token\\",\\"account_id\\": account_id_integer,\\"user_id\\":user_id_integer ","data":"{\\"action\\":\\"update_presence\\"}"}

Como atualizar a presença de um contato?

Para atualizar a presença de um contato, envie a seguinte carga útil para o servidor:

const agentPayload = stringify({
  command: "message",
  identifier: stringify({
    channel: "RoomChannel",
    pubsub_token: "<user-pubsub-token>",
  }),
  data: stringify({ action: "update_presence" }),
});

connection.send(agentPayload);
// The expected string in connection.send is of the format:
// {"command":"message","identifier":"{\\"channel\\":\\"RoomChannel\\",\\"pubsub_token\\":\\"your-pubsub-token\\","data":"{\\"action\\":\\"update_presence\\"}"}

Carga útil do WebSocket

Objetos

Um evento pode conter qualquer um dos seguintes objetos como carga útil. Os diferentes tipos de objetos suportados no PortoMicro são os seguintes.

Conversa

A seguinte carga útil será retornada para uma conversa.

{
  "additional_attributes": {
    "browser": {
      "device_name": "string",
      "browser_name": "string",
      "platform_name": "string",
      "browser_version": "string",
      "platform_version": "string"
    },
    "referer": "string",
    "initiated_at": {
      "timestamp": "iso-datetime"
    }
  },
  "can_reply": "boolean",
  "channel": "string",
  "id": "integer",
  "inbox_id": "integer",
  "contact_inbox": {
    "id": "integer",
    "contact_id": "integer",
    "inbox_id": "integer",
    "source_id": "string",
    "created_at": "datetime",
    "updated_at": "datetime",
    "hmac_verified": "boolean"
  },
  "messages": ["Array of message objects"],
  "meta": {
    "sender": {
      // Contact Object
    },
    "assignee": {
      // User Object
    }
  },
  "status": "string",
  "unread_count": "integer",
  "agent_last_seen_at": "unix-timestamp",
  "contact_last_seen_at": "unix-timestamp",
  "timestamp": "unix-timestamp",
  "account_id": "integer"
}

Contato

A seguinte carga útil será retornada para um contato.

{
  "additional_attributes": "object",
  "custom_attributes": "object",
  "email": "string",
  "id": "integer",
  "identifier": "string or null",
  "name": "string",
  "phone_number": "string or null",
  "thumbnail": "string"
}

Usuário

A seguinte carga útil será retornada para um agente/administrador.

{
  "id": "integer",
  "name": "string",
  "available_name": "string",
  "avatar_url": "string",
  "availability_status": "string",
  "thumbnail": "string"
}

Mensagem

A seguinte carga útil será retornada para uma mensagem.

{
  "id": "integer",
  "content": "string",
  "account_id": "integer",
  "inbox_id": "integer",
  "message_type": "integer",
  "created_at": "unix-timestamp",
  "updated_at": "datetime",
  "private": "boolean",
  "status": "string",
  "source_id": "string / null",
  "content_type": "string",
  "content_attributes": "object",
  "sender_type": "string",
  "sender_id": "integer",
  "external_source_ids": "object",
  "sender": {
    "type": "string - contact/user"
    // User or Contact Object
  }
}

Notificação

A seguinte carga útil será retornada para uma notificação.

{
  "id": "integer",
  "notification_type": "string",
  "primary_actor_type": "string",
  "primary_actor_id": "integer",
  "primary_actor": {
    "can_reply": "boolean",
    "channel": "string",
    "id": "integer",
    "inbox_id": "integer",
    "meta": {
      "assignee": {
        "id": "integer",
        "name": "string",
        "available_name": "string",
        "avatar_url": "string",
        "type": "user",
        "availability_status": "string",
        "thumbnail": "string"
      },
      "hmac_verified": "boolean"
    },
    "agent_last_seen_at": "unix-timestamp",
    "contact_last_seen_at": "unix-timestamp",
    "timestamp": "unix-timestamp",
  },
  "read_at": "unix-timestamp",
  "secondary_actor": "object/null",
  "created_at":"unix-timestamp",
  "account_id": "integer",
  "push_message_title": "string"
}

Identificador

Cada evento terá um  identifier atributo no seguinte formato.

{
  "identifier": "{\\"channel\\":\\"RoomChannel\\",\\"pubsub_token\\":\\"token\\",\\"account_id\\":id,\\"user_id\\":user_id}"
}

Mensagem

Cada evento incluirá um  message atributo que retornará o nome do evento, bem como os dados associados a ele. Para ver a lista de eventos, consulte a documentação abaixo.

Tipos de Eventos

conversa.criada

Este evento é acionado quando uma nova conversa é iniciada. Se você estiver inscrito no token PubSub do contato, este evento incluirá apenas dados relacionados à sessão específica associada ao token PubSub.

Disponível para : agente/administrador, contato

{
  "message": {
    "event": "conversation.created",
    "data": {
      // Conversation object will be available here
    }
  }
}

conversa.ler

Este evento é acionado e enviado aos agentes/administradores que têm acesso à caixa de entrada quando um contato lê uma mensagem.

Disponível para : agente/administrador

{
  "message": {
    "event": "conversation.read",
    "data": {
      // Conversation object will be available here
    }
  }
}

mensagem.criada

Este evento é acionado e enviado aos agentes, administradores e contatos quando uma nova mensagem é criada em uma conversa à qual eles têm acesso.

Disponível para : agente/administrador, contato

{
  "message": {
    "event": "message.created",
    "data": {
      // Message object will be available here
    }
  }
}

mensagem.atualizada

Este evento é acionado e enviado aos agentes, administradores e contatos quando uma mensagem é atualizada em uma conversa à qual eles têm acesso.

Disponível para : agente/administrador, contato

{
  "message": {
    "event": "message.updated",
    "data": {
      // Message object will be available here
    }
  }
}

conversa.status_alterado

Este evento é enviado aos agentes, administradores e contatos quando o status de uma conversa é atualizado.

Disponível para : agente/administrador, contato

{
  "message": {
    "event": "conversation.status_changed",
    "data": {
      // Conversation object will be available here
    }
  }
}

conversa.digitando_ligado

Este evento é enviado aos agentes, administradores e contatos quando um contato ou um agente começa a digitar uma resposta.

Disponível para : agente/administrador, contato

{
  "message": {
    "event": "conversation.typing_on",
    "data": {
      "conversation": {
        // Conversation object will be available here
      },
      "user": {
        // Contact / Agent,Admin User object will be available here.
      },
      "is_private": "boolean", // Shows whether the agent is typing a private note or not.
      "account_id": "integer"
    }
  }
}

conversa.digitando_desligado

Este evento é enviado aos agentes, administradores e contatos quando um contato ou um agente termina de digitar uma resposta.

Disponível para : agente/administrador, contato

{
  "message": {
    "event": "conversation.typing_off",
    "data": {
      "conversation": {
        // Conversation object will be available here
      },
      "user": {
        // Contact / User object will be available here.
      },
      "account_id": "integer"
    }
  }
}

atribuído.alterado

Este evento é enviado aos agentes/administradores com acesso a uma caixa de entrada quando o agente atribuído é alterado.

Disponível para : agente/administrador

{
  "message": {
    "event": "assignee.changed",
    "data": {
      // Conversation object will be available here
    }
  }
}

equipe.mudou

Este evento é enviado aos agentes/administradores com acesso a uma caixa de entrada quando a equipe atribuída é alterada.

Disponível para : agente/administrador

{
  "message": {
    "event": "team.changed",
    "data": {
      // Conversation object will be available here
    }
  }
}

conversa.contato_alterado

Este evento é enviado aos agentes/administradores quando dois contatos são mesclados e todas as suas conversas são consolidadas em um único contato.

Disponível para : agente/administrador

{
  "message": {
    "event": "conversation.contact_changed",
    "data": {
      // Conversation object will be available here
    }
  }
}

contato.criado

Este evento é enviado aos agentes/administradores quando um contato é criado.

Disponível para : agente/administrador

{
  "message": {
    "event": "contact.created",
    "data": {
      // Contact object will be available here
    }
  }
}

contato.atualizado

Este evento é enviado aos agentes/administradores quando um contato é atualizado.

Disponível para : agente/administrador

{
  "message": {
    "event": "contact.updated",
    "data": {
      // Contact object will be available here
    }
  }
}

atualização de presença

Disponível tanto para o agente quanto para o contato, este evento fornece atualizações em tempo real sobre o status de disponibilidade dos usuários no sistema. O evento enviado aos contatos não incluirá informações sobre o status de disponibilidade de outros contatos.

Disponível para : agente/administrador

{
  "message": {
    "event": "presence.update",
    "data": {
      "account_id": "integer",
      "users": {
        "user-id": "string"
      },
      "contacts": {
        "contact-id": "string"
      }
    }
  }
}

notificação_criada

Este evento é enviado aos agentes/administradores quando uma notificação é criada.

Disponível para : agente/administrador