Business Overview

🎯

サービス概要

お金のパーソナルトレーニング「b-Fine」の無料体験セッション集客LP。ファイナンシャルコンサルティングの体験予約をオンラインで完結させる

📅

予約システム

Google Calendar連携のリアルタイム空き枠表示。2ステップ予約フロー(日時選択 + 個人情報入力)でコンバージョンを最適化

📊

マルチLPパターン

4種のLPバリアント(v1, v1-2, v2, article-v1)を広告媒体・広告種別ごとに出し分け。A/Bテスト基盤として機能

💬

LINE連携

LIFF(LINE Front-end Framework)でLP上のCTAからLINE友だち追加へ誘導。予約データをLステップに連携し自動フォロー

System Architecture

Contentful CMS
LPメタデータ管理(パターン・媒体・CTA)
Google Calendar
空き枠管理・イベント作成
Delivery API / Calendar API
Next.js 16
App Router / Cloud Run (port 8080)
POST /api/reserve
Google Sheets
予約データ永続化
Gmail API
確認メール送信
Slack Webhook
チーム通知

LP Pattern Variants

広告チャネルやターゲットに応じて4種のLPパターンを使い分ける。Contentfulでパターン・媒体・広告種別を管理し、動的にルーティングする。

パターン 特徴 予約機能 URL例
v1 シンプル画像LP。CTAはLINE直リンク なし(LINE誘導のみ) /lp/v1/google/search
v1-2 フルLP + 2ステップ予約(モーダルカレンダー) カレンダー + フォーム /lp/v1-2/facebook/conversion
v2 LP本体にカレンダー埋め込み インラインカレンダー + フォーム /lp/v2/google/search
article-v1 記事型LP。読み物形式でカレンダー埋め込み インラインカレンダー + フォーム /lp/article-v1/meta/reel
💡
ルーティング規則

URLは /lp/{pattern}/{media}/{adType} 形式。レガシー(2パート)URLの場合はContentfulからパターンを解決する。予約サブページは /reserve/reserve/info

User Flow (v1-2 Pattern)

1
LP閲覧
広告流入
2
CTA押下
予約へ遷移
3
日時選択
カレンダーUI
4
情報入力
Zodバリデーション
5
予約完了
確認メール + Slack通知
6
LINE誘導
LIFF + Lステップ

Calendar System

📅

空き枠取得

Google Calendar APIから予定を取得し、予約済みスロットを算出。GET /api/calendar/booked-slots で提供

タイムスロット

9:00〜22:00の1時間枠(13スロット/日)。最大2週間先まで表示。当日は残り1.5時間未満のスロットを無効化

🔒

ダブルブッキング防止

カレンダーイベントと1時間スロットの重複を判定。イベントが1分でも重なるスロットは予約不可として表示

API Endpoints

Method Path 説明 副作用
POST /api/reserve 予約送信。フォームデータ + 日時 + UTMパラメータ Sheets書込 + Slack通知 + Calendar作成 + メール送信
GET /api/calendar/booked-slots 予約済みスロット取得。startDate/endDate指定 なし(読み取り専用)
🛠
エラー耐性

予約APIはGoogle Sheets書き込みが必須(失敗時は500)。メール送信・カレンダー作成の失敗は警告ログに留め、予約自体は成功として扱う。

External Integrations

📚

Contentful CMS

LPメタデータ(パターン、媒体、広告種別、CTAリンク、noIndexフラグ)を管理。本番はDelivery API、ステージングはPreview API

環境切替: BFINE_ENV
📈

Google Sheets

予約データの永続化。サービスアカウント認証で書き込み。本番環境のみ有効

JWT認証 / 本番のみ書込
📅

Google Calendar

コンサルタントの空き枠管理。予約時にイベント自動作成。本番/ステージングでカレンダーID分離

サービスアカウント / 環境別CalendarID
📧

Gmail API

予約確認メールをDomain-Wide Delegationで送信。Zoom案内・キャンセルポリシーを含むHTML/テキストメール

ドメイン全体の委任
🔔

Slack Webhook

新規予約のリアルタイム通知。本番は担当者メンション付き、ステージングはメンションなし

Block Kit / 環境別Webhook
💬

LINE LIFF + Lステップ

LP上のCTAからLINE友だち追加。予約完了ページで予約データをLステップ変数にマッピングし、自動フォローアップを実行

LIFF ID: 2008521966-EPNOgBWz

Reservation Data Model

フィールド バリデーション 説明
name string 全角日本語、スペース不可 氏名
email string メール形式 メールアドレス
phone string 10〜11桁、ハイフンなし 電話番号
gender enum male / female / no_answer 性別
birthYear string 1950〜2006 生年
hasSpouse enum yes / no 配偶者有無
date string yyyy-MM-dd 予約日
startTime / endTime string HH:mm 予約時間枠
params string 任意 UTMパラメータ(トラッキング用)
referrer string 任意 流入元LP URL

Tech Stack

技術 用途 備考
Next.js 16 フロントエンド / API Routes App Router、React 19、React Compiler有効
React 19 UIフレームワーク Suspense、Server Components
TypeScript 型安全 API Routes、lib層で使用(コンポーネントはJS)
Zod バリデーション 予約フォームのスキーマ定義・検証
React Hook Form フォーム管理 @hookform/resolvers でZod連携
Tailwind CSS スタイリング PostCSS経由、ユーティリティファースト
Contentful SDK CMS連携 Delivery API / Preview API 切替
googleapis Google連携 Calendar, Sheets, Gmail API
date-fns 日付処理 カレンダーUI、タイムスロット計算
Biome Linter / Formatter ESLint + Prettier の統合代替

Deployment

📦

Docker

マルチステージビルド(deps → builder → runner)。Node.js 20 Alpine。standalone出力で軽量イメージ生成

Cloud Run

GitHub Actions連動。staging/main ブランチで自動デプロイ。Secret ManagerでAPI鍵を注入

🔒

環境分離

BFINE_ENV で production / staging / dev を切替。Contentful API、Calendar ID、Slack Webhook、Sheets書込をそれぞれ分離

GTM

Google Tag Manager(GTM-WNKRKDVK)を @next/third-parties で統合。広告コンバージョン・アクセス解析のトラッキングに使用。

Environment Variables

カテゴリ 変数名 説明
Contentful CONTENTFUL_SPACE_ID スペースID
CONTENTFUL_ACCESS_TOKEN Delivery APIトークン
CONTENTFUL_PREVIEW_ACCESS_TOKEN Preview APIトークン
Sheets GOOGLE_SPREADSHEET_ID スプレッドシートID
GOOGLE_SHEET_NAME シート名
GOOGLE_SERVICE_ACCOUNT_KEY_JSON サービスアカウント鍵(JSON文字列)
Calendar GOOGLE_CALENDAR_SERVICE_ACCOUNT_KEY_JSON Calendar用サービスアカウント鍵
GOOGLE_CALENDAR_ID 本番カレンダーID
GOOGLE_CALENDAR_ID_STAGING ステージングカレンダーID
Email EMAIL_SENDER_KEY_JSON Gmail用サービスアカウント鍵
EMAIL_DELEGATE_ADDRESS Domain-Wide Delegation対象メール
EMAIL_SENDER_ADDRESS 送信元メールアドレス
EMAIL_SENDER_NAME 送信者名(デフォルト: b-Fine)
Slack SLACK_WEBHOOK_URL 本番通知用Webhook URL
App BFINE_ENV 環境(production / staging / dev)