OmochiXを検索

Esc で閉じる

問い合わせフォーム・LINE 連携付きの企業サイトを作る

5 ページの企業サイトに問い合わせフォームを付け、送信をメールと LINE 公式アカウントへ通知する。トークンはコードに書かない。

中級 約180分 最終検証 Claude Code Cursor
プレビュー(サンドボックス内で動作。送信などは模擬です)

この教材で作るもの

トップ・サービス・会社情報・お問い合わせ・プライバシーポリシーの 5 ページ。問い合わせフォームを送ると、管理者のメールと LINE 公式アカウントに 1 通ずつ通知が届く。Vercel で公開済み。

動作確認環境: Node.js 20 / Next.js 15(App Router) / Vercel(2026年10月時点の無料枠) / LINE Messaging API(push message) / Resend(メール送信)

前提条件

  • GitHub アカウント
  • Vercel アカウント(無料枠でよい)
  • LINE Developers のプロバイダーと Messaging API チャネル(無料)
  • Resend のアカウント(無料枠でよい。別のメール送信サービスでも可)
  • Node.js 20 以上と、Claude Code か Cursor

実装手順

  1. 作りたいものを 1 文で決める

    「誰のための、何をしてもらうサイトか」を 1 文にします。例:小さなデザイン事務所が、見積もりの問い合わせをもらうためのサイト。

    確認: 1 文で言えたら次へ

  2. AI に情報設計を出してもらう

    1 文をプロンプトに入れて、5 ページの見出し構成とフォーム項目を出してもらいます。分からない点は推測させず、質問として返してもらいます。

    AI に渡すプロンプト要件を 1 文から情報設計にするclaude-code
    あなたは Web 制作者です。次の 1 文から、企業サイトの情報設計を提案してください。
    
    作りたいもの: <ここに 1 文。例: 小さなデザイン事務所の、問い合わせをもらうためのサイト>
    
    出力:
    - 5 ページ(トップ / サービス / 会社情報 / お問い合わせ / プライバシーポリシー)それぞれの目的と見出し構成
    - トップに載せる要素の優先順位
    - 問い合わせフォームの項目(必須 / 任意)
    - まだ決まっていないことの質問リスト(推測で埋めない)

    確認: 5 ページの見出しとフォーム項目が決まった

  3. プロジェクトを作って GitHub に置く

    npx create-next-app@latest でプロジェクトを作り、最初のコミットを GitHub に置きます。手順は AI で 0 から Web サービスを公開する の STEP 4〜15 と同じです。

    確認: GitHub にリポジトリができた

  4. 静的サイトの骨子を作る

    5 ページと共通ヘッダー・フッターを作ってもらいます。文章はあとで差し替えるので、まずは構造と見た目だけを整えます。

    AI に渡すプロンプト静的サイトの骨子を作るclaude-code
    Next.js(App Router)で 5 ページの静的な企業サイトを作ってください。
    
    条件:
    - ページ: / , /services , /company , /contact , /privacy
    - 共通ヘッダー(ロゴ・ナビ)と共通フッター(会社名・プライバシーポリシーへのリンク)
    - CSS はフレームワークを使わず、CSS Modules か素の CSS。色は --primary: #6e4bff を基調に
    - 画像はプレースホルダーでよい(alt は必ず付ける)
    - スマートフォン幅(375px)で崩れないこと
    - 各ページの title と description を設定すること
    
    作ったら、起動コマンドと確認手順を最後に書いてください。

    確認: 5 ページが表示され、375px で崩れない

  5. 問い合わせフォームと API ルートを作る

    フォームと受け口の API を作ります。この段階では通知を送らず、受け付けた内容をサーバーのログに出すだけにして、検証とレート制限が効くことを先に確かめます。

    AI に渡すプロンプト問い合わせフォームと API ルートclaude-code
    /contact に問い合わせフォームを作り、送信先として API ルート app/api/contact/route.ts を作ってください。
    
    フォーム:
    - 項目: お名前(必須)、メールアドレス(必須・形式チェック)、お問い合わせ内容(必須・最大 2000 文字)
    - ハニーポット用の非表示項目(入力があれば受け付けない)
    - 送信中はボタンを無効化し、成功 / 失敗をテキストで表示(aria-live="polite")
    
    API:
    - POST のみ。JSON を受け取り、サーバー側でも同じ検証を行う
    - 同じ IP から 1 分に 3 回を超えたら 429 を返す(メモリ上の簡易制限でよい)
    - 成功したら { ok: true } を返す。通知の送信は次のステップで実装するので、いまは console.log で内容を出すだけにする
    - 秘密情報は一切ハードコードしない
    コード例app/api/contact/rate-limit.ts
    const hits = new Map<string, number[]>();
    
    export function tooMany(ip: string, limit = 3, windowMs = 60_000) {
      const now = Date.now();
      const recent = (hits.get(ip) ?? []).filter((t) => now - t < windowMs);
      recent.push(now);
      hits.set(ip, recent);
      return recent.length > limit;
    }

    確認: 空送信が拒否され、連打すると 429 になる

  6. LINE Developers でチャネルを用意する

    LINE Developers コンソールでプロバイダーと Messaging API チャネルを作り、チャネルアクセストークン(長期)を発行します。通知先は自分のユーザー ID(チャネル基本設定の「あなたのユーザー ID」)です。公式アカウントを友だち追加しておきます。

    トークンは .env に書きます。.env.example にはキー名とプレースホルダーだけを書きます。

    コード例.env.example
    # 実際の値は .env(git には入れない)と Vercel の環境変数にだけ置く
    RESEND_API_KEY=<ここに貼る:Resend の API キー>
    CONTACT_TO=<ここに貼る:通知を受け取るメールアドレス>
    CONTACT_FROM=<ここに貼る:Resend で認証した差出人>
    LINE_CHANNEL_ACCESS_TOKEN=<ここに貼る:LINE Developers のチャネルアクセストークン>
    LINE_TO=<ここに貼る:通知先の LINE ユーザー ID>

    確認: .env にトークンがあり、.env.example には実際の値が無い

  7. メールと LINE に通知する

    API ルートに通知処理を足します。環境変数が無いときは落ちずにスキップし、片方が失敗してももう片方は送るようにします。

    AI に渡すプロンプトメールと LINE への通知claude-code
    app/api/contact/route.ts に、受け付けた問い合わせを 2 か所へ通知する処理を追加してください。
    
    1. メール: Resend の SDK で管理者宛に送る。API キーは環境変数 RESEND_API_KEY、宛先は CONTACT_TO、差出人は CONTACT_FROM
    2. LINE: Messaging API の push message で、環境変数 LINE_CHANNEL_ACCESS_TOKEN と LINE_TO(通知先のユーザー ID)を使って送る。本文は「お名前 / メール / 内容の先頭 200 文字」
    
    条件:
    - 環境変数は process.env から読み、未設定のときは 500 ではなく「設定が足りません」とログに出して { ok: false } を返す
    - トークンや宛先をコードや .env.example に実際の値で書かない。.env.example にはキー名とプレースホルダー(<ここに貼る:…>)だけを書く
    - 片方の送信が失敗しても、もう片方は送る
    - 個人情報をログに残さない(名前・メール・本文をそのまま console.log しない)
    コード例app/api/contact/line.ts
    export async function notifyLine(text: string) {
      const token = process.env.LINE_CHANNEL_ACCESS_TOKEN;
      const to = process.env.LINE_TO;
      if (!token || !to) {
        console.warn('LINE notification skipped: environment is not configured');
        return false;
      }
      const res = await fetch('https://api.line.me/v2/bot/message/push', {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
          Authorization: `Bearer ${token}`,
        },
        body: JSON.stringify({ to, messages: [{ type: 'text', text: text.slice(0, 1000) }] }),
      });
      return res.ok;
    }

    確認: テスト送信でメールと LINE に 1 通ずつ届く

  8. プライバシーポリシーに通知先を書く

    問い合わせ内容を「メールと LINE で運営者に通知し、サーバーには保存しない」ことをプライバシーポリシーに明記します。文面は運営者が確認してから公開します。

    確認: 通知先と保存しない旨が書かれている

  9. 公開前チェックを AI に出してもらう

    秘密情報の混入、検証、レート制限、表示崩れを表で確認します。問題があればその場で直します。

    AI に渡すプロンプト公開前のセルフチェックclaude-code
    このプロジェクトを公開する前に、次を確認して結果を表にしてください。
    
    - .env が .gitignore に入っていて、git ls-files .env が空
    - .env.example に実際の値が入っていない
    - API ルートで入力を検証している(必須・長さ・メール形式・ハニーポット・レート制限)
    - 問い合わせ内容を永続化していない(通知だけ)
    - プライバシーポリシーに「問い合わせ内容をメールと LINE で運営者に通知する」ことが書いてある
    - 375px で全ページが崩れない
    - 各ページに title と description がある
    
    問題があれば、修正案も一緒に出してください。

    確認: 表のすべてが OK

  10. Vercel に公開する

    Vercel でリポジトリを取り込み、環境変数(5 つ)を Vercel 側に登録してからデプロイします。公開 URL でフォームを 1 回送信し、通知が届くことを確かめます。

    確認: 公開 URL からの送信でメールと LINE に届く

