Перейти к содержанию

Weixin

На этой странице Подключите Hermes к WeChat (微信) — личной платформе обмена сообщениями от Tencent. Адаптер использует iLink Bot API от Tencent для личных аккаунтов WeChat — это отличается от WeCom (корпоративного WeChat). Сообщения доставляются через long-polling, поэтому публичная конечная точка или вебхук не требуются. info Этот адаптер предназначен для личных аккаунтов WeChat (微信). Если вам нужен корпоративный WeChat, см. адаптер WeCom. Идентичность iLink-бота — обычные группы WeChat могут не работать QR-вход подключает Hermes к идентичности iLink-бота (например, a5ace6fd482e@im.bot), а не к полноценному обычному личному аккаунту WeChat. Последствия: * Идентичность iLink-бота, как правило, нельзя приглашать в обычные группы WeChat как обычный контакт. * iLink обычно не доставляет события обычных групп WeChat (включая @-упоминания личного аккаунта, использованного для QR-входа) на шлюз для большинства учётных записей ботов. * @-упоминание личного аккаунта WeChat, использованного для сканирования QR-кода, не то же самое, что @-упоминание iLink-бота — бот является отдельной идентичностью. * Настройки WEIXIN_GROUP_POLICY / WEIXIN_GROUP_ALLOWED_USERS ниже вступают в силу только тогда, когда iLink действительно возвращает групповые события для вашего типа аккаунта. Если этого не происходит, групповые сообщения никогда не достигнут Hermes независимо от политики.

На практике в большинстве развёртываний надёжно работают только личные сообщения (DM) iLink-боту. Если групповая доставка не работает после настройки, ограничение на стороне iLink, а не в Hermes. Шлюз логирует WARNING при запуске, если WEIXIN_GROUP_POLICY установлен в любое значение, отличное от disabled.

Предварительные требования

  • Личный аккаунт WeChat
  • Python-пакеты: aiohttp и cryptography
  • Отображение QR-кода в терминале включается при установке Hermes с дополнением messaging

Установите необходимые зависимости: [code] pip install aiohttp cryptography
# Опционально: для отображения QR-кода в терминале
pip install hermes-agent[messaging]

[/code]

Настройка

1\. Запустите мастер настройки

Самый простой способ подключить ваш аккаунт WeChat — через интерактивную настройку: [code] hermes gateway setup

[/code] Выберите Weixin при запросе. Мастер выполнит следующее: 1. Запросит QR-код у iLink Bot API 2. Отобразит QR-код в вашем терминале (или предоставит URL) 3. Подождёт, пока вы отсканируете QR-код мобильным приложением WeChat 4. Предложит подтвердить вход на телефоне 5. Автоматически сохранит учётные данные аккаунта в ~/.hermes/weixin/accounts/

После подтверждения вы увидите сообщение: [code] 微信连接成功,account_id=your-account-id

[/code] Мастер сохраняет account_id, token и base_url, так что вам не нужно настраивать их вручную.

2\. Настройте переменные окружения

После первоначального QR-входа установите как минимум идентификатор аккаунта в ~/.hermes/.env: [code] WEIXIN_ACCOUNT_ID=your-account-id

# Опционально: переопределить токен (обычно сохраняется автоматически из QR-входа)  
# WEIXIN_TOKEN=your-bot-token

# Опционально: ограничить доступ  
WEIXIN_DM_POLICY=open  
WEIXIN_ALLOWED_USERS=user_id_1,user_id_2

# Опционально: восстановить устаревшее поведение разделения многострочных сообщений  
# WEIXIN_SPLIT_MULTILINE_MESSAGES=true

# Опционально: домашний канал для cron/уведомлений  
WEIXIN_HOME_CHANNEL=chat_id  
WEIXIN_HOME_CHANNEL_NAME=Home

[/code]

3\. Запустите шлюз

[code] hermes gateway

[/code] Адаптер восстановит сохранённые учётные данные, подключится к iLink API и начнёт long-polling для получения сообщений.

Возможности

  • Long-poll транспорт — не требует публичной конечной точки, вебхука или WebSocket
  • Вход по QR-коду — подключение через сканирование с помощью hermes gateway setup
  • Личные сообщения (DM) — настраиваемые политики доступа; групповая переписка зависит от того, передаёт ли iLink групповые события для подключённой идентичности (часто не работает для учётных записей iLink-ботов — см. предупреждение выше)
  • Поддержка медиа — изображения, видео, файлы и голосовые сообщения
  • AES-128-ECB зашифрованный CDN — автоматическое шифрование/дешифрование всех медиа-передач
  • Постоянство контекстного токена — непрерывность ответов через перезапуски с сохранением на диск
  • Форматирование Markdown — сохраняет Markdown, включая заголовки, таблицы и блоки кода, так что клиенты WeChat, поддерживающие Markdown, могут отображать его нативно
  • Умная разбивка сообщений — сообщения остаются одним «пузырём», если не превышают лимит; только превышающие размер полезные нагрузки разбиваются по логическим границам
  • Индикаторы печати — показывает статус «печатает…» в клиенте WeChat, пока агент обрабатывает запрос
  • Защита от SSRF — исходящие URL медиа проверяются перед загрузкой
  • Дедупликация сообщений — скользящее окно в 5 минут предотвращает двойную обработку
  • Автоматические повторные попытки с экспоненциальной задержкой — восстановление после временных ошибок API

