plugins/platforms/line/ — no core edits, just enable it like any other platform.
LINE is the dominant messaging app in Japan, Taiwan, and Thailand. If your users live there, this is how they reach you.
Run mibyan gateway setup and pick LINE for a guided walk-through.
How the bot responds
Inbound text, images, audio, video, files, stickers, and locations are all handled. Outbound text uses the free reply token first (single-use, ~60s window) and falls back to the metered Push API when the token has expired.
Step 1: Create a LINE Messaging API channel
- Go to the LINE Developers Console.
- Create a Provider, then under it a Messaging API channel.
- From the channel’s Basic settings tab, copy the Channel secret.
- From the Messaging API tab, scroll to Channel access token (long-lived) and click Issue. Copy the token.
- In the Messaging API tab, also disable Auto-reply messages and Greeting messages so they don’t fight your bot’s replies.
Step 2: Expose the webhook port
LINE delivers webhooks over public HTTPS. The default port is8646 — override with LINE_PORT if needed.
https://... URL — you’ll set it as the webhook URL below. Leave the tunnel running while testing. For production, set up a fixed Cloudflare named tunnel so the webhook URL doesn’t change on restart.
Step 3: Configure Mibyan
Add to~/.mibyan/.env:
~/.mibyan/config.yaml:
gateway/config.py automatically picks up plugins/platforms/line/. No Platform.LINE enum edit, no _create_adapter registration.
Step 4: Set the webhook URL
Back in the LINE console:- Open your channel → Messaging API tab.
- Under Webhook settings → Webhook URL, paste
https://<your-tunnel>/line/webhook(note the/line/webhookpath — the adapter listens there). - Click Verify. LINE pings the URL; you should see a 200.
- Toggle Use webhook to On.
Step 5: Run the gateway
Slow LLM responses
LINE’s reply token is single-use and expires roughly 60 seconds after the inbound event. Slow LLMs can’t reply in time, which would normally force a paid Push API call. When the LLM is still running pastLINE_SLOW_RESPONSE_THRESHOLD seconds (default 45), the adapter consumes the original reply token to send a Template Buttons bubble:
🤔 Still thinking. Tap below to fetch the answer when it’s ready. [ Get answer ]The user taps Get answer when convenient — that postback delivers a fresh reply token, which the adapter uses to send the cached answer (still free). State machine:
PENDING → READY → DELIVERED, plus ERROR for cancelled runs (the orphan PENDING resolves to “Run was interrupted before completion.” after /stop so the persistent button doesn’t loop).
To disable the postback button and always Push-fallback instead:
Cron / notification delivery
deliver: line route to LINE_HOME_CHANNEL. The adapter ships a standalone Push-only sender so cron jobs work even when cron runs in a separate process from the gateway.
Environment variable reference
Troubleshooting
“invalid signature” on webhook verify. TheChannel secret was copied wrong, or your tunnel rewrote the request body. Verify with curl -i https://<tunnel>/line/webhook/health first — that should return {"status":"ok","platform":"line"}.
Bot receives nothing in groups. Check LINE_ALLOWED_GROUPS includes the C... group ID. To find a group ID, send a test message and grep ~/.mibyan/logs/gateway.log for LINE: rejecting unauthorized source — the rejected source dict has the IDs.
send_image fails with “LINE_PUBLIC_URL must be set”. LINE’s Messaging API does not accept binary uploads — images, audio, and video must be reachable HTTPS URLs. Set LINE_PUBLIC_URL to the tunnel’s public hostname and the adapter will serve files from /line/media/<token>/<filename> automatically.
Postback button never appears. Either the LLM responded faster than LINE_SLOW_RESPONSE_THRESHOLD, or another bubble (tool-progress, streaming) consumed the reply token first. See the suppression block under “Slow LLM responses”.
“already in use by another profile”. The same channel access token is bound to another running Mibyan profile. Stop the other gateway or use a separate channel.
Limitations
- Bubble and length caps. Each LINE text bubble is capped at 5000 characters. Longer responses are smart-chunked at ~4500 characters across up to 5 bubbles per Reply/Push call, splitting on natural boundaries where possible.
- No native message editing. LINE has no edit-message API — streaming responses always send fresh bubbles, never edit prior ones.
- No Markdown rendering. Bold (
**), italics (*), code fences, and headings render as literal characters. The adapter strips them before sending; URLs are preserved ([label](https://github.com/NousResearch/hermes-agent/tree/main/website/docs/user-guide/messaging/url)becomeslabel (url)). - Loading indicator is DM-only. LINE rejects the chat/loading API for groups and rooms, so the typing indicator only shows in 1:1 chats.