テスト・検証

チェックはこのブラウザにだけ保存されます。

検証項目
済項目やり方期待結果
公開 URL からテスト送信する メールと LINE 公式アカウントに 1 通ずつ届き、本文に名前・メール・内容の先頭が含まれる
必須項目を空にして送る。メール欄に abc と入れて送る 送信されず、エラー文が表示される(画面と API の両方で拒否)
1 分以内に 4 回送る 4 回目は 429 になり、通知は 3 通まで
開発者ツールで非表示項目に文字を入れて送る 受け付けられず、通知も届かない
git ls-files .env を実行し、.env.example を開く 何も表示されず、.env.example はプレースホルダーだけ
ローカルで .env を外して送信する 500 にならず、ログに「設定が足りません」と出る
Vercel のログを見る 名前・メール・本文がそのまま出ていない
端末エミュレーションで 5 ページを見る 横スクロールが出ず、フォームが押せる

安全性・秘密情報

  • チャネルアクセストークンとメール API キーは .env と Vercel の環境変数にだけ置く。コード・コミット・このページには書かない
  • .env を .gitignore に入れ、公開前に git ls-files .env が空であることを確認する
  • LINE API はブラウザから直接叩かず、必ずサーバー(API ルート)から送る
  • 入力はサーバー側でも検証し、ハニーポットとレート制限で迷惑送信を減らす
  • 問い合わせ内容はサーバーに保存せず通知だけにし、プライバシーポリシーに通知先を書く
  • ログに個人情報(名前・メール・本文)をそのまま出さない

