Настройка Feishu / Lark

Hermes Agent интегрируется с Feishu и Lark в качестве полнофункционального бота. После подключения вы можете общаться с агентом в личных сообщениях или групповых чатах, получать результаты cron-задач в домашнем чате, а также отправлять текст, изображения, аудио и файлы через стандартный gateway-канал.

Интеграция поддерживает оба режима подключения:

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

Контекст Поведение
Личные сообщения Hermes отвечает на каждое сообщение.
Групповые чаты Hermes отвечает только когда бота упоминают через @ в чате.
Общие групповые чаты По умолчанию история сессии изолируется для каждого пользователя внутри общего чата.

Это поведение в общих чатах контролируется в config.yaml:

group_sessions_per_user: true

Установите значение false, только если вы явно хотите одну общую беседу на чат.

Шаг 1: Создайте приложение Feishu / Lark

hermes gateway setup

Выберите Feishu / Lark и отсканируйте QR-код с помощью мобильного приложения Feishu или Lark. Hermes автоматически создаст приложение-бота с правильными разрешениями и сохранит учётные данные.

Альтернатива: Ручная настройка

Если сканирование недоступно, мастер переключится на ручной ввод:

  1. Откройте консоль разработчика Feishu или Lark:
  2. Feishu: https://open.feishu.cn/
  3. Lark: https://open.larksuite.com/

  4. Создайте новое приложение.

  5. В разделе Credentials & Basic Info скопируйте App ID и App Secret.

  6. Включите возможность Bot для приложения.

  7. Запустите hermes gateway setup, выберите Feishu / Lark и введите учётные данные по запросу.

Храните App Secret в секрете. Любой, кто им завладеет, сможет выдать себя за ваше приложение.

Шаг 2: Выберите режим подключения

Используйте режим WebSocket, когда Hermes запущен на вашем ноутбуке, рабочей станции или частном сервере. Публичный URL не требуется. Официальный Lark SDK открывает и поддерживает постоянное исходящее WebSocket-соединение с автоматическим переподключением.

FEISHU_CONNECTION_MODE=websocket

Требования: Пакет Python websockets должен быть установлен. SDK управляет жизненным циклом соединения, heartbeat'ами и автоматическим переподключением.

Как это работает: Адаптер запускает WebSocket-клиент Lark SDK в фоновом потоке-исполнителе. Входящие события (сообщения, реакции, действия с карточками) отправляются в основной asyncio-цикл. При отключении SDK автоматически попытается переподключиться.

Опционально: Режим Webhook

Используйте режим webhook только если Hermes уже запущен за доступной HTTP-точкой.

FEISHU_CONNECTION_MODE=webhook

В режиме webhook Hermes запускает HTTP-сервер (через aiohttp) и обслуживает endpoint Feishu по адресу:

/feishu/webhook

Требования: Пакет Python aiohttp должен быть установлен.

Вы можете настроить адрес привязки и путь webhook-сервера:

FEISHU_WEBHOOK_HOST=127.0.0.1   # по умолчанию: 127.0.0.1
FEISHU_WEBHOOK_PORT=8765         # по умолчанию: 8765
FEISHU_WEBHOOK_PATH=/feishu/webhook  # по умолчанию: /feishu/webhook

Когда Feishu отправляет запрос проверки URL (type: url_verification), webhook отвечает автоматически, чтобы вы могли завершить настройку подписки в консоли разработчика Feishu.

Шаг 3: Настройте Hermes

Вариант A: Интерактивная настройка

hermes gateway setup

Выберите Feishu / Lark и следуйте подсказкам.

Вариант B: Ручная настройка

Добавьте следующее в ~/.hermes/.env:

FEISHU_APP_ID=cli_xxx
FEISHU_APP_SECRET=secret_xxx
FEISHU_DOMAIN=feishu
FEISHU_CONNECTION_MODE=websocket

# Опционально, но настоятельно рекомендуется
FEISHU_ALLOWED_USERS=ou_xxx,ou_yyy
FEISHU_HOME_CHANNEL=oc_xxx

FEISHU_DOMAIN принимает:

Шаг 4: Запустите Gateway

hermes gateway

Затем отправьте сообщение боту в Feishu/Lark, чтобы подтвердить, что соединение активно.

Домашний чат

Используйте /set-home в чате Feishu/Lark, чтобы назначить его домашним каналом для результатов cron-задач и кроссплатформенных уведомлений.

Вы также можете настроить его заранее:

FEISHU_HOME_CHANNEL=oc_xxx

Безопасность

Белый список пользователей

Для production-использования задайте белый список Feishu Open ID:

FEISHU_ALLOWED_USERS=ou_xxx,ou_yyy

Если оставить белый список пустым, любой, кто может связаться с ботом, сможет его использовать. В групповых чатах белый список проверяется по open_id отправителя перед обработкой сообщения.

Ключ шифрования Webhook

При работе в режиме webhook установите ключ шифрования для проверки подписи входящих webhook-запросов:

FEISHU_ENCRYPT_KEY=your-encrypt-key

Этот ключ находится в разделе Event Subscriptions конфигурации вашего приложения Feishu. При установке адаптер проверяет каждый webhook-запрос с помощью алгоритма подписи:

SHA256(timestamp + nonce + encrypt_key + body)

Вычисленный хеш сравнивается с заголовком x-lark-signature с использованием время-безопасного сравнения. Запросы с недействительными или отсутствующими подписями отклоняются с HTTP 401.

В режиме WebSocket проверка подписи выполняется самим SDK, поэтому `FEISHU_ENCRYPT_KEY` необязателен. В режиме webhook он настоятельно рекомендуется для production.

Токен верификации

Дополнительный уровень аутентификации, который проверяет поле token внутри webhook-запросов:

FEISHU_VERIFICATION_TOKEN=your-verification-token

Этот токен также находится в разделе Event Subscriptions вашего приложения Feishu. При установке каждый входящий webhook-запрос должен содержать соответствующий token в своём объекте header. Несовпадающие токены отклоняются с HTTP 401.

Оба параметра FEISHU_ENCRYPT_KEY и FEISHU_VERIFICATION_TOKEN могут использоваться вместе для многоуровневой защиты.

Политика групповых сообщений

Переменная окружения FEISHU_GROUP_POLICY управляет тем, как и отвечает ли Hermes в групповых чатах:

FEISHU_GROUP_POLICY=allowlist   # по умолчанию
Значение Поведение
open Hermes отвечает на @упоминания от любого пользователя в любой группе.
allowlist Hermes отвечает только на @упоминания от пользователей из FEISHU_ALLOWED_USERS.
disabled Hermes полностью игнорирует все групповые сообщения.

Во всех режимах бот должен быть явно упомянут через @ (или @all) в группе, прежде чем сообщение будет обработано. Личные сообщения всегда обходят этот фильтр.

Установите FEISHU_REQUIRE_MENTION=false, чтобы разрешить Hermes читать весь групповой трафик без необходимости @упоминания:

FEISHU_REQUIRE_MENTION=false

Для контроля на уровне каждого чата установите require_mention в записи group_rules — см. Контроль доступа по группам ниже.

Идентификация бота

Hermes автоматически определяет open_id и отображаемое имя бота при запуске. Вам нужно устанавливать их вручную только если автоопределение не может связаться с API Feishu, или если ваше приложение использует tenant-scoped user ID:

FEISHU_BOT_OPEN_ID=ou_xxx     # только если автоопределение не сработало
FEISHU_BOT_USER_ID=xxx        # требуется, если приложение использует sender_id_type=user_id
FEISHU_BOT_NAME=MyBot         # только если автоопределение не сработало

Обмен сообщениями между ботами

По умолчанию Hermes игнорирует сообщения, отправленные другими ботами. Включите обмен сообщениями между ботами, если вы хотите, чтобы Hermes участвовал в A2A-оркестрации или получал уведомления от других ботов в той же группе.

FEISHU_ALLOW_BOTS=mentions   # по умолчанию: none
Значение Поведение
none Игнорировать все сообщения от других ботов (по умолчанию).
mentions Принимать только когда бот-отправитель @упоминает Hermes.
all Принимать все сообщения от других ботов.

