Pular para o conteúdo principal

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

Weixin (WeChat)

Weixin (WeChat)

Conecte o Hermes ao WeChat (微信), a plataforma de mensagens pessoais da Tencent. O adaptador usa a iLink Bot API da Tencent para contas pessoais do WeChat — isso é diferente do WeCom (WeChat Empresarial). As mensagens chegam por long-polling, então nenhum endpoint público ou webhook é necessário.

informação

Este adaptador é para contas pessoais do WeChat (微信). Se você precisa do WeChat corporativo/empresarial, veja o adaptador do WeCom.

Identidade de bot do iLink — grupos comuns do WeChat podem não funcionar

O login por QR conecta o Hermes a uma identidade de bot do iLink (por exemplo, a5ace6fd482e@im.bot), e não a uma conta pessoal comum do WeChat totalmente controlável por script. Consequências:

  • A identidade de bot do iLink em geral não pode ser convidada para grupos comuns do WeChat como um contato normal pode.
  • O iLink normalmente não entrega eventos de grupo comuns do WeChat (incluindo menções com @ à conta pessoal usada no login por QR) para o gateway na maioria das contas do tipo bot.
  • Mencionar com @ a conta pessoal do WeChat que leu o código QR não é o mesmo que mencionar com @ o bot do iLink — o bot é uma identidade separada.
  • As configurações WEIXIN_GROUP_POLICY / WEIXIN_GROUP_ALLOWED_USERS descritas abaixo só têm efeito quando o iLink realmente devolve eventos de grupo para o seu tipo de conta. Se não devolver, as mensagens de grupo nunca vão chegar ao Hermes, seja qual for a política.

Na prática, a maioria das instalações só consegue fazer funcionar de forma confiável as mensagens diretas para o bot do iLink. Se a entrega em grupo não funcionar depois da configuração, a limitação está do lado do iLink, não no Hermes. O gateway registra um WARNING na inicialização sempre que WEIXIN_GROUP_POLICY estiver definido como qualquer coisa diferente de disabled.

Pré-requisitos​

  • Uma conta pessoal do WeChat
  • Pacotes Python: aiohttp e cryptography
  • A renderização de QR no terminal já vem incluída quando o Hermes é instalado com o extra messaging

Instale as dependências necessárias:

pip install aiohttp cryptography
# Opcional: para exibir o código QR no terminal
cd ~/.hermes/hermes-agent && uv pip install -e ".[messaging]"

Configuração​

1. Rode o assistente de configuração​

A maneira mais fácil de conectar a sua conta do WeChat é pelo assistente interativo:

hermes gateway setup

Escolha Weixin quando for perguntado. O assistente vai:

  1. Pedir um código QR à iLink Bot API
  2. Exibir o código QR no seu terminal (ou fornecer uma URL)
  3. Esperar que você leia o código QR com o aplicativo do WeChat no celular
  4. Pedir que você confirme o login no telefone
  5. Salvar as credenciais da conta automaticamente em ~/.hermes/weixin/accounts/

Depois de confirmar, você verá uma mensagem assim:

微信连接成功,account_id=your-account-id

O assistente guarda o account_id, o token e a base_url, então você não precisa configurá-los à mão.

2. Configure as variáveis de ambiente​

Depois do login inicial por QR, defina no mínimo o ID da conta em ~/.hermes/.env:

WEIXIN_ACCOUNT_ID=id-da-sua-conta

# Opcional: sobrescreve o token (normalmente salvo automaticamente pelo login por QR)
# WEIXIN_TOKEN=token-do-seu-bot

# Opcional: restringe o acesso
WEIXIN_DM_POLICY=open
WEIXIN_ALLOWED_USERS=user_id_1,user_id_2

# Opcional: restaura o comportamento antigo de quebra de mensagens em várias linhas
# WEIXIN_SPLIT_MULTILINE_MESSAGES=true

# Opcional: canal principal para cron e notificações
WEIXIN_HOME_CHANNEL=chat_id
WEIXIN_HOME_CHANNEL_NAME=Home

3. Inicie o gateway​

hermes gateway