「<ここに貼る:…>」の形で書かれた値は、環境変数など公開されない場所に置きます。コード・リポジトリ・このページには入れません。

公開手順

  1. Vercel で GitHub リポジトリを取り込む
  2. Vercel の Environment Variables に .env.example の 5 項目を登録する(Production)
  3. デプロイ後、公開 URL から 1 回テスト送信して通知を確認する
  4. 独自ドメインを設定し、HTTPS になっていることを確認する
  5. Search Console にサイトを登録する

よくあるエラー

送信しても LINE に届かない

原因: LINE_TO が自分のユーザー ID ではない、または公式アカウントを友だち追加していない。トークンの期限切れや Vercel に環境変数を登録していないことも多い

対処: LINE Developers の「あなたのユーザー ID」を LINE_TO に入れ、公式アカウントを友だち追加する。Vercel の環境変数を確認して再デプロイする

メールは届くのに LINE だけ失敗する(401)

原因: チャネルアクセストークンが間違っている、または別チャネルのもの

対処: LINE Developers で長期トークンを再発行し、.env と Vercel の両方を更新する

ローカルでは届くのに公開後は届かない

原因: .env は git に入れていないので、Vercel 側に環境変数が無い

対処: Vercel の Environment Variables に 5 項目を登録して再デプロイする

正しい入力でも 429 になる

原因: レート制限の窓(1 分 3 回)にテスト送信が引っかかっている

対処: 1 分待つか、開発中だけ上限を上げる。本番の値は戻す

GitHub にトークンを push してしまった

原因: .env をコミットした、またはコードに直書きした

対処: すぐに LINE Developers と Resend でトークンを無効化・再発行し、履歴から削除する。再発行しない限り漏れたトークンは使われ続ける

AIへの実装指示書

この教材の手順・プロンプト・検証・安全性を 1 枚にまとめた Markdown です。コピーして Claude Code や Codex に渡します。

# 実装指示: 問い合わせフォーム・LINE 連携付きの企業サイトを作る
このファイルの指示に従って実装してください。分からない点は実装前に質問してください。

## 概要
- 教材: https://omochix.com/learn/practice/corporate-site-contact-line/
- 難易度: 中級 / 所要 約180分
- 対応AI: Claude Code / Cursor
- 使用技術: LINE Messaging API / Next.js / TypeScript / Vercel
- 最終検証日: 2026-10-21