Также настраивается как feishu.allow_bots в config.yaml (переменная окружения имеет приоритет, если заданы оба значения).

Ботов-отправителей не нужно добавлять в FEISHU_ALLOWED_USERS — этот белый список применяется только к пользователям-людям.

Предоставьте область application:bot.basic_info:read, чтобы отображать имена ботов-отправителей; без неё боты-отправители всё равно будут корректно маршрутизироваться, но будут отображаться как их open_id.

Интерактивные действия с карточками

Когда пользователи нажимают кнопки или взаимодействуют с интерактивными карточками, отправленными ботом, адаптер маршрутизирует эти действия как синтетические события команды /card:

Запросы на подтверждение обновления от gateway используют нативную карточку Feishu Да / Нет вместо обычных текстовых ответов. Когда hermes update --gateway требует подтверждения, адаптер записывает выбранный ответ в файл .update_response и заменяет карточку на resolved-состояние.

События действий с карточками отправляются с типом MessageType.COMMAND, поэтому они проходят через обычный конвейер обработки команд.

Также работает подтверждение команд — когда агенту нужно выполнить опасную команду, он отправляет интерактивную карточку с кнопками Allow Once / Session / Always / Deny. Пользователь нажимает кнопку, и callback действия с карточкой доставляет решение о подтверждении обратно агенту.

Требуемая конфигурация приложения Feishu

