Next.jsを活用して公式LINEからの予約ツールを作成したい、という考えの続き。
前回の記事
LINE側の準備
messaging APIの利用
- LINE開発者ツールからプロバイダー作成
- 新規チャンネル作成してMessaging APIの利用を開始
- 公式LINEを開設(この順じゃないとうまくいかなかった)
- コンソール>該当プロバイダー>該当チャンネル>messaging API設定からチャンネルアクセストークンを発行してコピーしとく
Next.js側の準備
やるべきことはAPIのためのファイルroute.ts
の準備
Next.jsでAPI機能を実装するにはappディレクトリ直下にapiディレクトリを作る必要があります。
そしてエンドポイントごとにディレクトリを作り、最終的にはroute.ts
のファイルを作ればエンドポイントを叩けるようになります。
例えばusers
へのエンドポイントを作りたければapp/api/users/route.ts
を作ればOK。
クライアント側、あるいはWebhookでのURLはドメイン/api/users
となります。
UIとなるpage.tsx
の準備
今回はLINEを利用したブロードキャストメッセージの送信だったので、Next.js側ではlinetest
ディレクトリを作ってpage.tsx
をまず作成しました。
"use client";
export default function lineTop() {
// ページ遷移させず、ボタンクリックでメッセージ送信させるためのasync関数の定義
const sendPushMessage = async () => {
try {
// apiをfetchメソッドで叩く
const response = await fetch("../api/line-test/", {
"method": "POST",
"headers": {
"Content-Type": "application/json",
},
body: JSON.stringify({ message: 'Hello LINE!' }),
})
// fetch結果に対するエラー処理
if (!response.ok) {
const errorData = await response.json();
throw new Error(errorData.error || "送信に失敗")
}
alert("LINEでメッセージを送信しました");
} catch (e: unknown) {
console.error(e);
const errorMessage = e instanceof Error ? e.message : "Unknown error occurred";
alert(`実行エラー:${errorMessage}`);
}
}
return (
<div>
<button type="button" onClick={sendPushMessage}>ブロードキャストメッセージ送信</button>
<p>※現在はトークン情報を更新しているためメッセージは送信されません</p>
</div>
)
}
このとき、はじめふと疑問に思ったことが、『どうやってエンドポイントを叩くか』ということでした。aタグ?と疑問に思ったのでメンター(ChatGPT)に聞きました。
ということで、上記のようにButtonタグでonClinc属性値を用意して完成となりました。
APIエンドポイントとなるroute.ts
を作成
続いて、エンドポイントとしてapi/line-test
とディレクトリを作成します。
import "dotenv/config";
// POSTメソッドでブロードキャストメッセージ(全体)の定義
export async function POST(request:Request) {
const req = await request.json();
console.log(req);
try {
const LINE_ACCESS_TOKEN = process.env.CHANNEL_ACCESS_TOKEN ? process.env.CHANNEL_ACCESS_TOKEN : process.env.NEXT_PUBLIC_CHANNEL_ACCESS_TOKEN;
const LINE_API_PATH = "https://api.line.me/v2/bot/message/broadcast";
const requestHeader = {
"Content-Type": "application/json",
Authorization: `Bearer ${LINE_ACCESS_TOKEN}`,
};
const requestBody = await JSON.stringify({
messages: [
// メッセージ1件目
{
type: "text",
text: "サンプルメッセージです",
},
],
});
const response = await fetch(LINE_API_PATH, {
method: "POST",
headers: requestHeader,
body: requestBody,
});
if (!response.ok) {
const errorData = await response.json();
throw new Error(`APIエラー:${errorData}`);
}
return new Response(JSON.stringify({success: true,}),{status: 200,});
} catch (e:unknown) {
const errorMessage = e instanceof Error ? e.message : "よくわからないエラー"
return new Response(
JSON.stringify(
{
success: false,
error: errorMessage,
}),
{
status: 500,
}
);
}
}
今後ローカル環境ではなく、Vercelでの公開を想定していたため、トークン情報などの環境変数については条件分岐で取得できるように書いています。
VercelでNext.jsプロジェクトを作成した場合、環境変数にアクセスするには
NEXT_PUBLIC_
の接頭辞をつける必要があるので注意です。
サイト公開(Vervel)側の準備
ローカルでもプログラムの実行はできますが、いずれアプリケーションとして公開することを念頭にして試しにデプロイしてみます。
CLIからのデプロイ
ターミナルからのデプロイをするにはnpm install vercel
ののちに、vercel
コマンドを実行すればOK。
そうすると、どのアカウントに紐づけるのか、既存のプロジェクトか新規に作るのかなど聞いてくれるので都度答えていけば大丈夫です。
Githubと連携してのデプロイ
ターミナルからの実行ではなく、ブラウザでVercelにアクセスして、Githubと連携させることで、ローカルからGithubへpushするたびにVercel側で再デプロイが実行されます。
画像右側にあるConnect Git
をクリックしてGithubアカウントと紐づけて、public repositoryを紐づければOK。数クリックで連携できます。
今後毎回vercelコマンド実行するのはめんどいなーと思ったので、git push
でそのままデプロイできるように接続してみると以下のエラーが。
Error: No Next.js version could be detected in your project. Make sure `"next"` is installed in "dependencies" or "devDependencies"
Github上のリポジトリについて、ルートディレクトリがあってその中にNext.jsプロジェクトを作っていたことが問題でした。
接続しているのはルートディレクトリなのに、Next.jsプロジェクト見つかりませんと怒られたのでした。
というわけで、Vercelに移動して当該project>setting>generalからRoot directoryをただしいものに変更すればOKです。
ここまできたら、上記で作ったButtonタグをクリックすれば公式LINEから全体に向けたメッセージ送信ができるようになりました。