O adaptador vai restaurar as credenciais salvas, conectar-se à API do iLink e começar o long-polling em busca de mensagens.

Recursos​

  • Transporte por long-poll — sem necessidade de endpoint público, webhook ou WebSocket
  • Login por código QR — configuração por leitura de QR via hermes gateway setup
  • Mensagens diretas — políticas de acesso configuráveis; as mensagens em grupo dependem de o iLink realmente entregar eventos de grupo para a identidade conectada (o que muitas vezes não acontece em contas de bot do iLink — veja o aviso acima)
  • Suporte a mídia — imagens, vídeo, arquivos e mensagens de voz
  • CDN criptografada em AES-128-ECB — criptografia e descriptografia automáticas em todas as transferências de mídia
  • Persistência de token de contexto — continuidade de resposta gravada em disco, mantida entre reinícios
  • Formatação Markdown — preserva o Markdown, incluindo títulos, tabelas e blocos de código, para que os clientes do WeChat que suportam Markdown possam renderizá-lo nativamente
  • Fatiamento inteligente de mensagens — mensagens ficam em uma única bolha quando estão abaixo do limite; só os conteúdos grandes demais são divididos em fronteiras lógicas
  • Indicadores de digitação — mostra o status "digitando…" no cliente do WeChat enquanto o agente processa
  • Proteção contra SSRF — as URLs de mídia de saída são validadas antes do download
  • Deduplicação de mensagens — uma janela deslizante de 5 minutos evita processamento duplicado
  • Nova tentativa automática com recuo — recupera-se de erros transitórios da API

Opções de configuração​

Defina estas opções no config.yaml, em platforms.weixin.extra:

ChavePadrãoDescrição
account_id—ID da conta do iLink Bot (obrigatório)
token—Token do iLink Bot (obrigatório, salvo automaticamente no login por QR)
base_urlhttps://ilinkai.weixin.qq.comURL base da API do iLink
cdn_base_urlhttps://novac2c.cdn.weixin.qq.com/c2cURL base da CDN para transferência de mídia
dm_policyopenAcesso a mensagens diretas: open, allowlist, disabled, pairing
group_policydisabledAcesso a grupos: open, allowlist, disabled
allow_from[]IDs de usuário liberados para mensagens diretas (quando dm_policy=allowlist)
group_allow_from[]IDs de grupo liberados (quando group_policy=allowlist)
split_multiline_messagesfalseQuando true, divide respostas de várias linhas em várias mensagens de chat (comportamento antigo). Quando false, mantém respostas de várias linhas como uma só mensagem, a menos que passem do limite de tamanho.
text_batch_delay_seconds3.0Período de silêncio (em segundos) antes de uma rajada de mensagens de texto rápidas, guardada em buffer, ser despachada como uma única requisição combinada. O iLink entrega as mensagens uma a uma, então esse debounce evita uma invocação do agente por fragmento. Defina 0 para despachar cada mensagem imediatamente.
text_batch_split_delay_seconds5.0Atraso estendido de despacho, usado quando o último fragmento está perto do limite de divisão (mensagens longas que o iLink pode ter fatiado).

Políticas de acesso​

Política de mensagens diretas​

Controla quem pode mandar mensagens diretas para o bot:

ValorComportamento
openQualquer pessoa pode mandar mensagem direta ao bot (padrão)
allowlistSó os IDs de usuário em allow_from podem mandar mensagem direta
disabledTodas as mensagens diretas são ignoradas
pairingModo de pareamento (para a configuração inicial)
WEIXIN_DM_POLICY=allowlist
WEIXIN_ALLOWED_USERS=user_id_1,user_id_2

WEIXIN_ALLOWED_USERS é um filtro de entrada, não um sistema de convites. O login por QR conecta uma identidade de bot do iLink ao Hermes. Outras pessoas não leem o código QR do Hermes com as contas delas; elas precisam mandar mensagem para o bot/contato do iLink conectado pelo WeChat, e o Hermes só vai processar a mensagem direta se o ID de usuário do Weixin de quem enviou estiver em WEIXIN_ALLOWED_USERS.