## 作るもの
トップ・サービス・会社情報・お問い合わせ・プライバシーポリシーの 5 ページ。問い合わせフォームを送ると、管理者のメールと LINE 公式アカウントに 1 通ずつ通知が届く。Vercel で公開済み。

## 前提条件
- GitHub アカウント
- Vercel アカウント(無料枠でよい)
- LINE Developers のプロバイダーと Messaging API チャネル(無料)
- Resend のアカウント(無料枠でよい。別のメール送信サービスでも可)
- Node.js 20 以上と、Claude Code か Cursor

## 動作確認環境
- Node.js 20
- Next.js 15(App Router)
- Vercel(2026年10月時点の無料枠)
- LINE Messaging API(push message)
- Resend(メール送信)

## 実装手順

### STEP 1: 作りたいものを 1 文で決める
「誰のための、何をしてもらうサイトか」を 1 文にします。例:小さなデザイン事務所が、見積もりの問い合わせをもらうためのサイト。

- 確認: 1 文で言えたら次へ

### STEP 2: AI に情報設計を出してもらう
1 文をプロンプトに入れて、5 ページの見出し構成とフォーム項目を出してもらいます。分からない点は推測させず、質問として返してもらいます。

AI に渡すプロンプト(要件を 1 文から情報設計にする):
```text
あなたは Web 制作者です。次の 1 文から、企業サイトの情報設計を提案してください。

作りたいもの: <ここに 1 文。例: 小さなデザイン事務所の、問い合わせをもらうためのサイト>

出力:
- 5 ページ(トップ / サービス / 会社情報 / お問い合わせ / プライバシーポリシー)それぞれの目的と見出し構成
- トップに載せる要素の優先順位
- 問い合わせフォームの項目(必須 / 任意)
- まだ決まっていないことの質問リスト(推測で埋めない)
```

- 確認: 5 ページの見出しとフォーム項目が決まった

### STEP 3: プロジェクトを作って GitHub に置く
npx create-next-app@latest でプロジェクトを作り、最初のコミットを GitHub に置きます。手順は AI で 0 から Web サービスを公開する の STEP 4〜15 と同じです。

- 確認: GitHub にリポジトリができた

### STEP 4: 静的サイトの骨子を作る
5 ページと共通ヘッダー・フッターを作ってもらいます。文章はあとで差し替えるので、まずは構造と見た目だけを整えます。

AI に渡すプロンプト(静的サイトの骨子を作る):
```text
Next.js(App Router)で 5 ページの静的な企業サイトを作ってください。

条件:
- ページ: / , /services , /company , /contact , /privacy
- 共通ヘッダー(ロゴ・ナビ)と共通フッター(会社名・プライバシーポリシーへのリンク)
- CSS はフレームワークを使わず、CSS Modules か素の CSS。色は --primary: #6e4bff を基調に
- 画像はプレースホルダーでよい(alt は必ず付ける)
- スマートフォン幅(375px)で崩れないこと
- 各ページの title と description を設定すること

作ったら、起動コマンドと確認手順を最後に書いてください。
```

- 確認: 5 ページが表示され、375px で崩れない

### STEP 5: 問い合わせフォームと API ルートを作る
フォームと受け口の API を作ります。この段階では通知を送らず、受け付けた内容をサーバーのログに出すだけにして、検証とレート制限が効くことを先に確かめます。

AI に渡すプロンプト(問い合わせフォームと API ルート):
```text
/contact に問い合わせフォームを作り、送信先として API ルート app/api/contact/route.ts を作ってください。

フォーム:
- 項目: お名前(必須)、メールアドレス(必須・形式チェック)、お問い合わせ内容(必須・最大 2000 文字)
- ハニーポット用の非表示項目(入力があれば受け付けない)
- 送信中はボタンを無効化し、成功 / 失敗をテキストで表示(aria-live="polite")

API:
- POST のみ。JSON を受け取り、サーバー側でも同じ検証を行う
- 同じ IP から 1 分に 3 回を超えたら 429 を返す(メモリ上の簡易制限でよい)
- 成功したら { ok: true } を返す。通知の送信は次のステップで実装するので、いまは console.log で内容を出すだけにする
- 秘密情報は一切ハードコードしない
```

コード例(app/api/contact/rate-limit.ts):
```typescript
const hits = new Map<string, number[]>();

export function tooMany(ip: string, limit = 3, windowMs = 60_000) {
  const now = Date.now();
  const recent = (hits.get(ip) ?? []).filter((t) => now - t < windowMs);
  recent.push(now);
  hits.set(ip, recent);
  return recent.length > limit;
}
```

