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]
command = "kiro-cli"
args = ["acp", "--trust-all-tools"]
working_dir = "/home/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.
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 |
LINE_CHANNEL_ACCESS_TOKEN |
Yes | Channel access token for Reply/Push Message API and LINE-hosted image/audio downloads |
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