みかづきブログ・カスタム

基本的にはちょちょいのほいです。

LINE Messaging APIを使ったLINE BotのWebHook用のAPIをNext.js(App Router)を使ってデプロイする 📱

前回は、LINEBot用のスクリプトを作成しましたが、その際はNgrokをつかって公開し、動作を確認しました。

blog.kimizuka.org

blog.kimizuka.org

blog.kimizuka.org

しかし、実際に永続的に運用していこうとなると、APIとしてどこかしらで動かし続けた方がよさそうです。
前回は、Next.jsのPage Routerを使って、VercelかNetlifyで公開してみましたが、今回はApp Routerを使って公開してみます。

blog.kimizuka.org

ソースコード

.env

CHANNEL_SECRET=LINEのチャネルシークレットを記載
CHANNEL_TOKEN=LINEのチャネルアクセストークンを記載

package.json

{
  "name": "line-bot",
  "version": "0.1.0",
  "private": true,
  "scripts": {
    "dev": "next dev",
    "build": "next build",
    "start": "next start",
    "lint": "next lint"
  },
  "dependencies": {
    "@line/bot-sdk": "^9.0.3",
    "next": "14.1.3",
    "react": "^18",
    "react-dom": "^18"
  },
  "devDependencies": {
    "@types/node": "^20",
    "@types/react": "^18",
    "@types/react-dom": "^18",
    "dotenv": "^16.4.5",
    "eslint": "^8",
    "eslint-config-next": "14.1.3",
    "typescript": "^5"
  }
}

src/app/api/line/send/route.js

// 定型文の送信
import * as dotenv from 'dotenv';
import { Client } from '@line/bot-sdk';
import { NextResponse } from 'next/server';

dotenv.config();

const { CHANNEL_SECRET, CHANNEL_TOKEN } = process.env;
const config = {
  channelSecret: CHANNEL_SECRET,
  channelAccessToken: CHANNEL_TOKEN
};
const client = new Client(config);

export function GET() {
  return NextResponse.json({
    method: 'GET'
  });
}

export async function POST() {
  try {
    const messages = [{
      type: 'text',
      text: 'Hello World.'
    }];

    await client.broadcast(messages);
  } catch (err) {
    console.log(err);
  }

  return NextResponse.json({
    method: 'POST'
  });
}

src/app/api/line/reply/route.js

// 定型文の返信
import * as dotenv from 'dotenv';
import { Client } from '@line/bot-sdk';
import { NextResponse } from 'next/server';

dotenv.config();

const { CHANNEL_SECRET, CHANNEL_TOKEN } = process.env;
const config = {
  channelSecret: CHANNEL_SECRET,
  channelAccessToken: CHANNEL_TOKEN
};
const client = new Client(config);

export function GET() {
  return NextResponse.json({ method: 'GET' });
}

export async function POST(request) {
  const req = await request.json();

  await Promise.all((req.events || []).map((event) => (async () => {
    switch(event.type) {
      case 'message': {
        return client.replyMessage(event.replyToken, {
          type: 'text',
          text: 'Hello World.'
        });
      }
    }
  })()));

  return NextResponse.json({ method: 'POST' });
}

src/app/api/line/null-pointer-exception/route.js

// メッセージに応じたテキストの返信
import * as dotenv from 'dotenv';
import { Client } from '@line/bot-sdk';
import { NextResponse } from 'next/server';

dotenv.config();

const { CHANNEL_SECRET, CHANNEL_TOKEN } = process.env;
const config = {
  channelSecret: CHANNEL_SECRET,
  channelAccessToken: CHANNEL_TOKEN
};
const client = new Client(config);

export function GET() {
  return NextResponse.json({ method: 'GET' });
}

export async function POST(request) {
  const req = await request.json();

  await Promise.all((req.events || []).map((event) => (async () => {
    switch(event.type) {
      case 'message': {
        if (/^ぬるぽ$/.test(event.message.text)) {
          return client.replyMessage(event.replyToken, {
            type: 'text',
            text: 'ガッ'
          });
        } else {
          return client.replyMessage(event.replyToken, {
            type: 'text',
            text: '...'
          });
        }
      }
    }
  })()));

  return NextResponse.json({ method: 'POST' });
}

定型文の送信定型文の返信メッセージに応じたテキストの返信の3パターンを、send.js、reply.js、null-pointer-exception.jsとしています。

これを、VercelやNetlifyにデプロイすればURLが発行されるので、LINE Developers にログインし、チャンネルの「Messaging API設定 > Webhook設定 > Webhook URL」から、WebHookのURLに設定すればOKです。

リポジトリ

github.com