Next.jsでLINE Messaging APIを使う

こんにちは、今回はNext.jsでLINE Messaging APIを使う方法を書いていきます。

## ■使用技術
・TypeScript
・Next.js(v12.2.0)
・API：axios
・LINE Messaging API(@line/bot-sdk v7.5.2)

## ■LINE Messaging APIとは？
イベントをトリガーにして、LINEにメッセージを送ってくれるAPI。
一方的に送る事も出来るし、こちらからのLINEメッセージに対して返却も可能。

## ■LINE側の設定
下記からアカウント登録を進めていきます。

https://developers.line.biz/ja/services/messaging-api/

アカウント登録が完了したらとボットの作成を進めていきます。
新規チャネル作成
| 項目名                     | 選択肢                                 | 
| -------------------------- | -------------------------------------- | 
| チャネルの種類             | Messaging API                          | 
| プロバイダー               | 個人開発                               | 
| 会社・事業者の所在国・地域 | 日本                                   | 
| チャネルアイコン           | LINE botアカウントのアイコン | 
| チャネル名                 | LINE botアカウントの名前               | 
| チャネル説明               | LINE botアカウントの説明文             | 
| 大業種                     | 個人                                   | 
| 小業種                     | 該当がなければ：個人(その他)           | 
| メールアドレス             | 自分のメールアドレス                   | 
| プライバシーポリシーURL    | 一旦空でOK                             | 
| サービス利用規約URL        | 一旦空でOK                             | 

同意して進むと、botアカウントが作成されます。

## ■Next.js側の設定
### 1.必要なモジュールのインストール
Next.jsで作成したプロジェクトに対して、@line/bot-sdkをインストールします。

```plaintext
npm i @line/bot-sdk
または
yarn add @line/bot-sdk
```

### 2.Next.jsのapi-routesでAPIを作成

```react:pages/api/linebot.ts
import { NextApiRequest, NextApiResponse } from "next";
import * as line from "@line/bot-sdk";

const config = {
  channelAccessToken: チャネルアクセストークン,
  channelSecret: チャネルシークレット,
};

const client = new line.Client(config);

export default async function handler(
  req: NextApiRequest,
  res: NextApiResponse
) {
  try {
    const message = req.body.message;

    await client.pushMessage(送りたいトークルームのユーザーIDかグループID, {
      type: "text",
      text: message,
    });

    res.status(200).json({ message: `${message}というメッセージが送信されました。` });
  } catch (e) {
    res.status(500).json({ message: `error! ${e} ` });
  }
}
```

細かく見ていきます。

①ここでLINEのAPIにアクセスする認証を行なっています。
各キーは下記から取得可能です。

Messaging API設定 > チャネルアクセストークン(発行を押下して出てきたキー)
チャネル基本設定 > チャネルシークレット
```react
const config = {
  channelAccessToken: チャネルアクセストークン,
  channelSecret: チャネルシークレット,
};

const client = new line.Client(config);
```

②このNext.jsのAPIはPOSTメソッドとして作りたいと思います。
messageをkeyにして、valueに送りたいメッセージを入れてAPIを叩くとLINEにそのメッセージが飛びます。
```react
const message = req.body.message;
```

```react:APIを叩く時    
await axios.post("/api/linebot", {
   message: "送りたいメッセージ",
});
```

③LINEのメソッドを使って、メッセージを登録します。
使えるメソッドは、下記に表示されているもののみとなっています。
※もし今回使用している`pushMessage`が書いていなければ、記載されているメソッドを使って下さい。
LINE Developers > Messaging API設定タブ > 利用できるAPI
![スクリーンショット 2023-02-28 12.24.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2365717/fed8b377-dd74-ddd5-756d-ab300ba100d0.png)

今回は、一方的に送りたいだけなので`pushMessage`を使いたいと思います。
メソッドについてのドキュメントはこちら

https://line.github.io/line-bot-sdk-nodejs/api-reference/client.html#methods:~:text=Message-,%23,-pushMessage(to%3A%20string


送りたいトークルームのユーザーIDかグループIDを入れるとそのトークルームにメッセージが送信されます。

・自身のユーザーID
→ LINE Developers > チャネル基本設定 > あなたのユーザーID

・他人のユーザーID,グループID
→ IDを検出するために、別でメソッドを作る必要があります。
非常に面倒ですが「GAS LINE groupID」などで調べるとGASを使って簡単に取得する方法がワンサカ出てきますので、そちらをご参照ください。GASでメソッドを書いて、IDを知りたいグループにbotを参加させるとIDが取得出来ます。

※awaitを忘れずに！

```react
await client.pushMessage(送りたいトークルームのユーザーIDかグループID, {
   type: "text",
   text: message,
});
```
これで、APIの準備は完了です。
あとはLINEを送信したいタイミングで作成したNext.js上のAPIを叩けばOKです。
```react:APIを叩く時(例)    
const onClickMethod = async() =>{
console.log("ボタンが押されました！")

//LINEで、ボタンが押されたことを通知する
await axios.post("/api/linebot", {
   message: "ボタンが押されました！",
});
}
```

ちなみに私は、家計簿で金額を登録したらその内容をLINEに投稿する仕組みを作りました。
\nを入れれば、文章の改行も可能です。

## ■まとめ
今回は、Next.jsでLINE Messaging APIを使う方法をまとめました。GASやNode.jsを使った方法はかなり出てきたのですが、Next.jsとの連携は少なかったのでこちらが役に立てば幸いです。

お読み頂きありがとうございました。


## ■参考資料

https://developers.line.biz/ja/docs/messaging-api/overview/

https://developers.line.biz/ja/docs/messaging-api/nodejs-sample/

https://qiita.com/fe_js_engineer/items/ac205d28909b387ef655