Unified Mode (v0.9.0+): The OAB binary now embeds the line adapter directly. Set
LINE_CHANNEL_SECRETas an env var — no separate gateway container or[gateway]config needed. See Telegram docs for the pattern.
Minimal:
[agent]
env = { KIRO_API_KEY = "${KIRO_API_KEY}" }Recommended:
[agent]
env = { KIRO_API_KEY = "${KIRO_API_KEY}" }
[pool]
max_sessions = 3
session_ttl_hours = 1
[reactions]
tool_display = "compact"
[markdown]
tables = "off"Set LINE_CHANNEL_SECRET (and related platform env vars) on the container. No [gateway] needed.
Connect a LINE bot to OpenAB via the Custom Gateway.
LINE ──POST──▶ Gateway (:8080) ◀──WebSocket── OAB Pod
(OAB connects out)
- A running OAB instance (with kiro-cli or any ACP agent authenticated)
- The Custom Gateway deployed (gateway/README.md)
- A LINE Official Account with Messaging API enabled
- Go to LINE Official Account Manager and create a new account
- After creation, go to Settings → Messaging API → Enable Messaging API
- Select or create a Provider, then confirm
The channel now appears in the LINE Developers Console.
In the LINE Developers Console, open your channel:
- Basic settings tab → Channel secret → copy (→
LINE_CHANNEL_SECRET) - Messaging API tab → scroll to bottom → Channel access token → Issue → copy (→
LINE_CHANNEL_ACCESS_TOKEN)
Add the LINE env vars to your gateway deployment:
# Docker
docker run -d --name openab-gateway \
-e TELEGRAM_BOT_TOKEN="..." \
-e LINE_CHANNEL_SECRET="your-channel-secret" \
-e LINE_CHANNEL_ACCESS_TOKEN="your-channel-access-token" \
-p 8080:8080 \
ghcr.io/openabdev/openab-gateway:0.3.0
# Kubernetes
kubectl set env deployment/openab-gateway \
LINE_CHANNEL_SECRET="your-channel-secret" \
LINE_CHANNEL_ACCESS_TOKEN="your-channel-access-token"In the LINE Developers Console → Messaging API tab:
- Webhook URL → Edit → enter:
https://gw.yourdomain.com/webhook/line - Use webhook → ON
- Auto-reply messages → OFF (prevents LINE's default auto-reply from interfering)
- Click Verify to test the connection
[gateway]
url = "ws://openab-gateway:8080/ws"
platform = "line"
# allowed_users = ["U1234567890abcdef"] # restrict to specific LINE user IDs
# allowed_channels = ["C1234567890abcdef"] # restrict to specific chat/group IDs
[agent]Tip: To find a LINE user ID, check the gateway logs — the sender ID is logged for each incoming message. By default all users and channels are allowed. Setting
allowed_usersorallowed_channelsautomatically restricts access to only those listed.
Trust resolution: the
[line]section's trust settings apply in both deployment modes. Broker-side enforcement goes through the shared per-platform trust registry with precedenceGATEWAY_*env <[gateway]section <[line]section — in the standalone-gateway mode, the broker's WebSocket path consults the same registry, so a[line]section overrides[gateway].allow_all_users/allowed_usersfor this platform.
Identity trust defaults to deny-all (identity-trust-none ADR): unknown senders are rejected until explicitly admitted. Configure trust with a first-class [line] section:
[line]
allowed_users = ["U1234567890abcdef0123456789abcdef"] # LINE user IDs (U…, 33 chars)
# allow_all_users = true # explicit opt-in only — any user can drive the agentEach field falls back to its LINE_* env var when unset. Since #1376 the section also carries the channel credentials (channel_secret, channel_access_token) and webhook_path — config-first, env as fallback:
[line]
channel_secret = "${LINE_CHANNEL_SECRET}"
channel_access_token = "${LINE_CHANNEL_ACCESS_TOKEN}"This replaces the uniform GATEWAY_ALLOW_ALL_USERS / GATEWAY_ALLOWED_USERS env vars for LINE:
⚠️ Deprecated: driving LINE trust throughGATEWAY_ALLOW_ALL_USERS/GATEWAY_ALLOWED_USERSstill works but logs a startup warning; it will become a startup error in a later phase. Migrate to[line](orLINE_*env vars).
In the LINE Developers Console → Messaging API tab → scan the QR code with your LINE app, or search for the bot by its LINE ID.
- 1:1 chat — send a message to the bot, get an AI agent response
- Inbound voice messages in 1:1 chat — LINE-hosted audio messages are downloaded through the LINE Content API and forwarded to OpenAB as
audioattachments, so the existing STT flow can transcribe them. This requires[stt] enabled = truein OpenAB core. See STT (Speech-to-Text). - Group chat — add the bot to a group; it responds only when @-mentioned (see @mention gating below)
- Inbound images — user-sent LINE images are downloaded through the LINE Content API and forwarded to OpenAB as image attachments
- Webhook signature validation — HMAC-SHA256 via
LINE_CHANNEL_SECRET
Implementation tradeoff: OpenAB now acknowledges LINE webhooks before image download/processing so slow attachment work is less likely to trigger webhook redelivery. The follow-up image download and event emission happen asynchronously, which keeps the request path short but also means a crash after the HTTP 200 can still lose that in-flight work. This PR intentionally keeps scope small and does not add a separate background-task durability or duplicate-suppression layer on top of early-ack. Because image processing now happens after the ACK, an earlier image webhook can also reach OpenAB after a later text webhook from the same chat if the image path is slower. OpenAB now also caps how many LINE payloads can enter that post-ACK path concurrently; once the cap is full, new webhooks wait for capacity instead of creating unbounded background backlog. If a LINE-hosted image cannot be downloaded or decoded, OpenAB logs and skips that image event rather than synthesizing a fake text prompt.
- Threads — LINE has no thread/topic concept. All messages in a chat share one agent session.
- Reactions — LINE Bot API does not support message reactions.
- @mention gating — Supported (zero-config). In group/room chats the gateway only forwards messages where the bot is explicitly @-mentioned (LINE's native
mentionees[].isSelfsignal). 1:1 DMs are always forwarded. No env var is needed.- Limitation — non-text messages: LINE only attaches mention data to text messages. Images, videos, stickers, files, and location messages in groups are silently dropped because they cannot carry an @-mention.
- Limitation — group voice messages: LINE voice/audio messages in groups and rooms are also dropped today because audio messages do not carry mention metadata. This PR only enables inbound voice STT for 1:1 chats.
- Limitation —
@All: A group-wide@Allmention does not trigger the bot; only a direct@BotNamemention does. - Breaking change: This gating is always active. Deployments that previously relied on the bot responding to all group messages will need to @-mention the bot after upgrading.
- Markdown rendering — LINE uses its own text formatting. Agent replies are sent as plain text.
- External-content images — LINE image messages backed by
contentProvider.type = "external"are not downloaded yet. - External-content audio — LINE audio messages backed by
contentProvider.type = "external"are not downloaded yet.
| Variable | Required | Description |
|---|---|---|
LINE_CHANNEL_SECRET |
Yes* | Channel secret for webhook signature validation. *Fallback for [line].channel_secret — config wins |
LINE_CHANNEL_ACCESS_TOKEN |
Yes* | Channel access token for Reply/Push Message API and LINE-hosted image/audio downloads. *Fallback for [line].channel_access_token — config wins |
LINE_WEBHOOK_PATH |
No | Webhook mount path. Fallback for [line].webhook_path (default /webhook/line) |
LINE_ALLOW_ALL_USERS |
No | true = any user may interact. Fallback for [line].allow_all_users; default deny-all |
LINE_ALLOWED_USERS |
No | Comma-separated LINE user IDs. Fallback for [line].allowed_users |
Bot doesn't respond:
- Verify webhook URL is correct and shows ✅ in LINE Developers Console
- Check Use webhook is ON and Auto-reply messages is OFF
- Check gateway logs:
kubectl logs -l app=openab-gateway
Voice message doesn't transcribe:
- Confirm you sent the voice message in a 1:1 chat, not a group or room
- Confirm
[stt] enabled = truein your OpenAB config - Confirm the STT provider is configured correctly; see STT (Speech-to-Text)
- Check gateway logs for
media storedand OpenAB logs for downstream dispatch
"Invalid signature" in gateway logs:
- Verify
LINE_CHANNEL_SECRETmatches the value in LINE Developers Console - Make sure you're using the Channel secret (not the Channel access token)
Webhook verify fails:
- Ensure the gateway is reachable at the webhook URL
- Check
curl https://your-gateway-host/healthreturnsok