Pular para o conteúdo principal

Documentação oficial desta página · v0.20.6

WeCom (WeChat Corporativo)

Conecte o Hermes ao WeCom (企业微信), a plataforma de mensagens corporativas da Tencent. O adaptador usa o gateway WebSocket de AI Bot do WeCom para comunicação bidirecional em tempo real — sem precisar de endpoint público nem de webhook.

Veja também: WeCom Callback para configurar o webhook de entrada.

Pré-requisitos​

  • Uma conta de organização no WeCom
  • Um AI Bot criado no console de administração do WeCom
  • O Bot ID e o Secret da página de credenciais do bot
  • Pacotes Python: aiohttp e httpx

Instalação​

Passo 1: crie um AI Bot​

hermes gateway setup

Escolha WeCom e leia o QR code com o aplicativo do WeCom no celular. O Hermes cria automaticamente uma aplicação de bot com as permissões certas e salva as credenciais.

O assistente de instalação vai:

  1. Mostrar um QR code no seu terminal
  2. Esperar você ler o código com o app do WeCom
  3. Buscar automaticamente o Bot ID e o Secret
  4. Guiar você pela configuração do controle de acesso

Alternativa: instalação manual​

Se a criação por QR code não estiver disponível, o assistente cai para a entrada manual:

  1. Entre no console de administração do WeCom
  2. Vá em Aplicações → Criar aplicação → AI Bot
  3. Configure o nome e a descrição do bot
  4. Copie o Bot ID e o Secret da página de credenciais
  5. Rode hermes gateway setup, escolha WeCom e informe as credenciais quando pedido
aviso

Mantenha o Bot Secret em segredo. Quem tem ele consegue se passar pelo seu bot.

Passo 2: configure o Hermes​

hermes gateway setup

Escolha WeCom e siga as perguntas. O assistente guia você por:

  • Credenciais do bot (por leitura de QR code ou entrada manual)
  • Ajustes de controle de acesso (lista de permissão, modo de pareamento ou acesso aberto)
  • Canal principal para notificações

Opção B: configuração manual​

Acrescente o seguinte ao ~/.hermes/.env:

WECOM_BOT_ID=seu-bot-id
WECOM_SECRET=seu-secret

# Opcional: restringe o acesso
WECOM_ALLOWED_USERS=user_id_1,user_id_2

# Opcional: canal principal para cron/notificações
WECOM_HOME_CHANNEL=chat_id

Passo 3: suba o gateway​

hermes gateway

Recursos​

  • Transporte por WebSocket — conexão persistente, sem precisar de endpoint público
  • Mensagens diretas e em grupo — políticas de acesso configuráveis
  • Listas de remetentes permitidos por grupo — controle fino de quem pode interagir em cada grupo
  • Suporte a mídia — upload e download de imagens, arquivos, voz e vídeo
  • Mídia criptografada em AES — descriptografia automática dos anexos de entrada
  • Contexto de citação — preserva o encadeamento das respostas
  • Renderização de Markdown — respostas com texto formatado
  • Correlação de resposta — as respostas são correlacionadas ao contexto da mensagem de entrada
  • Reconexão automática — recuo exponencial quando a conexão cai
Streaming e indicadores de digitação

O adaptador do WeCom transmite respostas nativamente pelo protocolo msgtype: "stream" do WeCom: o cliente mostra um balão de "pensando/digitando" assim que o turno começa, e a resposta é renderizada token a token num único balão, conforme o modelo gera. O progresso das chamadas de ferramenta entra no mesmo balão. O streaming nativo vem ligado por padrão (display.platforms.wecom.streaming: true no config.yaml); defina como false para voltar à entrega de uma vez só.

Opções de configuração​

Defina estas em config.yaml, sob platforms.wecom.extra:

ChavePadrãoDescrição
bot_id—Bot ID do AI Bot do WeCom (obrigatório)
secret—Secret do AI Bot do WeCom (obrigatório)
websocket_urlwss://openws.work.weixin.qq.comURL do gateway WebSocket
dm_policyopenAcesso por mensagem direta: open, allowlist, disabled, pairing
group_policyopenAcesso em grupo: open, allowlist, disabled
allow_from[]IDs de usuário liberados para mensagem direta (quando dm_policy=allowlist)
group_allow_from[]IDs de grupo liberados (quando group_policy=allowlist)
groups{}Configuração por grupo (veja abaixo)
stream_keepalive_enabledfalseEnvia quadros periódicos de keepalive para renovar a janela de ~6 minutos do fluxo de resposta do WeCom em turnos longos
stream_keepalive_interval_seconds120Cadência dos quadros de keepalive quando ligado
stream_safe_duration_seconds330Idade do fluxo a partir da qual a finalização prefere o envio proativo, mais confiável

Políticas de acesso​

Política de mensagem direta​

Controla quem pode mandar mensagem direta para o bot:

ValorComportamento
openQualquer um pode mandar mensagem direta (padrão)
allowlistSó os IDs de usuário em allow_from podem mandar
disabledTodas as mensagens diretas são ignoradas
pairingModo de pareamento (para a configuração inicial)
WECOM_DM_POLICY=allowlist

Política de grupo​

Controla em quais grupos o bot responde:

ValorComportamento
openO bot responde em todos os grupos (padrão)
allowlistO bot só responde nos IDs de grupo listados em group_allow_from
disabledTodas as mensagens de grupo são ignoradas
WECOM_GROUP_POLICY=allowlist

Listas de remetentes permitidos por grupo​

Para um controle mais fino, você pode restringir quais usuários podem interagir com o bot dentro de grupos específicos. Isso é configurado no config.yaml:

platforms:
wecom:
enabled: true
extra:
bot_id: "seu-bot-id"
secret: "seu-secret"
group_policy: "allowlist"
group_allow_from:
- "group_id_1"
- "group_id_2"
groups:
group_id_1:
allow_from:
- "user_alice"
- "user_bob"
group_id_2:
allow_from:
- "user_charlie"
"*":
allow_from:
- "user_admin"

Como funciona:

  1. Os controles group_policy e group_allow_from determinam se o grupo é permitido, para começar.
  2. Se o grupo passa na checagem de topo, a lista groups.<group_id>.allow_from (se existir) restringe ainda mais quais remetentes daquele grupo podem interagir com o bot.
  3. Uma entrada de grupo curinga "*" serve de padrão para os grupos que não estão listados explicitamente.
  4. As entradas da lista aceitam o curinga * para liberar todos os usuários, e não diferenciam maiúsculas de minúsculas.
  5. As entradas podem, opcionalmente, usar o formato com prefixo wecom:user: ou wecom:group: — o prefixo é removido automaticamente.

Se nenhum allow_from estiver configurado para um grupo, todos os usuários daquele grupo são permitidos (supondo que o próprio grupo passe na checagem de política de topo).

Suporte a mídia​

Entrada (recebimento)​

O adaptador recebe anexos de mídia dos usuários e guarda em cache local para o agente processar:

TipoComo é tratado
ImagensBaixadas e guardadas em cache local. Aceita imagens por URL e codificadas em base64.
ArquivosBaixados e guardados em cache. O nome do arquivo é preservado da mensagem original.
VozA transcrição em texto da mensagem de voz é extraída, quando disponível.
Mensagens mistasMensagens de tipo misto do WeCom (texto + imagens) são analisadas e todos os componentes extraídos.

Mensagens citadas: a mídia de mensagens citadas (respondidas) também é extraída, para que o agente tenha contexto sobre o que o usuário está respondendo.

Descriptografia de mídia com AES​

O WeCom criptografa alguns anexos de mídia de entrada com AES-256-CBC. O adaptador cuida disso automaticamente:

  • Quando um item de mídia de entrada traz o campo aeskey, o adaptador baixa os bytes criptografados e descriptografa com AES-256-CBC e padding PKCS#7.
  • A chave AES é o valor do campo aeskey decodificado de base64 (precisa ter exatamente 32 bytes).
  • O IV é derivado dos 16 primeiros bytes da chave.
  • Isso exige o pacote Python cryptography (pip install cryptography).

Não é preciso configurar nada — a descriptografia acontece de forma transparente quando chega mídia criptografada.

Saída (envio)​

MétodoO que enviaLimite de tamanho
sendMensagens de texto em Markdown4000 caracteres
send_image / send_image_fileMensagens nativas de imagem10 MB
send_documentAnexos de arquivo20 MB
send_voiceMensagens de voz (só formato AMR para voz nativa)2 MB
send_videoMensagens de vídeo10 MB

Upload em pedaços: os arquivos são enviados em pedaços de 512 KB, por um protocolo de três etapas (init → pedaços → finish). O adaptador cuida disso automaticamente.

Rebaixamento automático: quando a mídia passa do limite de tamanho do tipo nativo mas fica abaixo do limite absoluto de 20 MB por arquivo, ela é enviada automaticamente como anexo de arquivo genérico:

  • Imagens > 10 MB → enviadas como arquivo
  • Vídeos > 10 MB → enviados como arquivo
  • Voz > 2 MB → enviada como arquivo
  • Áudio que não seja AMR → enviado como arquivo (o WeCom só aceita AMR para voz nativa)