Um fluxo prático de configuração é:

  1. Pareie o Hermes uma vez com hermes gateway setup e anote a conta de bot do iLink conectada.
  2. Peça a cada usuário liberado que mande uma mensagem direta para esse bot/contato.
  3. Leia o ID de quem enviou nos logs do gateway ou no payload do evento de entrada.
  4. Acrescente esses IDs a WEIXIN_ALLOWED_USERS e reinicie o gateway.

Se só a conta que leu o código QR consegue falar com o Hermes, confira se os outros usuários estão mandando mensagem para a própria identidade de bot do iLink, e não para a conta pessoal do WeChat que fez o login por QR. O bot do iLink é uma identidade separada, e o roteamento comum de contatos e grupos do WeChat pode ser limitado pelo comportamento do iLink da Tencent.

Política de grupos​

Controla em quais grupos o bot responde quando o iLink entrega eventos de grupo para a identidade conectada. Para identidades de bot do iLink criadas por login por QR (por exemplo, ...@im.bot), os eventos de grupo normalmente não são entregues, então esta política pode não ter efeito nenhum — veja o aviso sobre a limitação do bot do iLink no início da página.

ValorComportamento
openO bot responde em todos os grupos (se os eventos forem entregues)
allowlistO bot só responde nos IDs de grupo listados em group_allow_from (se os eventos forem entregues)
disabledTodas as mensagens de grupo são ignoradas (padrão)
WEIXIN_GROUP_POLICY=allowlist
# ATENÇÃO: esta é uma lista de IDs de conversa de grupo separada por vírgulas, NÃO
# de IDs de usuário dos membros, apesar de o nome da variável conter "USERS".
# Tenha isso em mente ao configurar.
WEIXIN_GROUP_ALLOWED_USERS=group_id_1,group_id_2
observação

A política de grupo padrão do Weixin é disabled (diferente do WeCom, onde o padrão é open). Isso é intencional — contas pessoais do WeChat podem estar em muitos grupos, e identidades de bot do iLink normalmente não conseguem receber mensagens de grupo comuns do WeChat de jeito nenhum. O gateway registra um WARNING na inicialização se você definir WEIXIN_GROUP_POLICY como qualquer coisa diferente de disabled.

Suporte a mídia​

Entrada (recebimento)​

O adaptador recebe anexos de mídia dos usuários, baixa-os da CDN do WeChat, descriptografa e guarda em cache local para o agente processar:

TipoComo é tratado
ImagensBaixadas, descriptografadas com AES e guardadas em cache como JPEG.
VídeoBaixado, descriptografado com AES e guardado em cache como MP4.
ArquivosBaixados, descriptografados com AES e guardados em cache. O nome original do arquivo é preservado.
VozSe há transcrição em texto disponível, ela é extraída como texto. Caso contrário, o áudio (formato SILK) é baixado e guardado em cache.

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.

CDN criptografada em AES-128-ECB​

Os arquivos de mídia do WeChat são transferidos por uma CDN criptografada. O adaptador cuida disso de forma transparente:

  • Entrada: a mídia criptografada é baixada da CDN por URLs com encrypted_query_param e depois descriptografada com AES-128-ECB, usando a chave por arquivo fornecida no payload da mensagem.
  • Saída: os arquivos são criptografados localmente com uma chave AES-128-ECB aleatória, enviados à CDN, e a referência criptografada é incluída na mensagem de saída.
  • A chave AES tem 16 bytes (128 bits). As chaves podem chegar como base64 cru ou em hexadecimal — o adaptador lida com os dois formatos.
  • Isso exige o pacote Python cryptography.

Nenhuma configuração é necessária — a criptografia e a descriptografia acontecem automaticamente.

Saída (envio)​

MétodoO que envia
sendMensagens de texto com formatação Markdown
send_image / send_image_fileMensagens de imagem nativas (via upload para a CDN)
send_documentAnexos de arquivo (via upload para a CDN)
send_videoMensagens de vídeo (via upload para a CDN)

