@nakanoaas/hono-linebot-middleware
v0.0.5
Published
Hono middleware for LINE Bot webhook signature validation built on Web Standards
Maintainers
Readme
@nakanoaas/hono-linebot-middleware
Hono middleware for LINE Bot webhook signature validation built on Web Standards
A lightweight, zero-dependency middleware for validating LINE Bot webhook signatures in Hono applications. Built entirely on Web Standards APIs, it works seamlessly across Cloudflare Workers, Node.js, Deno, Bun, and any runtime that supports Web Crypto API.
✨ Features
- 🔒 Secure by Default - Validates webhook signatures using HMAC-SHA256
- 🌐 Web Standards - Built on Web Crypto API, no runtime dependencies
- 🚀 Universal Runtime Support - Works on Cloudflare Workers, Node.js, Deno, Bun, and more
- 📦 Zero Dependencies - Lightweight and fast
- 💪 TypeScript First - Full type definitions included
- 🎯 Simple API - One function, zero configuration
📦 Installation
via npm
npm install @nakanoaas/hono-linebot-middlewarepnpm add @nakanoaas/hono-linebot-middlewareyarn add @nakanoaas/hono-linebot-middlewarevia JSR (Deno)
deno add jsr:@nakanoaas/hono-linebot-middlewareOr use directly in your code:
import { lineBotMiddleware } from "jsr:@nakanoaas/hono-linebot-middleware";🚀 Quick Start
import { Hono } from "hono";
import type { WebhookRequestBody } from "@line/bot-sdk";
import { lineBotMiddleware } from "@nakanoaas/hono-linebot-middleware";
const app = new Hono();
const channelSecret = /* LINE Channel Secret */;
app.post("/webhook", lineBotMiddleware(channelSecret), async (c) => {
const events = await c.req.json<WebhookRequestBody>();
// Handle LINE webhook events
return c.body(null, 204);
});That's it! The middleware automatically validates incoming webhook requests and rejects invalid signatures with a 401 Unauthorized response.
💡 Examples
Cloudflare Workers
import { env } from "cloudflare:workers";
import type { WebhookRequestBody } from "@line/bot-sdk";
import { lineBotMiddleware } from "@nakanoaas/hono-linebot-middleware";
import { Hono } from "hono";
const app = new Hono();
app.post("/webhook", lineBotMiddleware(env.LINE_CHANNEL_SECRET!), async (c) => {
const events = await c.req.json<WebhookRequestBody>();
// Handle LINE webhook events
return c.body(null, 204);
});
export default app;Node.js
import { Hono } from "hono";
import { serve } from "@hono/node-server";
import type { WebhookRequestBody } from "@line/bot-sdk";
import { lineBotMiddleware } from "@nakanoaas/hono-linebot-middleware";
const app = new Hono();
app.post("/webhook", lineBotMiddleware(process.env.LINE_CHANNEL_SECRET!), async (c) => {
const events = await c.req.json<WebhookRequestBody>();
// Handle LINE webhook events
return c.body(null, 204);
});
serve(app);Deno
import { Hono } from "https://deno.land/x/hono/mod.ts";
import type { WebhookRequestBody } from "@line/bot-sdk";
import { lineBotMiddleware } from "@nakanoaas/hono-linebot-middleware";
const app = new Hono();
app.post("/webhook", lineBotMiddleware(Deno.env.get("LINE_CHANNEL_SECRET")!), async (c) => {
const events = await c.req.json<WebhookRequestBody>();
// Handle LINE webhook events
return c.body(null, 204);
});
Deno.serve(app.fetch);Bun
import { Hono } from "hono";
import type { WebhookRequestBody } from "@line/bot-sdk";
import { lineBotMiddleware } from "@nakanoaas/hono-linebot-middleware";
const app = new Hono();
app.post("/webhook", lineBotMiddleware(Bun.env.LINE_CHANNEL_SECRET!), async (c) => {
const events = await c.req.json<WebhookRequestBody>();
// Handle LINE webhook events
return c.body(null, 204);
});
export default {
port: 3000,
fetch: app.fetch,
};📚 Documentation
API
lineBotMiddleware(channelSecret: string): MiddlewareHandler
Creates a Hono middleware that validates LINE Bot webhook signatures.
Parameters:
channelSecret(string): Your LINE Bot channel secret
Returns:
MiddlewareHandler: A Hono middleware handler
Behavior:
- Validates the
x-line-signatureheader using HMAC-SHA256 - Throws
HTTPExceptionwith status401if:- The signature header is missing
- The signature validation fails
- Calls
next()if validation succeeds
Throws:
Error: IfchannelSecretis not a stringHTTPException(401): If the signature header is missing or validation fails
importKeyFromChannelSecret(channelSecret: string): Promise<CryptoKey>
Imports a cryptographic key from a LINE Bot channel secret for HMAC-SHA256 signature verification.
Parameters:
channelSecret(string): The LINE Bot channel secret string
Returns:
Promise<CryptoKey>: A Promise that resolves to a CryptoKey configured for HMAC-SHA256 verification
Example:
import { importKeyFromChannelSecret } from "@nakanoaas/hono-linebot-middleware";
const key = await importKeyFromChannelSecret("your-channel-secret");validateSignature(body: BufferSource, key: CryptoKey, signature: string): Promise<boolean>
Validates a LINE Bot webhook signature using HMAC-SHA256.
Parameters:
body(BufferSource): The request body as a BufferSource (ArrayBuffer, TypedArray, or DataView)key(CryptoKey): The CryptoKey imported from the channel secretsignature(string): The Base64-encoded signature from thex-line-signatureheader
Returns:
Promise<boolean>: A Promise that resolves totrueif the signature is valid,falseotherwise
Example:
import { importKeyFromChannelSecret, validateSignature } from "@nakanoaas/hono-linebot-middleware";
const body = await request.arrayBuffer();
const key = await importKeyFromChannelSecret(channelSecret);
const isValid = await validateSignature(body, key, signature);🔧 Technical Details
- Signature Algorithm: HMAC-SHA256
- Signature Header:
x-line-signature(Base64 encoded) - Web Crypto API: Uses
crypto.subtle.verify()for signature validation - Hono Version: Requires Hono ^4.0.0
🛠️ Development
Prerequisites
Setup
mise trust
mise installBuild
pnpm buildTest
pnpm testType Check
pnpm check-typesLint & Format
pnpm check
pnpm check:fix📄 License
Apache-2.0 © Nakano as a Service
🔗 Related Projects
- Hono - Web framework built on Web Standards
- @line/bot-sdk - LINE Messaging API SDK for nodejs