Arquivos que passam do limite absoluto de 20 MB são recusados, com uma mensagem informativa enviada ao chat.

Respostas em modo de resposta​

Quando o bot recebe uma mensagem pelo callback do WeCom, o adaptador guarda o ID da requisição de entrada. Se uma resposta é enviada enquanto o contexto da requisição ainda está ativo, o adaptador usa o modo de resposta do WeCom (aibot_respond_msg) para correlacionar a resposta diretamente à mensagem de entrada. Isso deixa a conversa mais natural no cliente do WeCom.

Quando há um fluxo nativo de resposta ativo, a resposta é transmitida aos poucos por quadros msgtype: "stream" em modo de resposta. Se o contexto da requisição de entrada expirou ou não está disponível (ou se um quadro do fluxo falha), o adaptador cai para o envio proativo de mensagem, via aibot_send_msg.

O modo de resposta também funciona para mídia: a mídia enviada pode ir como resposta à mensagem de origem.

Conexão e reconexão​

O adaptador mantém uma conexão WebSocket persistente com o gateway do WeCom em wss://openws.work.weixin.qq.com.

Ciclo de vida da conexão​

  1. Conectar: abre uma conexão WebSocket e envia um quadro de autenticação aibot_subscribe com o bot_id e o secret.
  2. Heartbeat: envia quadros de ping no nível da aplicação a cada 30 segundos, para manter a conexão viva.
  3. Escutar: lê continuamente os quadros de entrada e despacha os callbacks de mensagem.

Comportamento de reconexão​

Quando a conexão cai, o adaptador reconecta com recuo exponencial:

TentativaEspera
1ª tentativa2 segundos
2ª tentativa5 segundos
3ª tentativa10 segundos
4ª tentativa30 segundos
5ª tentativa em diante60 segundos

Depois de cada reconexão bem-sucedida, o contador de recuo volta a zero. Todas as futures de requisição pendentes falham na desconexão, para que quem chamou não fique travado para sempre.

Deduplicação​

As mensagens de entrada são deduplicadas por ID de mensagem, com uma janela de 5 minutos e cache máximo de 1000 entradas. Isso evita processar a mesma mensagem duas vezes durante reconexões ou soluços de rede.

Todas as variáveis de ambiente​

VariávelObrigatóriaPadrãoDescrição
WECOM_BOT_ID✅—Bot ID do AI Bot do WeCom
WECOM_SECRET✅—Secret do AI Bot do WeCom
WECOM_ALLOWED_USERS—(vazio)IDs de usuário separados por vírgula, para a lista de permissão no nível do gateway
WECOM_HOME_CHANNEL——ID de chat para a saída de cron/notificações
WECOM_WEBSOCKET_URL—wss://openws.work.weixin.qq.comURL do gateway WebSocket
WECOM_DM_POLICY—openPolítica de acesso por mensagem direta
WECOM_GROUP_POLICY—openPolítica de acesso em grupo

Resolução de problemas​

ProblemaSolução
WECOM_BOT_ID and WECOM_SECRET are requiredDefina as duas variáveis de ambiente ou configure pelo assistente
WeCom startup failed: aiohttp not installedInstale o aiohttp: pip install aiohttp
WeCom startup failed: httpx not installedInstale o httpx: pip install httpx
invalid secret (errcode=40013)Confira se o secret bate com as credenciais do seu bot
Timed out waiting for subscribe acknowledgementVerifique a conectividade de rede com openws.work.weixin.qq.com
O bot não responde em gruposConfira o ajuste group_policy e garanta que o ID do grupo está em group_allow_from
O bot ignora certos usuários num grupoConfira as listas allow_from por grupo na seção groups da configuração
A descriptografia de mídia falhaInstale o cryptography: pip install cryptography
cryptography is required for WeCom media decryptionA mídia de entrada está criptografada em AES. Instale: pip install cryptography
Mensagens de voz chegam como arquivosO WeCom só aceita o formato AMR para voz nativa. Outros formatos são rebaixados automaticamente para arquivo.
Erro File too largeO WeCom tem um limite absoluto de 20 MB para todo upload de arquivo. Comprima ou divida o arquivo.
Imagens chegam como arquivosImagens > 10 MB passam do limite nativo de imagem e são rebaixadas automaticamente para anexo de arquivo.
Timeout sending message to WeComO WebSocket pode ter desconectado. Procure mensagens de reconexão nos logs.
WeCom websocket closed during authenticationProblema de rede ou credenciais erradas. Confira o bot_id e o secret.