Skip to content

feat(line): add LINE Messaging API platform plugin#21020

Closed
perng wants to merge 1 commit intoNousResearch:mainfrom
perng:claude/cranky-pike-656cfa
Closed

feat(line): add LINE Messaging API platform plugin#21020
perng wants to merge 1 commit intoNousResearch:mainfrom
perng:claude/cranky-pike-656cfa

Conversation

@perng
Copy link
Copy Markdown

@perng perng commented May 7, 2026

What does this PR do?

Adds a LINE Messaging API platform adapter under plugins/platforms/line/ so Hermes Agent can be run as a LINE bot. LINE is the dominant messaging app in Taiwan, Japan, and Thailand, and there is currently no gateway option for users in those markets.

The adapter is modeled on the existing teams/irc plugins and the OpenClaw extensions/line channel, and uses the plugin path (plugins/platforms/line/) per gateway/platforms/ADDING_A_PLATFORM.md — no edits to core files needed; Platform("line") is auto-discovered via the bundled-plugin scan in gateway/config.py.

Related Issue

Fixes #6081
Refs #16611

Type of Change

  • ✨ New feature (non-breaking change that adds functionality)
  • ✅ Tests (adding or improving test coverage)

Changes Made

  • plugins/platforms/line/adapter.pyLineAdapter(BasePlatformAdapter):
    • aiohttp webhook server at /line/webhook, HMAC-SHA256 + base64 X-Line-Signature verification (constant-time hmac.compare_digest, 64 KB body cap)
    • chat-id resolution for user / group / room sources
    • outbound sends via the LINE Messaging API: reply token preferred (50s TTL cap, single-use), automatic fallback to push API when token is absent, expired, or rejected
    • 5-message-per-call batching as the LINE API requires
    • inbound image attachments fetched from api-data.line.me/.../content and cached via cache_image_from_bytes
    • send_typing wired to LINE's chat/loading/start ("loading animation") endpoint; skipped client-side for group/room IDs which the API rejects
    • self-message filter via /v2/bot/info userId, plus MessageDeduplicator
    • LINE_ALLOWED_USERS / LINE_ALLOW_ALL_USERS access control (wired through register_platform)
    • interactive_setup() for hermes setup line
  • plugins/platforms/line/plugin.yaml + __init__.py — auto-discovery
  • tests/gateway/test_line_adapter.py — 27 tests (signature validation, source resolution, reply-token TTL, push fallback, message batching, loading-animation indicator, register metadata)
  • scripts/line_adapter_test.py — standalone runner that boots only the adapter (no full gateway) for quick local webhook testing

How to Test

Unit tests:

pytest tests/gateway/test_line_adapter.py -v
# → 27 passed

Live channel:

  1. Create a Messaging API channel at https://developers.line.biz/console/ and obtain LINE_CHANNEL_ACCESS_TOKEN + LINE_CHANNEL_SECRET.
  2. Add to ~/.hermes/.env:
    LINE_CHANNEL_ACCESS_TOKEN=...
    LINE_CHANNEL_SECRET=...
  3. Add to ~/.hermes/config.yaml:
    platforms:
      line:
        enabled: true
  4. Expose port 3979 with cloudflared tunnel --url http://localhost:3979 (or ngrok).
  5. Set the channel's webhook URL to https://<tunnel>/line/webhook and click Verify in the LINE console.
  6. hermes --gateway → message your bot from the LINE app.

Verified end-to-end against a real LINE channel in 1:1 DM and group chat with gemini-3-flash-preview.

Checklist

Code

  • I've read the Contributing Guide
  • My commit messages follow Conventional Commits
  • I searched for existing PRs to make sure this isn't a duplicate
  • My PR contains only changes related to this feature
  • I've run pytest tests/gateway/test_line_adapter.py -v and all 27 tests pass
  • I've added tests for my changes
  • I've tested on my platform: macOS 15 (Darwin 25.4.0), Python 3.12

Documentation & Housekeeping

  • N/A — adapter docstring + plugin.yaml describe configuration; follows the gateway/platforms/ADDING_A_PLATFORM.md plugin path
  • N/A — no new keys in cli-config.yaml.example; standard platforms.<name>.{enabled, extra} shape
  • N/A — no architecture/workflow change
  • Cross-platform: pure Python + aiohttp, no platform-specific code
  • N/A — no tool descriptions changed

Notes for reviewers

Relationship to #16611: That issue references leepoweii/hermes-agent@feat/line-adapter, which uses the built-in path (gateway/platforms/line.py + edits to Platform enum + setup wizard) and adds a PENDING/READY/DELIVERED postback Quick Reply state machine for slow LLM responses. This PR uses the plugin path (recommended in ADDING_A_PLATFORM.md) and handles the 60-second reply-token deadline by capping internal token validity at 50s and falling back to push — simpler, no postback UX, but functionally correct for the deadline. Maintainers may prefer the leepoweii approach for #16611; happy to defer to whichever you want to land.

LINE_PORT default: 3979 (Teams uses 3978). Override with extra.port in config.yaml or LINE_PORT env var.

Adds a LINE platform adapter under plugins/platforms/line/ so Hermes
Agent can be run as a LINE bot (the dominant messaging app in Taiwan,
Japan, and Thailand).

Adapter is modeled on the openclaw line extension and the existing
teams/irc plugins:

- aiohttp webhook server at /line/webhook with HMAC-SHA256 + base64
  signature verification (constant-time comparison, 64 KB body cap)
- chat-id resolution for user / group / room sources
- outbound sends via the LINE Messaging API: reply token preferred
  (50s TTL cap, single-use), automatic fallback to push when the
  token is absent, expired, or rejected
- 5-message-per-call batching as the LINE API requires
- inbound image attachments fetched from api-data.line.me/.../content
  and cached via cache_image_from_bytes
- send_typing wired to LINE's chat/loading/start ("loading animation")
  endpoint; skipped for group/room IDs which the API rejects
- self-message filter via /v2/bot/info userId, plus dedup cache
- LINE_ALLOWED_USERS / LINE_ALLOW_ALL_USERS access control
- interactive_setup() for hermes setup line

Also includes:
- tests/gateway/test_line_adapter.py — 27 tests covering signature
  validation, source resolution, reply-token TTL, push fallback,
  message batching, and the loading-animation indicator
- scripts/line_adapter_test.py — standalone runner that boots only
  the adapter (no full gateway) for local webhook testing

Verified end-to-end against a real LINE channel in 1:1 DM and group
chat.

Closes NousResearch#6081
Refs  NousResearch#16611
@perng
Copy link
Copy Markdown
Author

perng commented May 7, 2026

Closing — re-opening from a properly named branch (feat/line-adapter) per the contributing guideline.

@perng perng closed this May 7, 2026
@perng perng deleted the claude/cranky-pike-656cfa branch May 7, 2026 04:18
@alt-glitch alt-glitch added type/feature New feature or request P3 Low — cosmetic, nice to have comp/gateway Gateway runner, session dispatch, delivery comp/plugins Plugin system and bundled plugins labels May 7, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp/gateway Gateway runner, session dispatch, delivery comp/plugins Plugin system and bundled plugins P3 Low — cosmetic, nice to have type/feature New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature]: LINE Messaging Platform Adapter

2 participants