Open3

LINE Bot SDKの便利関数

Nakano as a ServiceNakano as a Service

特定のEventMessageにダウンキャストできるジェネリクスと型ガード関数

import type { EventMessage, MessageEvent, ReplyableEvent } from "@line/bot-sdk"

export type EventMessageOfType<T extends EventMessage> = {
  type: "message"
  message: T
} & ReplyableEvent

export function isEventMessageOfType<T extends EventMessage>(
  e: MessageEvent,
  messageType: T["type"],
): e is EventMessageOfType<T> {
  return e.message.type === messageType
}
Nakano as a ServiceNakano as a Service

テキストメッセージだけを扱う関数:

function handleTextMessage(
  e: EventMessageOfType<TextEventMessage>,
  lineUser: LineUser,
) {
  // テキストメッセージイベントを処理...
}

メッセージイベントを各ハンドラに振り分ける関数:

export async function dispatchMessageEvent(
  e: MessageEvent,
  lineUser: LineUser,
) {
  if (isEventMessageOfType<TextEventMessage>(e, "text")) {
    await handleTextMessage(e, lineUser)
  } else if (isEventMessageOfType<ImageEventMessage>(e, "image")) {
    await handleImageMessage(e)
  } else {
    console.warn(`Unsupported message event: ${e.message.type}`)
  }
}
Nakano as a ServiceNakano as a Service

シグネチャを検証するHono Middleware

import { validateSignature } from "@line/bot-sdk"
import { createMiddleware } from "hono/factory"
import { HTTPException } from "hono/http-exception"

import { env } from "~/env"

export const lineBotMiddleware = createMiddleware(async (c, next) => {
  const requestSignature = c.req.header("x-line-signature")
  if (!requestSignature) {
    throw new HTTPException(401, { message: "Signature is missing" })
  }

  const body = await c.req.text()

  if (!validateSignature(body, env.LINE_CHANNEL_SECRET, requestSignature)) {
    throw new HTTPException(401, { message: "Invalid signature" })
  }

  await next()
})
const app = new Hono()

app.use(lineBotMiddleware)