Параметры конфигурации

Установите их в config.yaml в разделе platforms.weixin.extra: Ключ| По умолчанию| Описание
---|---|---
account_id| —| ID аккаунта iLink Bot (обязательно)
token| —| Токен iLink Bot (обязательно, автоматически сохраняется из QR-входа)
base_url| https://ilinkai.weixin.qq.com| Базовый URL API iLink
cdn_base_url| https://novac2c.cdn.weixin.qq.com/c2c| Базовый URL CDN для передачи медиа
dm_policy| open| Доступ к DM: open, allowlist, disabled, pairing
group_policy| disabled| Доступ к группам: open, allowlist, disabled
allow_from| []| ID пользователей, разрешённых для DM (когда dm_policy=allowlist)
group_allow_from| []| ID групп, разрешённых (когда group_policy=allowlist)
split_multiline_messages| false| Если true, разделять многострочные ответы на несколько сообщений чата (устаревшее поведение). Если false, оставлять многострочные ответы одним сообщением, если они не превышают лимит длины.

Политики доступа

Политика DM

Контролирует, кто может отправлять боту личные сообщения: Значение| Поведение
---|---
open| Любой может писать боту в DM (по умолчанию)
allowlist| Только пользователи из allow_from могут писать в DM
disabled| Все DM игнорируются
pairing| Режим сопряжения (для начальной настройки) [code] WEIXIN_DM_POLICY=allowlist
WEIXIN_ALLOWED_USERS=user_id_1,user_id_2

[/code]

Политика групп

Контролирует, в каких группах бот отвечает когда iLink доставляет групповые события для подключённой идентичности. Для идентичностей iLink-ботов, вошедших через QR (например, ...@im.bot), групповые события обычно не доставляются вовсе, поэтому эта политика может не иметь эффекта — см. предупреждение об ограничении iLink-бота в начале страницы. Значение| Поведение
---|---
open| Бот отвечает во всех группах (если события доставляются)
allowlist| Бот отвечает только в группах из group_allow_from (если события доставляются)
disabled| Все групповые сообщения игнорируются (по умолчанию) [code] WEIXIN_GROUP_POLICY=allowlist
# ПРИМЕЧАНИЕ: это список ID групповых чатов через запятую, НЕ ID пользователей-участников,
# несмотря на то, что имя переменной содержит «USERS». Учитывайте это при настройке.
WEIXIN_GROUP_ALLOWED_USERS=group_id_1,group_id_2

[/code]
note Политика групп по умолчанию — disabled для Weixin (в отличие от WeCom, где по умолчанию open). Это сделано намеренно — личные аккаунты WeChat могут быть во многих группах, а идентичности iLink-ботов обычно вообще не могут получать обычные групповые сообщения WeChat. Шлюз логирует WARNING при запуске, если вы устанавливаете WEIXIN_GROUP_POLICY в любое значение, отличное от disabled.

Поддержка медиа

Входящие (получение)

Адаптер получает медиавложения от пользователей, загружает их с CDN WeChat, расшифровывает и кеширует локально для обработки агентом: Тип| Как обрабатывается
---|---
Изображения| Загружаются, расшифровываются AES и кешируются как JPEG.
Видео| Загружается, расшифровывается AES и кешируется как MP4.
Файлы| Загружаются, расшифровываются AES и кешируются. Исходное имя файла сохраняется.
Голос| Если доступна текстовая расшифровка, извлекается как текст. В противном случае аудио (формат SILK) загружается и кешируется.
Цитируемые сообщения: Медиа из цитируемых (на которые дан ответ) сообщений также извлекается, чтобы агент имел контекст того, на что отвечает пользователь.

AES-128-ECB зашифрованный CDN

