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

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

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

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

blog.kimizuka.org

blog.kimizuka.org

blog.kimizuka.org

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

ソースコード

.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/pages/api/line/send.js

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

dotenv.config();

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

export default async function handler(req, res) {
  if (req.method === 'POST') {
    try {
      const messages = [{
        type: 'text',
        text: 'Hello World.'
      }];

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

    res.status(200).json({ method: 'POST' });
  } else if (req.method === 'GET') {
    res.status(200).json({ method: 'GET' });
  }
}

src/pages/api/line/reply.js

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

dotenv.config();

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

export default async function handler(req, res) {
  if (req.method === 'POST') {
    await Promise.all((req.body.events || []).map((event) => (async () => {
      switch(event.type) {
        case 'message': {
          return client.replyMessage(event.replyToken, {
            type: 'text',
            text: 'Hello World.'
          });
        }
      }
    })()));

    res.status(200).json({ method: 'POST' });
  } else if (req.method === 'GET') {
    res.status(200).json({ method: 'GET' });
  }
}

src/pages/api/line/null-pointer-exception.js

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

dotenv.config();

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

export default async function handler(req, res) {
  if (req.method === 'POST') {
    await Promise.all((req.body.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: '...'
            });
          }
        }
      }
    })()));

    res.status(200).json({ method: 'POST' });
  } else if (req.method === 'GET') {
    res.status(200).json({ method: 'GET' });
  }
}

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

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

リポジトリ

github.com