- 確認: 空送信が拒否され、連打すると 429 になる

### STEP 6: LINE Developers でチャネルを用意する
LINE Developers コンソールでプロバイダーと Messaging API チャネルを作り、チャネルアクセストークン(長期)を発行します。通知先は自分のユーザー ID(チャネル基本設定の「あなたのユーザー ID」)です。公式アカウントを友だち追加しておきます。
トークンは .env に書きます。.env.example にはキー名とプレースホルダーだけを書きます。

コード例(.env.example):
```bash
# 実際の値は .env(git には入れない)と Vercel の環境変数にだけ置く
RESEND_API_KEY=<ここに貼る:Resend の API キー>
CONTACT_TO=<ここに貼る:通知を受け取るメールアドレス>
CONTACT_FROM=<ここに貼る:Resend で認証した差出人>
LINE_CHANNEL_ACCESS_TOKEN=<ここに貼る:LINE Developers のチャネルアクセストークン>
LINE_TO=<ここに貼る:通知先の LINE ユーザー ID>
```

- 確認: .env にトークンがあり、.env.example には実際の値が無い

### STEP 7: メールと LINE に通知する
API ルートに通知処理を足します。環境変数が無いときは落ちずにスキップし、片方が失敗してももう片方は送るようにします。

AI に渡すプロンプト(メールと LINE への通知):
```text
app/api/contact/route.ts に、受け付けた問い合わせを 2 か所へ通知する処理を追加してください。

1. メール: Resend の SDK で管理者宛に送る。API キーは環境変数 RESEND_API_KEY、宛先は CONTACT_TO、差出人は CONTACT_FROM
2. LINE: Messaging API の push message で、環境変数 LINE_CHANNEL_ACCESS_TOKEN と LINE_TO(通知先のユーザー ID)を使って送る。本文は「お名前 / メール / 内容の先頭 200 文字」

条件:
- 環境変数は process.env から読み、未設定のときは 500 ではなく「設定が足りません」とログに出して { ok: false } を返す
- トークンや宛先をコードや .env.example に実際の値で書かない。.env.example にはキー名とプレースホルダー(<ここに貼る:…>)だけを書く
- 片方の送信が失敗しても、もう片方は送る
- 個人情報をログに残さない(名前・メール・本文をそのまま console.log しない)
```

コード例(app/api/contact/line.ts):
```typescript
export async function notifyLine(text: string) {
  const token = process.env.LINE_CHANNEL_ACCESS_TOKEN;
  const to = process.env.LINE_TO;
  if (!token || !to) {
    console.warn('LINE notification skipped: environment is not configured');
    return false;
  }
  const res = await fetch('https://api.line.me/v2/bot/message/push', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      Authorization: `Bearer ${token}`,
    },
    body: JSON.stringify({ to, messages: [{ type: 'text', text: text.slice(0, 1000) }] }),
  });
  return res.ok;
}
```

- 確認: テスト送信でメールと LINE に 1 通ずつ届く

### STEP 8: プライバシーポリシーに通知先を書く
問い合わせ内容を「メールと LINE で運営者に通知し、サーバーには保存しない」ことをプライバシーポリシーに明記します。文面は運営者が確認してから公開します。

- 確認: 通知先と保存しない旨が書かれている

### STEP 9: 公開前チェックを AI に出してもらう
秘密情報の混入、検証、レート制限、表示崩れを表で確認します。問題があればその場で直します。

AI に渡すプロンプト(公開前のセルフチェック):
```text
このプロジェクトを公開する前に、次を確認して結果を表にしてください。

- .env が .gitignore に入っていて、git ls-files .env が空
- .env.example に実際の値が入っていない
- API ルートで入力を検証している(必須・長さ・メール形式・ハニーポット・レート制限)
- 問い合わせ内容を永続化していない(通知だけ)
- プライバシーポリシーに「問い合わせ内容をメールと LINE で運営者に通知する」ことが書いてある
- 375px で全ページが崩れない
- 各ページに title と description がある

問題があれば、修正案も一緒に出してください。
```

- 確認: 表のすべてが OK

### STEP 10: Vercel に公開する
Vercel でリポジトリを取り込み、環境変数(5 つ)を Vercel 側に登録してからデプロイします。公開 URL でフォームを 1 回送信し、通知が届くことを確かめます。

- 確認: 公開 URL からの送信でメールと LINE に届く