Интерактивные карточки требуют трёх шагов настройки в консоли разработчика Feishu. Отсутствие любого из них вызывает ошибку 200340 при нажатии пользователями кнопок на карточках.

  1. Подпишитесь на событие card action: В разделе Event Subscriptions добавьте card.action.trigger в подписанные события.

  2. Включите возможность Interactive Card: В разделе App Features > Bot убедитесь, что переключатель Interactive Card включён. Это сообщает Feishu, что ваше приложение может получать callback'и действий с карточками.

  3. Настройте Card Request URL (только для webhook-режима): В разделе App Features > Bot > Message Card Request URL установите URL на тот же endpoint, что и для событий webhook (например, https://your-server:8765/feishu/webhook). В режиме WebSocket это обрабатывается автоматически SDK.

Без всех трёх шагов Feishu будет успешно *отправлять* интерактивные карточки (для отправки требуется только разрешение `im:message:send`), но нажатие любой кнопки приведёт к ошибке 200340. Карточка выглядит работающей — ошибка проявляется только при взаимодействии с ней.

Интеллектуальные ответы на комментарии в документах

Помимо чата, адаптер также может отвечать на @-упоминания, оставленные на документах Feishu/Lark. Когда пользователь комментирует документ (локальный выделенный текст или комментарий ко всему документу) и @упоминает бота, Hermes читает документ вместе с окружающей веткой комментариев и публикует ответ LLM непосредственно в ветке.

Работает на основе события drive.notice.comment_add_v1. Обработчик:

Трёхуровневый контроль доступа

Ответы на комментарии в документах работают только по явному разрешению — нет неявного режима «разрешить всем». Разрешения разрешаются в следующем порядке (первое совпадение выигрывает, для каждого поля):

  1. Точный документ — правило, ограниченное конкретным токеном документа.

  2. Wildcard — правило, соответствующее шаблону документов.

  3. Верхний уровень — правило по умолчанию для рабочей области.

Две доступные политики для каждого правила:

Правила хранятся в ~/.hermes/feishu_comment_rules.json (разрешения pairing — в ~/.hermes/feishu_comment_pairing.json) с hot-reload'ом на основе времени изменения файла — изменения вступают в силу при следующем событии комментария без перезапуска gateway.

CLI:

# Просмотр текущих правил и состояния pairing
python -m gateway.platforms.feishu_comment_rules status

# Симуляция проверки доступа для конкретного документа + пользователя
python -m gateway.platforms.feishu_comment_rules check <fileType:fileToken> <user_open_id>

# Управление pairing-разрешениями в реальном времени
python -m gateway.platforms.feishu_comment_rules pairing list
python -m gateway.platforms.feishu_comment_rules pairing add <user_open_id>
python -m gateway.platforms.feishu_comment_rules pairing remove <user_open_id>

Требуемая конфигурация приложения Feishu

В дополнение к уже предоставленным разрешениям для чата/карточек, добавьте событие drive comment:

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

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

Адаптер получает и кэширует следующие типы медиа от пользователей:

Тип Расширения Как обрабатывается
Изображения .jpg, .jpeg, .png, .gif, .webp, .bmp Загружаются через API Feishu и кэшируются локально
Аудио .ogg, .mp3, .wav, .m4a, .aac, .flac, .opus, .webm Загружаются и кэшируются; мелкие текстовые файлы извлекаются автоматически
Видео .mp4, .mov, .avi, .mkv, .webm, .m4v, .3gp Загружаются и кэшируются как документы
Файлы .pdf, .doc, .docx, .xls, .xlsx, .ppt, .pptx и другие Загружаются и кэшируются как документы

Медиа из сообщений с rich-текстом (post), включая встроенные изображения и вложения файлов, также извлекаются и кэшируются.

Для небольших текстовых документов (.txt, .md) содержимое файла автоматически вставляется в текст сообщения, чтобы агент мог прочитать его напрямую без использования инструментов.

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

Метод Что отправляет
send Текстовые или rich post-сообщения (автоопределение на основе markdown-содержимого)
send_image / send_image_file Загружает изображение в Feishu, затем отправляет как нативный image-пузырёк (с опциональной подписью)
send_document Загружает файл в API Feishu, затем отправляет как вложение файла
send_voice Загружает аудиофайл как вложение файла Feishu
send_video Загружает видео и отправляет как нативное медиа-сообщение
send_animation GIF конвертируются во вложения файлов (у Feishu нет нативного GIF-пузырька)

Маршрутизация загрузки файлов автоматическая на основе расширения:

Рендеринг Markdown и резервный Post-режим

Когда исходящий текст содержит markdown-форматирование (заголовки, жирный текст, списки, блоки кода, ссылки и т.д.), адаптер автоматически отправляет его как сообщение Feishu post со встроенным тегом md, а не как обычный текст. Это обеспечивает расширенный рендеринг в клиенте Feishu.

Если API Feishu отклоняет post-полезную нагрузку (например, из-за неподдерживаемых markdown-конструкций), адаптер автоматически переключается на отправку обычного текста с удалённой markdown-разметкой. Этот двухэтапный резервный механизм гарантирует, что сообщения всегда доставляются.

Обычные текстовые сообщения (без обнаруженного markdown) отправляются как простой тип сообщения text.

Реакции статуса обработки

Пока агент работает, бот показывает реакцию Typing на вашем сообщении. Она очищается, когда приходит ответ, или заменяется на CrossMark, если обработка завершилась ошибкой.

Установите FEISHU_REACTIONS=false, чтобы отключить это.

Защита от всплесков и пакетирование

Адаптер включает подавление для быстрых всплесков сообщений, чтобы не перегружать агента:

Пакетирование текста

Когда пользователь отправляет несколько текстовых сообщений подряд, они объединяются в одно событие перед отправкой:

Настройка Переменная окружения По умолчанию
Период тишины HERMES_FEISHU_TEXT_BATCH_DELAY_SECONDS 0.6 с
Макс. сообщений в пакете HERMES_FEISHU_TEXT_BATCH_MAX_MESSAGES 8
Макс. символов в пакете HERMES_FEISHU_TEXT_BATCH_MAX_CHARS 4000

Пакетирование медиа

Несколько вложений медиа, отправленных подряд (например, перетаскивание нескольких изображений), объединяются в одно событие:

Настройка Переменная окружения По умолчанию
Период тишины HERMES_FEISHU_MEDIA_BATCH_DELAY_SECONDS 0.8 с

Сериализация по чатам

Сообщения внутри одного чата обрабатываются последовательно (по одному за раз) для поддержания связности беседы. У каждого чата своя блокировка, поэтому сообщения в разных чатах обрабатываются параллельно.

Ограничение скорости (Webhook-режим)

В режиме webhook адаптер применяет ограничение скорости по IP для защиты от злоупотреблений:

Запросы, превышающие лимит, получают HTTP 429 (Too Many Requests).

Отслеживание аномалий Webhook

Адаптер отслеживает последовательные ответы с ошибками для каждого IP-адреса. После 25 последовательных ошибок с одного IP в течение 6-часового окна в лог записывается предупреждение. Это помогает обнаружить неправильно настроенные клиенты или попытки сканирования.

Дополнительные защиты webhook:

Настройка WebSocket

При использовании режима websocket вы можете настроить поведение переподключения и ping:

platforms:
  feishu:
    extra:
      ws_reconnect_interval: 120   # Секунды между попытками переподключения (по умолчанию: 120)
      ws_ping_interval: 30         # Секунды между WebSocket ping'ами (опционально; SDK по умолчанию, если не задано)
Настройка Ключ конфига По умолчанию Описание
Интервал переподключения ws_reconnect_interval 120 с Как долго ждать между попытками переподключения
Интервал ping ws_ping_interval (по умолчанию SDK) Частота keepalive-пингов WebSocket

Контроль доступа по группам

Помимо глобальной FEISHU_GROUP_POLICY, вы можете задать детальные правила для каждого группового чата, используя group_rules в config.yaml:

platforms:
  feishu:
    extra:
      default_group_policy: "open"     # По умолчанию для групп, не указанных в group_rules
      admins:                          # Пользователи, которые могут управлять настройками бота
        - "ou_admin_open_id"
      group_rules:
        "oc_group_chat_id_1":
          policy: "allowlist"          # open | allowlist | blacklist | admin_only | disabled
          allowlist:
            - "ou_user_open_id_1"
            - "ou_user_open_id_2"
        "oc_group_chat_id_2":
          policy: "admin_only"
        "oc_group_chat_id_3":
          policy: "blacklist"
          blacklist:
            - "ou_blocked_user"
        "oc_free_chat":
          policy: "open"
          require_mention: false       # переопределяет FEISHU_REQUIRE_MENTION для этого чата
Политика Описание
open Любой участник группы может использовать бота
allowlist Только пользователи из allowlist группы могут использовать бота
blacklist Все, кроме пользователей из blacklist группы, могут использовать бота
admin_only Только пользователи из глобального списка admins могут использовать бота в этой группе
disabled Бот игнорирует все сообщения в этой группе

Установите require_mention: false в записи group_rules, чтобы пропустить требование @упоминания для этого конкретного чата. Если не указано, чат наследует глобальное значение FEISHU_REQUIRE_MENTION.

Группы, не указанные в group_rules, используют default_group_policy (по умолчанию равно значению FEISHU_GROUP_POLICY).

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

Входящие сообщения дедуплицируются с использованием ID сообщений и TTL в 24 часа. Состояние дедупликации сохраняется между перезапусками в файл ~/.hermes/feishu_seen_message_ids.json.

Настройка Переменная окружения По умолчанию
Размер кэша HERMES_FEISHU_DEDUP_CACHE_SIZE 2048 записей

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

Переменная Обязательная По умолчанию Описание
FEISHU_APP_ID Feishu/Lark App ID
FEISHU_APP_SECRET Feishu/Lark App Secret
FEISHU_DOMAIN feishu feishu (Китай) или lark (международный)
FEISHU_CONNECTION_MODE websocket websocket или webhook
FEISHU_ALLOWED_USERS (пусто) Список open_id через запятую для белого списка пользователей
FEISHU_ALLOW_BOTS none Принимать сообщения от других ботов: none, mentions или all
FEISHU_REQUIRE_MENTION true Должны ли групповые сообщения @упоминать бота
FEISHU_HOME_CHANNEL ID чата для вывода cron/уведомлений
FEISHU_ENCRYPT_KEY (пусто) Ключ шифрования для проверки подписи webhook
FEISHU_VERIFICATION_TOKEN (пусто) Токен верификации для аутентификации webhook-запросов
FEISHU_GROUP_POLICY allowlist Политика групповых сообщений: open, allowlist, disabled
FEISHU_BOT_OPEN_ID (пусто) open_id бота (для обнаружения @упоминаний)
FEISHU_BOT_USER_ID (пусто) user_id бота (для обнаружения @упоминаний)
FEISHU_BOT_NAME (пусто) Отображаемое имя бота (для обнаружения @упоминаний)
FEISHU_WEBHOOK_HOST 127.0.0.1 Адрес привязки webhook-сервера
FEISHU_WEBHOOK_PORT 8765 Порт webhook-сервера
FEISHU_WEBHOOK_PATH /feishu/webhook Путь endpoint'а webhook
HERMES_FEISHU_DEDUP_CACHE_SIZE 2048 Макс. количество отслеживаемых дедуплицированных ID сообщений
HERMES_FEISHU_TEXT_BATCH_DELAY_SECONDS 0.6 Период подавления всплесков текстовых сообщений
HERMES_FEISHU_TEXT_BATCH_MAX_MESSAGES 8 Макс. сообщений, объединяемых в текстовый пакет
HERMES_FEISHU_TEXT_BATCH_MAX_CHARS 4000 Макс. символов, объединяемых в текстовый пакет
HERMES_FEISHU_MEDIA_BATCH_DELAY_SECONDS 0.8 Период подавления всплесков медиа

Настройки WebSocket и ACL по группам настраиваются в config.yaml в разделе platforms.feishu.extra (см. Настройка WebSocket и Контроль доступа по группам выше).

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

Проблема Решение
lark-oapi not installed Установите SDK: pip install lark-oapi
websockets not installed; websocket mode unavailable Установите websockets: pip install websockets
aiohttp not installed; webhook mode unavailable Установите aiohttp: pip install aiohttp
FEISHU_APP_ID or FEISHU_APP_SECRET not set Установите обе переменные окружения или настройте через hermes gateway setup
Another local Hermes gateway is already using this Feishu app_id Только один экземпляр Hermes может использовать один app_id одновременно. Сначала остановите другой gateway.
Бот не отвечает в группах Убедитесь, что бот упомянут через @, проверьте FEISHU_GROUP_POLICY и убедитесь, что отправитель есть в FEISHU_ALLOWED_USERS, если политика allowlist
Webhook rejected: invalid verification token Убедитесь, что FEISHU_VERIFICATION_TOKEN соответствует токену в конфигурации Event Subscriptions вашего приложения Feishu
Webhook rejected: invalid signature Убедитесь, что FEISHU_ENCRYPT_KEY соответствует ключу шифрования в конфигурации вашего приложения Feishu
Post-сообщения отображаются как обычный текст API Feishu отклонил post-полезную нагрузку; это нормальное резервное поведение. Проверьте логи для подробностей.
Изображения/файлы не получены ботом Предоставьте области разрешений im:message и im:resource вашему приложению Feishu
Идентификация бота не определена автоматически Обычно временная сетевая проблема при обращении к endpoint'у информации о боте Feishu. Установите FEISHU_BOT_OPEN_ID и FEISHU_BOT_NAME вручную как обходное решение.
Сообщения от других ботов всё ещё игнорируются после включения FEISHU_ALLOW_BOTS Hermes не может идентифицировать себя — установите FEISHU_BOT_OPEN_IDFEISHU_BOT_USER_ID, если ваше приложение использует sender_id_type=user_id).
Боты-отправители отображаются как ou_xxxxxx вместо имени Предоставьте область application:bot.basic_info:read.
Ошибка 200340 при нажатии кнопок подтверждения Включите возможность Interactive Card и настройте Card Request URL в консоли разработчика Feishu. См. Требуемая конфигурация приложения Feishu выше.
Webhook rate limit exceeded Более 120 запросов/минуту с одного IP. Обычно это неправильная конфигурация или зацикливание.

Набор инструментов

Feishu / Lark использует предустановку платформы hermes-feishu, которая включает те же основные инструменты, что и Telegram и другие платформы обмена сообщениями на основе gateway.