Toda mídia de saída passa pelo fluxo de upload criptografado para a CDN:

  1. Gerar uma chave AES-128 aleatória
  2. Criptografar o arquivo com AES-128-ECB + preenchimento PKCS#7
  3. Pedir uma URL de upload à API do iLink (getuploadurl)
  4. Enviar o texto cifrado para a CDN
  5. Enviar a mensagem com a referência de mídia criptografada

Persistência do token de contexto​

A iLink Bot API exige que um context_token seja devolvido junto com cada mensagem de saída para um determinado interlocutor. O adaptador mantém um repositório de tokens de contexto gravado em disco:

  • Os tokens são salvos por conta+interlocutor em ~/.hermes/weixin/accounts/<account_id>.context-tokens.json
  • Na inicialização, os tokens salvos anteriormente são restaurados
  • Toda mensagem de entrada atualiza o token guardado para aquele remetente
  • As mensagens de saída incluem automaticamente o token de contexto mais recente

Isso garante a continuidade das respostas mesmo depois de reinícios do gateway.

Formatação Markdown​

Os clientes do WeChat conectados pela iLink Bot API conseguem renderizar Markdown diretamente, então o adaptador preserva o Markdown em vez de reescrevê-lo:

  • Títulos continuam como títulos Markdown (#, ##, ...)
  • Tabelas continuam como tabelas Markdown
  • Cercas de código continuam como blocos de código cercados
  • Linhas em branco em excesso são reduzidas a duas quebras de linha, fora dos blocos de código cercados

Fatiamento de mensagens​

As mensagens são entregues como uma única mensagem de chat sempre que cabem no limite da plataforma. Só os conteúdos grandes demais são divididos para a entrega:

  • Tamanho máximo da mensagem: 4000 caracteres
  • Mensagens abaixo do limite ficam intactas, mesmo com vários parágrafos ou quebras de linha
  • Mensagens grandes demais são divididas em fronteiras lógicas (parágrafos, linhas em branco, cercas de código)
  • As cercas de código são mantidas intactas sempre que possível (nunca divididas no meio do bloco, a menos que a própria cerca passe do limite)
  • Blocos individuais grandes demais caem na lógica de truncamento do adaptador base
  • Um atraso de 0,3 s entre pedaços evita descartes por limite de taxa do WeChat quando vários pedaços são enviados

Indicadores de digitação​

O adaptador mostra o status de digitação no cliente do WeChat:

  1. Quando chega uma mensagem, o adaptador busca um typing_ticket pela API getconfig
  2. Os tíquetes de digitação ficam em cache por 10 minutos, por usuário
  3. send_typing envia um sinal de início de digitação; stop_typing envia um sinal de fim de digitação
  4. O gateway aciona os indicadores de digitação automaticamente enquanto o agente processa uma mensagem

Conexão por long-poll​

O adaptador usa long-polling HTTP (não WebSocket) para receber mensagens:

Como funciona​

  1. Conexão: valida as credenciais e inicia o laço de polling
  2. Poll: chama getupdates com um timeout de 35 segundos; o servidor segura a requisição até que cheguem mensagens ou o timeout expire
  3. Despacho: as mensagens de entrada são despachadas de forma concorrente via asyncio.create_task
  4. Buffer de sincronização: um cursor de sincronização persistente (get_updates_buf) é salvo em disco, para que o adaptador retome da posição correta depois de reinícios

Comportamento de nova tentativa​

Em erros da API, o adaptador usa uma estratégia simples de nova tentativa:

CondiçãoComportamento
Erro transitório (1º–2º)Tenta de novo depois de 2 segundos
Erros repetidos (3 ou mais)Recua por 30 segundos e depois zera o contador
Sessão expirada (errcode=-14)Pausa por 10 minutos (pode ser necessário fazer login de novo)
TimeoutRefaz o poll imediatamente (comportamento normal de long-poll)

Deduplicação​

As mensagens de entrada são deduplicadas por IDs de mensagem, com uma janela de 5 minutos. Isso evita processamento duplicado durante instabilidades de rede ou respostas de poll sobrepostas.

Trava de token​

Só uma instância de gateway do Weixin pode usar um determinado token de cada vez. O adaptador adquire uma trava com escopo na inicialização e a libera no encerramento. Se outro gateway já estiver usando o mesmo token, a inicialização falha com uma mensagem de erro informativa.

Todas as variáveis de ambiente​

VariávelObrigatóriaPadrãoDescrição
WEIXIN_ACCOUNT_ID✅—ID da conta do iLink Bot (vem do login por QR)
WEIXIN_TOKEN✅—Token do iLink Bot (salvo automaticamente no login por QR)
WEIXIN_BASE_URL—https://ilinkai.weixin.qq.comURL base da API do iLink
WEIXIN_CDN_BASE_URL—https://novac2c.cdn.weixin.qq.com/c2cURL base da CDN para transferência de mídia
WEIXIN_DM_POLICY—openPolítica de acesso a mensagens diretas: open, allowlist, disabled, pairing
WEIXIN_GROUP_POLICY—disabledPolítica de acesso a grupos: open, allowlist, disabled
WEIXIN_ALLOWED_USERS—(vazio)IDs de usuário separados por vírgula para a lista de permissão de mensagens diretas
WEIXIN_GROUP_ALLOWED_USERS—(vazio)IDs de conversa de grupo separados por vírgula (não IDs de usuário dos membros) para a lista de permissão de grupos. O nome da variável é herdado do passado — ela espera IDs de grupo, não de usuário.
WEIXIN_HOME_CHANNEL——ID de conversa para a saída de cron e notificações
WEIXIN_HOME_CHANNEL_NAME—HomeNome de exibição do canal principal
WEIXIN_ALLOW_ALL_USERS——Sinalizador no nível do gateway para liberar todos os usuários (usado pelo assistente de configuração)

Solução de problemas​

ProblemaSolução
Weixin startup failed: aiohttp and cryptography are requiredInstale os dois: pip install aiohttp cryptography
Weixin startup failed: WEIXIN_TOKEN is requiredRode hermes gateway setup para concluir o login por QR, ou defina WEIXIN_TOKEN à mão
Weixin startup failed: WEIXIN_ACCOUNT_ID is requiredDefina WEIXIN_ACCOUNT_ID no seu .env ou rode hermes gateway setup
Another local Hermes gateway is already using this Weixin tokenPare a outra instância do gateway primeiro — só é permitido um poller por token
Sessão expirada (errcode=-14)A sua sessão de login expirou. Rode hermes gateway setup de novo para ler um novo código QR
Código QR expirou durante a configuraçãoO QR se renova automaticamente até 3 vezes. Se ele continuar expirando, verifique a sua conexão de rede
O bot não responde a mensagens diretasConfira WEIXIN_DM_POLICY — se estiver em allowlist, quem envia precisa estar em WEIXIN_ALLOWED_USERS
O bot ignora mensagens de grupoA política de grupo é disabled por padrão. Defina WEIXIN_GROUP_POLICY=open ou allowlist — mas note que identidades de bot do iLink criadas por login por QR (...@im.bot) normalmente não conseguem receber mensagens de grupo comuns do WeChat de jeito nenhum. Se os logs do gateway não mostram nenhum evento cru de entrada para mensagens de grupo, a limitação está do lado do iLink, não no Hermes.
Falha no download ou upload de mídiaConfirme que o cryptography está instalado. Verifique o acesso de rede a novac2c.cdn.weixin.qq.com
Blocked unsafe URL (SSRF protection)A URL de mídia de saída aponta para um endereço privado/interno. Só URLs públicas são permitidas
Mensagens de voz aparecem como textoSe o WeChat fornece uma transcrição, o adaptador usa o texto. Esse é o comportamento esperado
Mensagens aparecem duplicadasO adaptador deduplica por ID de mensagem. Se você vê duplicatas, verifique se há várias instâncias do gateway rodando
iLink POST ... HTTP 4xx/5xxErro de API do serviço iLink. Verifique a validade do seu token e a conectividade de rede
O código QR não aparece no terminalReinstale com o extra de mensagens: cd ~/.hermes/hermes-agent && uv pip install -e ".[messaging]". Como alternativa, abra a URL impressa acima do QR