24日目にLINEミニアプリが完成する初心者 ── Day11. プッシュメッセージの送信


# はじめに

前回は「24 日目に LINE ミニアプリが完成する初心者 ── Day10. Messaging API」と題して、LINE 公式アカウントの作成と Messaging API の設定を行いました。

https://qiita.com/non_watanabe/items/ef7179dd94a67696b0fa

<br/>
今回は、Messaging APIを使用して資料請求完了の際にLINEにプッシュメッセージを送信する機能を実装していきます。

# チャネルアクセストークンを発行

はじめに Messaging API で使用するチャネルアクセストークンの発行を行っていきます。

トークンには以下の種類があります。

- **任意の有効期間を指定できるチャネルアクセストークン**
- **ステートレスチャネルアクセストークン**
- **短期のチャネルアクセストークン**
- **長期のチャネルアクセストークン**

## 長期のチャネルアクセストークンの発行

今回は初めなので、簡単に発行できる長期のチャネルアクセストークンを発行していきます。

LINE Developers から Messaging API のチャネルを開いていきます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2743174/e1589e75-7ee0-3c78-bbf1-1e9d7ec38c7e.png)

<br/>
上のタブから「Messaging API設定」をクリックします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2743174/69cc27f1-ae78-5873-a225-d095d25887c1.png)

<br/>
ページの一番下にあるチャネルアクセストークンの「発行」をクリックします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2743174/e650a959-69eb-dd60-22a4-8595b024cafe.png)

<br/>
トークンが表示されれば発行は完了です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2743174/7b6b06e0-953f-fc9c-97db-1f6c8eb8b5b3.png)

# プッシュメッセージの実装

プッシュメッセージの実装は以下の情報を元に行っていきたいと思います。

https://developers.line.biz/ja/reference/messaging-api/#send-push-message

## 環境変数の設定

先ほど発行したトークンを環境変数として設定していきます。

`.env.local`には以下の通り設定します。

```
NEXT_PUBLIC_LINE_ACCESS_TOKEN="your_long_term_access_token"
```

Netlify 側でも環境変数の設定を行っておきましょう。

`line-liff-v2-starter`配下のターミナルで以下のコマンドを入力します。

```terminal
$ netlify env:set NEXT_PUBLIC_LINE_ACCESS_TOKEN "your_long_term_access_token"
```

## API の実装

環境変数の設定が完了したら API を作成します。

`pages/api`配下に新しく`message.ts`というファイルを作成しましょう。

```ts: src/nextjs/pages/api/message.ts
import type { NextApiRequest, NextApiResponse } from "next";

export default async function handler(
  req: NextApiRequest,
  res: NextApiResponse
) {
  const { method, body } = req;
  if (method === "POST") {
    try {
      const url = "https://api.line.me/v2/bot/message/push";

      const response = await fetch(url, {
        method: "POST",
        headers: {
          "Content-Type": "application/json",
          Authorization: `Bearer ${process.env.NEXT_PUBLIC_LINE_ACCESS_TOKEN}`,
        },
        body,
      });

      const result = await response.json();
      res.status(200).json(result);
    } catch (err) {
      res.status(500).json({ error: "Internal Server Error" });
    }
  } else {
    res.setHeader("Allow", ["POST"]);
    res.status(405).end(`Method ${req.method} Not Allowed`);
  }
}
```

`Authorization`として先ほど発行したアクセストークンを設定しています。

## ユーザ ID の取得

プッシュメッセージの設定にはユーザ ID が必要になります。

完了画面を閉じる時にも利用した LIFF SDK を使ってユーザ ID を取得を行っていきましょう。

`CatalogPage.tsx`に以下の内容を追記していきます。

```tsx:src/nextjs/components/pages/catalog/CatalogPage.tsx
import { useEffect, useState } from "react";
import liff from "@line/liff";

// （中略）

type MessageProps = {
  to: string;
  messages: { type: "text"; text: string }[];
};

async function sendData<T>(url: string, { arg }: { arg: T }) {
  await fetch(url, {
    method: "POST",
    body: JSON.stringify(arg),
  });
}

export default function CatalogPage({
  setIsComplete,
}: {
  setIsComplete: (isComplete: boolean) => void;
}) {
  const [userId, setUserId] = useState(null);

  useEffect(() => {
    if (liff) {
      liff.ready.then(() => {
        liff
          .getProfile()
          .then((profile) => {
            setUserId(profile.userId);
          })
          .catch((error) => {
            console.error("Failed to get profile:", error);
          });
      });
    }
  }, [liff]);

  // （中略）
}
```

今回取得したユーザ ID は useState へ格納しています。

## 送信処理

プッシュメッセージの送信は「送信する」ボタンが押され、スプレッドシートへの出力が完了してから行います。

`onSubmit`を以下の通り更新していきます。

```tsx:src/nextjs/components/pages/catalog/CatalogPage.tsx
  const { trigger: catalogTrigger, isMutating } = useSWRMutation(
    "/api/catalog",
    sendData<CatalogPageProps>
  );
  const { trigger: messageTrigger } = useSWRMutation(
    "/api/message",
    sendData<MessageProps>
  );

  const onSubmit: SubmitHandler<CatalogPageProps> = (data) => {
    console.log(data);
    catalogTrigger(data, {
      onSuccess: () => {
        setIsComplete(true);
        messageTrigger({
          to: userId,
          messages: [
            {
              type: "text",
              text: "カタログをご請求いただきありがとうございます！カタログのご到着までしばしお待ち下さい。なにかご不明点があれば、お気軽にお問い合わせください！",
            },
          ],
        });
      },
    });
  };
```

以上でプッシュメッセージの実装は完了です。

# デプロイ

ここまでの内容が確認できたら LINE 画面で確認するため、デプロイを行いましょう。

`line-liff-v2-starter`配下のターミナルで以下のコマンドを入力します。

```terminal
$ netlify deploy --build --prod
```

# 動作確認

ご自身の LINE から再度資料請求を行ってみましょう。

送信完了画面が出た後、前回作成した公式アカウントからメッセージが届けば完了です！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2743174/ef334fb3-1a13-944b-4630-ce50c1a87ca4.png)

# まとめ

今回は、Messaging API を使用して資料請求完了時にプッシュメッセージを送信する機能を実装しました。

次回からは新機能として、問い合わせを実装していきたいと思います。

残りは 13 日！
気になる方は是非フォローやカレンダー購読をお願いします:star: