Agent skill

LINE Webhooks Skill

Receive and verify LINE Messaging API webhooks. Use when setting up LINE bot webhook handlers, debugging LINE x-line-signature verification (HMAC-SHA256, base64, channel secret), answering the LINE Developers Console "Verify" request, or handling LINE events like message, follow, unfollow, postback, join, memberJoined, unsend, and accountLink.

Install this skill

npx skills add hookdeck/webhook-skills --skill line-webhooks


When to Use This Skill

  • How do I receive LINE Messaging API webhooks for my LINE bot?
  • How do I verify the LINE x-line-signature header?
  • Why does my LINE webhook signature verification fail?
  • Why does the Verify button in the LINE Developers Console fail for my webhook URL?
  • How do I handle LINE message, follow, postback or memberJoined events?
  • How do I dedupe redelivered LINE webhooks?

Verification (core)

LINE signs the raw request body with HMAC-SHA256 keyed on your channel secret (Console → channel → Basic settings) and sends the base64 digest in x-line-signature. There's no timestamp and no prefix. Verify the exact bytes received; parsing and re-serializing the JSON breaks the signature.

Node (@line/bot-sdk):

const { validateSignature } = require('@line/bot-sdk');

function verifyLineSignature(rawBody, signature, channelSecret) {
  if (!signature || !channelSecret) return false;
  try {
    return validateSignature(rawBody, channelSecret, signature); // timing-safe
  } catch {
    return false;
  }
}

Python (line-bot-sdk):

from linebot.v3 import SignatureValidator

def verify_line_signature(raw_body: bytes, signature: str, channel_secret: str) -> bool:
    if not signature or not channel_secret:
        return False
    # Equivalent to: base64(hmac.new(secret, raw_body, sha256).digest()) == signature
    return SignatureValidator(channel_secret).validate(raw_body.decode("utf-8"), signature)

No SDK? The manual version is in references/verification.md.

For complete handlers with tests, see examples/express/, examples/nextjs/, examples/fastapi/.

The console Verify button sends a signed {"destination":"U...","events":[]}. Verify it like any other request and return 200; an empty events array is valid.

Common Event Types

One webhook request carries an events array; dispatch on each event's type:

Event typeTriggered When
messageUser sends a message (message.type: text, image, video, audio, file, location, sticker)
messageEditedUser edits a text message (group chats)
unsendUser unsends a message
followUser adds the account as a friend, or unblocks it
unfollowUser blocks the account
join / leaveAccount joins / leaves a group or multi-person chat
memberJoined / memberLeftA user joins / leaves a group the account is in
postbackUser triggers a postback action (postback.data)
videoPlayCompleteUser finishes a tracked video message
beaconUser enters a LINE Beacon's range
accountLinkUser links their LINE account to your service
membershipUser joins, leaves or renews a membership

For full event reference, see Webhook event objects and references/overview.md.

Important Headers and Fields

Header / fieldDescription
x-line-signaturebase64 HMAC-SHA256 of the raw body, keyed on the channel secret
destinationBot user ID the events are for (pick the channel secret per bot if you run several)
events[].webhookEventIdUnique event ID (ULID). Use it to dedupe.
events[].deliveryContext.isRedeliverytrue when LINE is redelivering a failed webhook
events[].replyTokenToken for the reply message endpoint

Environment Variables

LINE_CHANNEL_SECRET=your_channel_secret   # Console → channel → Basic settings → Channel secret

Local Development

# Start tunnel (no account needed)
npx hookdeck-cli listen 3000 line --path /webhooks/line

Paste the URL into Messaging API → Webhook URL, click Verify, and enable Use webhook.

Reference Materials


Repository

hookdeck/webhook-skills

v0.1.0 · MIT · Updated Oct 28, 2026

View on GitHub →