Auth model
Installed plugin + LINE Messaging API credentials + webhook endpoint
A plugin lane for teams targeting LINE without flattening everything into webhook boilerplate.
LINE Messaging API setup for OpenClaw: plugin installation, webhook wiring, channel credentials, verification drills, and rollout notes for supported regions.
Auth model
Installed plugin + LINE Messaging API credentials + webhook endpoint
Safety stance
Respect webhook integrity and account boundaries before adding richer templates or menu actions.
Verification ritual
Validate webhook delivery, bot reply behavior, and one richer message surface after the first text round-trip.
Rollout mode
25–40 min setup
Messaging API webhook
The LINE plugin supports DMs, groups, media, locations, Flex messages, template messages, and quick replies, while reactions and threads remain out of scope.
Watch the webhook
Webhook misrouting and template limits can masquerade as generic delivery bugs.
LINE is a webhook-first OpenClaw lane. The trust boundary is not just the bot token: it is the combination of plugin installation, HTTPS webhook reachability, signature verification with the raw request body, and OpenClaw DM / group policy.
LINE is documented upstream as a plugin channel built on the LINE Messaging API.
That gives it a different operational feel from Telegram or Feishu:
channelSecret,So if the webhook layer is unstable, the rest of the experience is unstable too.
The local official docs describe LINE as supported via plugin with these capabilities:
The same docs also state the two important limits clearly:
That should shape expectations early, especially if your team is comparing LINE to workspace-style chat tools.
Do not bury these facts below the fold:
openclaw plugins install @openclaw/linechannelSecretThat means “LINE can hit my endpoint” and “OpenClaw should answer this sender” are separate questions.
The docs require:
If that layer is wrong, OpenClaw never gets a meaningful inbound event.
Once LINE events arrive, OpenClaw still evaluates:
dmPolicyallowFromgroupPolicygroupAllowFromgroups.<groupId>.allowFromSo a webhook can be perfectly healthy while the bot remains silent on purpose.
The official minimal config is already conservative where it matters most: DMs default to pairing.
For a practical first rollout, keep the lane narrow:
pairing,{
channels: {
line: {
enabled: true,
channelAccessToken: 'LINE_CHANNEL_ACCESS_TOKEN',
channelSecret: 'LINE_CHANNEL_SECRET',
dmPolicy: 'pairing',
groupPolicy: 'allowlist',
},
},
}
Why this is a sensible first shape:
The local docs also support file-backed secrets:
{
channels: {
line: {
tokenFile: '/path/to/line-token.txt',
secretFile: '/path/to/line-secret.txt',
},
},
}
That is often a better operational posture than copying long-lived secrets into ad hoc shell state.
The official order is straightforward and worth following literally:
The default documented path is:
https://gateway-host/line/webhook
If you customize the path, the docs require that channels.line.webhookPath or channels.line.accounts.<id>.webhookPath match the URL you entered in LINE.
The docs support multiple LINE accounts, but most operators should prove one account first.
Minimal config is enough to get started:
{
channels: {
line: {
enabled: true,
channelAccessToken: 'LINE_CHANNEL_ACCESS_TOKEN',
channelSecret: 'LINE_CHANNEL_SECRET',
dmPolicy: 'pairing',
},
},
}
Environment variables also exist for the default account:
LINE_CHANNEL_ACCESS_TOKENLINE_CHANNEL_SECRETUse envs if you need them, but long-term operators usually reason more clearly from config or secret files.
The official docs expose the usual OpenClaw trust knobs, but LINE adds one subtle operational detail: IDs are case-sensitive.
The same local docs say valid IDs look like:
U + 32 hex charactersC + 32 hex charactersR + 32 hex charactersThat matters because a policy mistake can look like a webhook bug when the real issue is a mismatched identifier.
Recommended starting point:
dmPolicy: 'pairing'Approve new senders with:
openclaw pairing list line
openclaw pairing approve line <CODE>
The local docs support:
channels.line.groupPolicychannels.line.groupAllowFromchannels.line.groups.<groupId>.allowFromA practical first rollout is still to keep shared spaces tight until you have one known-good DM and one known-good group round-trip.
The docs explicitly warn that if channels.line is completely missing, runtime falls back to groupPolicy="allowlist" for group checks even if channels.defaults.groupPolicy is set.
That is not a reason to overcomplicate config. It is a reason to make the channel block explicit when you are debugging group silence.
LINE supports richer presentation features, but the official docs are careful about how message behavior works:
5000 characters,channels.line.mediaMaxMb with a default of 10.That should change how you verify the lane.
First prove:
Only then is it worth validating richer payloads.
The official docs support LINE-specific channelData.line for:
There is also a built-in /card command for Flex presets.
That is a useful capability surface, but do not mistake it for baseline health. If the webhook path, secret, or policy is wrong, no amount of Flex payload tuning will save the lane.
Before testing conversational behavior, confirm the webhook URL is correct, HTTPS, and bound to the expected path.
The local docs say the gateway handles both:
GETPOSTIf verification is failing, stop there and fix that first.
Once webhook verification is healthy:
openclaw pairing list line
openclaw pairing approve line <CODE>
If pairing as a concept is fuzzy, use:
After DMs work, add one group or room and verify:
After plain text is stable, test one richer surface only:
That catches payload-shape mistakes without expanding the blast radius too early.
Do one deliberate gateway restart and repeat the DM plus shared-surface test.
Webhook-based lanes feel healthy only when they survive a simple lifecycle event.
The local docs give the first checks directly:
channelSecret matches the LINE console.Because signature verification depends on the raw body, do not assume reverse-proxy or middleware changes are neutral until you have re-tested.
The docs point to two likely causes first:
channels.line.webhookPath,Those are better first hypotheses than blaming the model or the prompt.
The local docs are specific here too: raise channels.line.mediaMaxMb if the media exceeds the default limit.
That is a real configuration problem, not a generic webhook failure.
Because LINE DMs default to pairing and groups may be allowlisted, a healthy webhook can still produce no reply.
Always separate delivery succeeded from policy allowed a response.
LINE is a good fit when:
It is a weaker first lane when you want a setup that avoids public ingress entirely.
Verification & references
References