## 検証
- フォーム送信で通知が届く — やり方: 公開 URL からテスト送信する / 期待結果: メールと LINE 公式アカウントに 1 通ずつ届き、本文に名前・メール・内容の先頭が含まれる
- 空送信・不正なメールが拒否される — やり方: 必須項目を空にして送る。メール欄に abc と入れて送る / 期待結果: 送信されず、エラー文が表示される(画面と API の両方で拒否)
- 連打がブロックされる — やり方: 1 分以内に 4 回送る / 期待結果: 4 回目は 429 になり、通知は 3 通まで
- ハニーポットが効く — やり方: 開発者ツールで非表示項目に文字を入れて送る / 期待結果: 受け付けられず、通知も届かない
- 秘密情報が git に入っていない — やり方: git ls-files .env を実行し、.env.example を開く / 期待結果: 何も表示されず、.env.example はプレースホルダーだけ
- 環境変数なしで落ちない — やり方: ローカルで .env を外して送信する / 期待結果: 500 にならず、ログに「設定が足りません」と出る
- 個人情報がログに出ない — やり方: Vercel のログを見る / 期待結果: 名前・メール・本文がそのまま出ていない
- 375px で崩れない — やり方: 端末エミュレーションで 5 ページを見る / 期待結果: 横スクロールが出ず、フォームが押せる

## 安全性・秘密情報
- チャネルアクセストークンとメール API キーは .env と Vercel の環境変数にだけ置く。コード・コミット・このページには書かない
- .env を .gitignore に入れ、公開前に git ls-files .env が空であることを確認する
- LINE API はブラウザから直接叩かず、必ずサーバー(API ルート)から送る
- 入力はサーバー側でも検証し、ハニーポットとレート制限で迷惑送信を減らす
- 問い合わせ内容はサーバーに保存せず通知だけにし、プライバシーポリシーに通知先を書く
- ログに個人情報(名前・メール・本文)をそのまま出さない
- 「<ここに貼る:…>」の形のプレースホルダーは、環境変数など公開されない場所に実際の値を置き、コードやリポジトリに書かない

## 公開手順
- Vercel で GitHub リポジトリを取り込む
- Vercel の Environment Variables に .env.example の 5 項目を登録する(Production)
- デプロイ後、公開 URL から 1 回テスト送信して通知を確認する
- 独自ドメインを設定し、HTTPS になっていることを確認する
- Search Console にサイトを登録する

## よくあるエラー
- 送信しても LINE に届かない — 原因: LINE_TO が自分のユーザー ID ではない、または公式アカウントを友だち追加していない。トークンの期限切れや Vercel に環境変数を登録していないことも多い / 対処: LINE Developers の「あなたのユーザー ID」を LINE_TO に入れ、公式アカウントを友だち追加する。Vercel の環境変数を確認して再デプロイする
- メールは届くのに LINE だけ失敗する(401) — 原因: チャネルアクセストークンが間違っている、または別チャネルのもの / 対処: LINE Developers で長期トークンを再発行し、.env と Vercel の両方を更新する
- ローカルでは届くのに公開後は届かない — 原因: .env は git に入れていないので、Vercel 側に環境変数が無い / 対処: Vercel の Environment Variables に 5 項目を登録して再デプロイする
- 正しい入力でも 429 になる — 原因: レート制限の窓(1 分 3 回)にテスト送信が引っかかっている / 対処: 1 分待つか、開発中だけ上限を上げる。本番の値は戻す
- GitHub にトークンを push してしまった — 原因: .env をコミットした、またはコードに直書きした / 対処: すぐに LINE Developers と Resend でトークンを無効化・再発行し、履歴から削除する。再発行しない限り漏れたトークンは使われ続ける

## 参照した公式仕様
- LINE Messaging API リファレンス(プッシュメッセージ) https://developers.line.biz/ja/reference/messaging-api/#send-push-message
- Next.js Route Handlers https://nextjs.org/docs/app/building-your-application/routing/route-handlers
- Vercel Environment Variables https://vercel.com/docs/projects/environment-variables
- Resend Node.js SDK https://resend.com/docs/send-with-nodejs

## 受け入れ条件
- 上の検証項目がすべて期待結果どおりになる
- 秘密情報がコード・設定ファイル・公開ページに含まれていない
- スマートフォン幅でも表示が崩れず、キーボードだけで操作できる

参照した公式仕様

更新履歴

2026.10.21
初版
指示書 検証