Медиафайлы WeChat передаются через зашифрованный CDN. Адаптер обрабатывает это прозрачно: * Входящие: Зашифрованные медиа загружаются с CDN с использованием URL с encrypted_query_param, затем расшифровываются с помощью AES-128-ECB, используя пофайловый ключ из полезной нагрузки сообщения. * Исходящие: Файлы шифруются локально случайным ключом AES-128-ECB, загружаются на CDN, и зашифрованная ссылка включается в исходящее сообщение. * Ключ AES имеет размер 16 байт (128 бит). Ключи могут поступать в виде сырого base64 или hex-кодировки — адаптер поддерживает оба формата. * Для этого требуется Python-пакет cryptography.

Никакой настройки не требуется — шифрование и дешифрование происходят автоматически.

Исходящие (отправка)

Метод Что отправляет
send Текстовые сообщения с форматированием Markdown
send_image / send_image_file Нативные сообщения-изображения (через загрузку на CDN)
send_document Вложения-файлы (через загрузку на CDN)
send_video Видеосообщения (через загрузку на CDN)
Все исходящие медиа проходят через зашифрованный поток загрузки на CDN:
1. Генерация случайного ключа AES-128
2. Шифрование файла с помощью AES-128-ECB + PKCS#7 padding
3. Запрос URL для загрузки у iLink API (getuploadurl)
4. Загрузка шифротекста на CDN
5. Отправка сообщения с зашифрованной медиа-ссылкой

Постоянство контекстного токена

iLink Bot API требует, чтобы context_token отправлялся обратно с каждым исходящим сообщением для данного собеседника. Адаптер поддерживает хранилище контекстных токенов на диске: * Токены сохраняются для каждой пары аккаунт+собеседник в ~/.hermes/weixin/accounts/<account_id>.context-tokens.json * При запуске ранее сохранённые токены восстанавливаются * Каждое входящее сообщение обновляет сохранённый токен для этого отправителя * Исходящие сообщения автоматически включают последний контекстный токен

Это обеспечивает непрерывность ответов даже после перезапусков шлюза.

Форматирование Markdown

