Настройка LINE

Запустите Hermes Agent как бота LINE через официальный LINE Messaging API. Адаптер находится как встроенный плагин платформы в plugins/platforms/line/ — без редактирования ядра, просто включите его, как любую другую платформу.

LINE — доминирующее приложение для обмена сообщениями в Японии, Тайване и Таиланде. Если ваши пользователи живут там, вот как они могут связаться с вами.

Как бот отвечает

Context Behavior
Чат 1:1 (U ID) Отвечает на каждое сообщение
Групповой чат (C ID) Отвечает, когда группа находится в белом списке
Многопользовательская комната (R ID) Отвечает, когда комната находится в белом списке

Входящий текст, изображения, аудио, видео, файлы, стикеры и местоположения — всё обрабатывается. Исходящий текст использует сначала бесплатный токен ответа (одноразовый, окно ~60с) и переключается на платный Push API, когда токен истёк.


Шаг 1: Создайте канал LINE Messaging API

  1. Перейдите в консоль разработчиков LINE.

  2. Создайте провайдера, затем под ним канал Messaging API.

  3. На вкладке Основные настройки канала скопируйте Секрет канала.

  4. На вкладке Messaging API прокрутите до Токен доступа канала (долгоживущий) и нажмите Выпустить. Скопируйте токен.

  5. На вкладке Messaging API также отключите Автоответы и Приветственные сообщения, чтобы они не конфликтовали с ответами вашего бота.


Шаг 2: Откройте порт вебхука

LINE доставляет вебхуки через публичный HTTPS. Порт по умолчанию — 8646 — переопределите с помощью LINE_PORT, если необходимо.

# Cloudflare Tunnel (recommended for production — fixed hostname)
cloudflared tunnel --url http://localhost:8646

# ngrok (good for dev)
ngrok http 8646

# devtunnel
devtunnel create hermes-line --allow-anonymous
devtunnel port create hermes-line -p 8646 --protocol https
devtunnel host hermes-line

Скопируйте URL https://... — вы установите его как URL вебхука ниже. Оставьте туннель запущенным во время тестирования. Для продакшна настройте фиксированный именованный туннель Cloudflare, чтобы URL вебхука не менялся при перезапуске.


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

Добавьте в ~/.hermes/.env:

LINE_CHANNEL_ACCESS_TOKEN=YOUR_LONG_LIVED_TOKEN
LINE_CHANNEL_SECRET=YOUR_CHANNEL_SECRET

# Allowlist — at least one of these (or LINE_ALLOW_ALL_USERS=true for dev)
LINE_ALLOWED_USERS=U1234567890abcdef...           # comma-separated U-prefixed IDs
LINE_ALLOWED_GROUPS=C1234567890abcdef...          # optional group IDs
LINE_ALLOWED_ROOMS=R1234567890abcdef...           # optional room IDs

# Required for image / audio / video sends — the public HTTPS base URL
# the tunnel resolves to.  Without it, send_image/voice/video will refuse.
LINE_PUBLIC_URL=https://my-tunnel.example.com

Затем в ~/.hermes/config.yaml:

gateway:
  platforms:
    line:
      enabled: true

Этого достаточно — сканирование встроенных плагинов в gateway/config.py автоматически подхватывает plugins/platforms/line/. Никаких правок enum Platform.LINE, никакой регистрации _create_adapter.


Шаг 4: Установите URL вебхука

Вернитесь в консоль LINE:

  1. Откройте ваш канал → вкладка Messaging API.

  2. Под Настройки вебхукаURL вебхука, вставьте https://<ваш-туннель>/line/webhook (обратите внимание на путь /line/webhook — адаптер слушает там).

  3. Нажмите Проверить. LINE пингует URL; вы должны увидеть 200.

  4. Переключите Использовать вебхук в Вкл.


Шаг 5: Запустите шлюз

hermes gateway

В логе агента отображается:

LINE: webhook listening on 0.0.0.0:8646/line/webhook (public: https://my-tunnel.example.com)

Добавьте бота в друзья из приложения LINE (отсканируйте QR-код на вкладке Messaging API канала) и отправьте ему сообщение.


Медленные ответы LLM

Токен ответа LINE одноразовый и истекает примерно через 60 секунд после входящего события. Медленные LLM не могут ответить вовремя, что обычно вынудило бы использовать платный Push API.

Когда LLM всё ещё работает после LINE_SLOW_RESPONSE_THRESHOLD секунд (по умолчанию 45), адаптер использует исходный токен ответа для отправки пузырька Шаблонных кнопок:

🤔 Still thinking. Tap below to fetch the answer when it's ready.

[ Get answer ]

Пользователь нажимает Получить ответ, когда удобно — этот постбэк доставляет свежий токен ответа, который адаптер использует для отправки кэшированного ответа (по-прежнему бесплатно).

Конечный автомат: PENDING → READY → DELIVERED, плюс ERROR для отменённых запусков (осиротевший PENDING разрешается в "Запуск был прерван до завершения." после /stop, чтобы постоянная кнопка не зацикливалась).

Чтобы отключить кнопку постбэка и всегда использовать Push-запасной вариант:

LINE_SLOW_RESPONSE_THRESHOLD=0

Чтобы поток постбэка срабатывал надёжно, подавьте болтовню, которая израсходовала бы токен ответа до порога:

# ~/.hermes/config.yaml
display:
  interim_assistant_messages: false
  platforms:
    line:
      tool_progress: off

Доставка Cron / уведомлений

LINE_HOME_CHANNEL=Uxxxxxxxxxxxxxxxxxxxx     # default delivery target

Задания Cron с deliver: line маршрутизируются в LINE_HOME_CHANNEL. Адаптер поставляет отдельный отправитель только для Push, поэтому задания Cron работают, даже когда cron запускается в отдельном процессе от шлюза.


Справочник переменных окружения

Variable Required Default Description
LINE_CHANNEL_ACCESS_TOKEN yes Долгоживущий токен доступа канала
LINE_CHANNEL_SECRET yes Секрет канала (проверка вебхука HMAC-SHA256)
LINE_HOST no 0.0.0.0 Хост привязки вебхука
LINE_PORT no 8646 Порт привязки вебхука
LINE_PUBLIC_URL for media Публичный базовый HTTPS URL; требуется для отправки изображений/голоса/видео
LINE_ALLOWED_USERS one of ID пользователей через запятую (с префиксом U)
LINE_ALLOWED_GROUPS one of ID групп через запятую (с префиксом C)
LINE_ALLOWED_ROOMS one of ID комнат через запятую (с префиксом R)
LINE_ALLOW_ALL_USERS dev only false Полностью пропустить белый список
LINE_HOME_CHANNEL no Цель доставки cron / уведомлений по умолчанию
LINE_SLOW_RESPONSE_THRESHOLD no 45 Секунд до срабатывания кнопки постбэка (0 = отключено)
LINE_PENDING_TEXT no "🤔 Still thinking…" Текст пузырька, отображаемый рядом с кнопкой постбэка
LINE_BUTTON_LABEL no "Get answer" Метка кнопки
LINE_DELIVERED_TEXT no "Already replied ✅" Ответ при повторном нажатии уже доставленной кнопки
LINE_INTERRUPTED_TEXT no "Run was interrupted before completion." Ответ при нажатии осиротевшей кнопки /stop

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

"invalid signature" при проверке вебхука. Секрет канала был скопирован неправильно, или ваш туннель перезаписал тело запроса. Сначала проверьте с помощью curl -i https://<туннель>/line/webhook/health — это должно вернуть {"status":"ok","platform":"line"}.

Бот ничего не получает в группах. Проверьте, что LINE_ALLOWED_GROUPS включает ID группы C.... Чтобы найти ID группы, отправьте тестовое сообщение и найдите в ~/.hermes/logs/gateway.log LINE: rejecting unauthorized source — в отклонённом словаре источника есть ID.

send_image завершается ошибкой "LINE_PUBLIC_URL must be set". Messaging API LINE не принимает бинарные загрузки — изображения, аудио и видео должны быть доступны по HTTPS URL. Установите LINE_PUBLIC_URL на публичное имя хоста туннеля, и адаптер будет автоматически обслуживать файлы из /line/media/<token>/<filename>.

Кнопка постбэка никогда не появляется. Либо LLM ответил быстрее, чем LINE_SLOW_RESPONSE_THRESHOLD, либо другой пузырёк (прогресс инструмента, стриминг) первым израсходовал токен ответа. См. блок подавления в разделе "Медленные ответы LLM".

"уже используется другим профилем". Тот же токен доступа канала привязан к другому запущенному профилю Hermes. Остановите другой шлюз или используйте отдельный канал.


Ограничения

  • Один пузырёк на фрагмент. Каждый текстовый пузырёк LINE ограничен 5000 символами, и максимум 5 пузырьков отправляется за вызов Reply/Push. Более длинные ответы обрезаются с многоточием.

  • Нет встроенного редактирования сообщений. У LINE нет API редактирования сообщений — стриминговые ответы всегда отправляют свежие пузырьки, никогда не редактируя предыдущие.

  • Нет рендеринга Markdown. Жирный (**), курсив (*), блоки кода и заголовки отображаются как литеральные символы. Адаптер удаляет их перед отправкой; URL сохраняются ([метка](url) становится метка (url)).

  • Индикатор загрузки только для DM. LINE отклоняет API chat/loading для групп и комнат, поэтому индикатор набора текста отображается только в чатах 1:1.