Connecting an AI Agent to a LINE Bot, Method and Mistakes

I tried connecting Hermes Agent to a LINE bot after Telegram and Discord. It was much harder โ€” webhook-only, signature verification, and proxy issues.
Markdown sourceยทAnything to add or correct?

After Telegram and Discord, I tried connecting LINE too. Short version: much harder than Telegram or Discord. Telegram uses polling so the server just asks, but LINE is webhook-only with signature verification, so "it won't connect" problems mostly come from proxy and signature issues. Here is what I actually broke and how I fixed it. (measured on the operator's environment)

1. Creating a channel in LINE Developers Console

  1. Go to LINE Developers Console
  2. Select a provider โ†’ Create a channel โ†’ choose Messaging API (not LINE Login)
  3. Provider โ†’ Channel โ†’ Messaging API tab

Trap 1: The channel must be Messaging API type

If you create a LINE Login channel, no bot token is generated. I initially created one with LINE Login and wandered through channel settings for nothing. Only a Messaging API channel issues Channel secret and Channel access token.

2. Getting tokens

From Basic settings you get two values:


Channel secret: a1b2c3d4e5f6...
Channel access token (long-lived): eyJhbGciOi...

Trap 2: Short-lived tokens die after a few days

The initially issued short-lived token worked for days, then the bot went silent one morning. Logs showed 401 โ€” the token had expired. Replaced with the long-lived token. For 24-hour operation, you must use the long-lived token.

3. Webhook registration

Set the Webhook URL in Messaging API settings and click Verify.


https://my-domain.example.com/webhook/line

Trap 3: LINE webhooks only accept public HTTPS

Entering a local address (http://localhost:8000) makes the Verify button fail entirely. LINE servers must reach your server from outside, and localhost is unreachable. I used a tunnel like ngrok for development testing.

Trap 4: If the proxy does not forward X-Forwarded-For, requests are blocked

Behind a reverse proxy (Nginx, Caddy), requests appear to come from the proxy address (127.0.0.1). LINE only sends POSTs to allowlisted IPs, so if that address is what gets seen, every request is silently ignored. I fixed this by configuring the proxy to forward headers:


location /webhook/line {
    proxy_pass http://127.0.0.1:8000;
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;
}

4. Signature verification

This is the most important part of LINE integration. LINE requests carry an HMAC-SHA256 signature in the X-Line-Signature header.

Trap 5: Verifying with parsed JSON always fails

You must verify against the original raw bytes. JSON parsing changes key order, whitespace, and encoding.


import base64, hashlib, hmac

def verify(raw_body: bytes, signature: str, secret: str) -> bool:
    expected = base64.b64encode(
        hmac.new(secret.encode(), raw_body, hashlib.sha256).digest()
    ).decode()
    return hmac.compare_digest(expected, signature)

Trap 6: Return 400 on verification failure

If you return 200 on failure, nobody knows there is a problem. I saved the first request body to a file and compared byte-by-byte with the test body from the LINE console to find the issue.

5. Agent execution


hermes gateway start

Trap 7: In group chats, you must mention the bot

LINE does not read group messages unless the bot is mentioned (@BotName). The advantage is that channel chatter never becomes LLM cost. The disadvantage is that without a mention, nothing happens.

6. Comparison across three platforms

TelegramDiscordLINE
Bot creationBotFatherDeveloper PortalMessaging API channel
Connectionpolling (easy)websocketwebhook only (hard)
HTTPS needednonoyes (public cert)
Signature verificationnonenoneHMAC-SHA256
Token lifetimepermanentpermanentshort-lived expires
Group responsemention not neededprefix neededmention required
Difficultyeasymediumhard

Summary

  1. Create a Messaging API channel (LINE Login won't issue tokens)
  2. Get the long-lived access token (short-lived dies after days)
  3. Get a public HTTPS domain before registering the webhook
  4. Forward X-Forwarded-For in your reverse proxy
  5. Verify signatures against raw bytes (re-serializing JSON always fails)
  6. Return 400 on verification failure, register users with U-prefixed IDs

Honestly, for a personal assistant, Telegram is far easier. LINE only makes sense when the domain is fixed and the use case is domestic service integration. I lost half a day on this, but I left the record so others don't have to.