Клиенты WeChat, подключённые через iLink Bot API, могут отображать Markdown напрямую, поэтому адаптер сохраняет Markdown вместо его перезаписи: * Заголовки остаются как Markdown-заголовки (#, ##, ...) * Таблицы остаются как Markdown-таблицы * Блоки кода остаются как блоки кода в обратных кавычках * Лишние пустые строки схлопываются до двойных переводов строки вне блоков кода

Разбивка сообщений

Сообщения доставляются как одно сообщение чата, когда они умещаются в лимит платформы. Только превышающие размер полезные нагрузки разбиваются для доставки: * Максимальная длина сообщения: 4000 символов * Сообщения, не превышающие лимит, остаются целыми, даже если содержат несколько абзацев или переносов строк * Сообщения, превышающие лимит, разбиваются по логическим границам (абзацы, пустые строки, блоки кода) * Блоки кода сохраняются целыми, когда это возможно (никогда не разбиваются посередине блока, если только сам блок не превышает лимит) * Отдельные блоки, превышающие лимит, переходят к логике усечения базового адаптера * Задержка в 0,3 с между частями предотвращает сброс из-за лимитов скорости WeChat при отправке нескольких частей

Индикаторы печати

Адаптер показывает статус печати в клиенте WeChat: 1. Когда приходит сообщение, адаптер получает typing_ticket через API getconfig 2. Тикет печати кешируется на 10 минут на пользователя 3. send_typing отправляет сигнал начала печати; stop_typing отправляет сигнал остановки печати 4. Шлюз автоматически запускает индикаторы печати, пока агент обрабатывает сообщение

Long-Poll соединение

Адаптер использует HTTP long-polling (не WebSocket) для получения сообщений:

Как это работает

  1. Подключение: Проверяет учётные данные и запускает цикл опроса
  2. Опрос: Вызывает getupdates с таймаутом 35 секунд; сервер удерживает запрос до поступления сообщений или истечения таймаута
  3. Обработка: Входящие сообщения обрабатываются конкурентно через asyncio.create_task
  4. Буфер синхронизации: Постоянный курсор синхронизации (get_updates_buf) сохраняется на диск, чтобы адаптер возобновлял работу с правильной позиции после перезапусков

Поведение при повторах

При ошибках API адаптер использует простую стратегию повторов: Условие| Поведение
---|---
Временная ошибка (1–2)| Повтор через 2 секунды
Повторяющиеся ошибки (3+)| Ожидание 30 секунд, затем сброс счётчика
Сессия истекла (errcode=-14)| Пауза на 10 минут (может потребоваться повторный вход)
Таймаут| Немедленный повторный опрос (нормальное поведение long-poll)

Дедупликация

Входящие сообщения дедуплицируются по ID сообщения с окном в 5 минут. Это предотвращает двойную обработку при сетевых сбоях или перекрывающихся ответах опроса.

Блокировка токена

Только один экземпляр шлюза Weixin может использовать данный токен одновременно. Адаптер получает ограниченную блокировку при запуске и освобождает её при остановке. Если другой шлюз уже использует тот же токен, запуск завершается с информативным сообщением об ошибке.

Все переменные окружения

Переменная| Обязательно| По умолчанию| Описание
---|---|---|---|---
WEIXIN_ACCOUNT_ID| ✅| —| ID аккаунта iLink Bot (из QR-входа)
WEIXIN_TOKEN| ✅| —| Токен iLink Bot (автоматически сохраняется из QR-входа)
WEIXIN_BASE_URL| —| https://ilinkai.weixin.qq.com| Базовый URL API iLink
WEIXIN_CDN_BASE_URL| —| https://novac2c.cdn.weixin.qq.com/c2c| Базовый URL CDN для передачи медиа
WEIXIN_DM_POLICY| —| open| Политика доступа к DM: open, allowlist, disabled, pairing
WEIXIN_GROUP_POLICY| —| disabled| Политика доступа к группам: open, allowlist, disabled
WEIXIN_ALLOWED_USERS| —| (пусто)| ID пользователей через запятую для DM allowlist
WEIXIN_GROUP_ALLOWED_USERS| —| (пусто)| ID групповых чатов (не ID пользователей-участников) через запятую для группового allowlist. Имя переменной устаревшее — ожидаются ID групп, а не пользователей.
WEIXIN_HOME_CHANNEL| —| —| ID чата для вывода cron/уведомлений
WEIXIN_HOME_CHANNEL_NAME| —| Home| Отображаемое имя домашнего канала
WEIXIN_ALLOW_ALL_USERS| —| —| Флаг уровня шлюза для разрешения всем пользователям (используется мастером настройки)

Устранение неполадок

Проблема Решение
Weixin startup failed: aiohttp and cryptography are required Установите оба пакета: pip install aiohttp cryptography
Weixin startup failed: WEIXIN_TOKEN is required Запустите hermes gateway setup для завершения QR-входа или установите WEIXIN_TOKEN вручную
Weixin startup failed: WEIXIN_ACCOUNT_ID is required Установите WEIXIN_ACCOUNT_ID в вашем .env или запустите hermes gateway setup
Another local Hermes gateway is already using this Weixin token Сначала остановите другой экземпляр шлюза — разрешён только один поллер на токен
Сессия истекла (errcode=-14) Срок действия вашей сессии истёк. Повторно запустите hermes gateway setup для сканирования нового QR-кода
QR-код истёк во время настройки QR автоматически обновляется до 3 раз. Если он продолжает истекать, проверьте ваше сетевое соединение
Бот не отвечает на DM Проверьте WEIXIN_DM_POLICY — если установлено allowlist, отправитель должен быть в WEIXIN_ALLOWED_USERS
Бот игнорирует групповые сообщения Политика групп по умолчанию — disabled. Установите WEIXIN_GROUP_POLICY=open или allowlist — но учтите, что идентичности iLink-ботов, вошедших через QR (...@im.bot), обычно вообще не могут получать обычные групповые сообщения WeChat. Если логи шлюза не показывают сырых входящих событий для групповых сообщений, ограничение на стороне iLink, а не в Hermes.
Загрузка/выгрузка медиа не удаётся Убедитесь, что установлен cryptography. Проверьте доступ к novac2c.cdn.weixin.qq.com
Blocked unsafe URL (SSRF protection) Исходящий URL медиа указывает на частный/внутренний адрес. Разрешены только публичные URL
Голосовые сообщения отображаются как текст Если WeChat предоставляет расшифровку, адаптер использует текст. Это ожидаемое поведение
Сообщения дублируются Адаптер дедуплицирует по ID сообщения. Если вы видите дубликаты, проверьте, не запущено ли несколько экземпляров шлюза
iLink POST ... HTTP 4xx/5xx Ошибка API от сервиса iLink. Проверьте действительность токена и сетевое подключение
QR-код в терминале не отображается Переустановите с дополнением messaging: pip install hermes-agent[messaging]. Альтернативно, откройте URL, напечатанный над QR-кодом
* Предварительные требования
* Настройка
* 1\. Запустите мастер настройки
* 2\. Настройте переменные окружения
* 3\. Запустите шлюз
* Возможности
* Параметры конфигурации
* Политики доступа
* Политика DM
* Политика групп
* Поддержка медиа
* Входящие (получение)
* AES-128-ECB зашифрованный CDN
* Исходящие (отправка)
* Постоянство контекстного токена
* Форматирование Markdown
* Разбивка сообщений
* Индикаторы печати
* Long-Poll соединение
* Как это работает
* Поведение при повторах
* Дедупликация
* Блокировка токена
* Все переменные окружения
* Устранение неполадок