※この記事はZennにも投稿しています。
https://zenn.dev/articles/64d292edcb34a9/edit
はじめに
昨日の記事「【個人開発】GoogleのAI「Antigravity」とペアプロしたら、日程調整ツールが爆速で完成した話」では、AIエージェントとペアプログラミングをして、日程調整まとめアプリ「ScheduLinx(スケジュリンクス)」のプロトタイプを爆速で開発しました。
今回はその続編です。
「プロトタイプ完成」からわずか一晩で、**「Googleカレンダーと連携して、予定の仮押さえから確定までを完結できるツール」**へと進化させました。
この記事では、NextAuth.jsを使ったGoogle Calendar API連携の技術的なポイントや、個人開発アプリを「使われるプロダクト」にするためのUX/SEO改善について解説します。
1. 作ったもの:ScheduLinx (v1.0)
ScheduLinxは、複数の日程調整ツール(伝助、調整さんなど)のURLを登録するだけで、候補日を自動で取り込み、自分のGoogleカレンダーと重ねて表示できるアプリです。
URL: https://schedule-manager-beta.vercel.app
GitHub: https://github.com/NaokiKenmochi/schedule-manager
今回実装した新機能
-
Googleカレンダー双方向同期:
- 候補日を取り込むと、Googleカレンダーに「[仮]」として予定を作成。
- アプリで「確定」すると、Googleカレンダーの予定を正式登録し、他の候補日を自動削除。
-
UXの磨き込み:
- OGP画像の作成、Favicon設定、使い方ガイドの実装。
2. 技術ハイライト:Googleカレンダー連携の裏側
今回の最大の山場は、**「アプリでの操作をGoogleカレンダーにリアルタイムで反映させる」**ことでした。
認証スコープの昇格 (NextAuth.js)
これまでは読み取り専用(calendar.readonly)でしたが、予定の作成・削除を行うため、書き込み権限(calendar)を追加しました。
GoogleProvider({
clientId: process.env.GOOGLE_CLIENT_ID!,
clientSecret: process.env.GOOGLE_CLIENT_SECRET!,
authorization: {
params: {
// calendar.readonly から calendar へ変更
scope: "openid email profile https://www.googleapis.com/auth/calendar",
},
},
}),
「仮押さえ」と「確定」のロジック
日程調整で一番面倒なのは、**「候補日をカレンダーに仮登録する作業」と、「決まった後に不要な仮予定を消す作業」**です。これを全自動化しました。
Step 1: 候補日の取り込み(仮押さえ)
調整ツールのURLを解析して候補日を抽出したら、即座にGoogleカレンダーへPOSTします。この時、タイトルに [仮] を付けて区別します。
Step 2: 確定アクション(お掃除機能)
ユーザーが候補日の一つを「確定」した時の処理がこちらです。
const handleConfirmEvent = async (event: CalendarEvent) => {
if (!window.confirm(`「${event.title}」を確定しますか?`)) return;
// Googleカレンダー連携済みの場合
if (session?.accessToken && event.googleEventId) {
try {
// 1. 確定した予定を更新([仮] を削除)
const newTitle = event.title.replace(/^\[仮\]\s*/, '');
await fetch('/api/calendar/events', {
method: 'PATCH',
body: JSON.stringify({
eventId: event.googleEventId,
title: newTitle,
}),
});
// 2. 同じグループの「選ばれなかった候補日」を全削除
const otherEvents = events.filter(e => e.groupId === event.groupId && e.id !== event.id);
await Promise.all(otherEvents.map(async (other) => {
if (other.googleEventId) {
await fetch(`/api/calendar/events?eventId=${other.googleEventId}`, {
method: 'DELETE',
});
}
}));
} catch (error) {
console.error('Failed to sync confirmation', error);
}
}
// ...ローカルの状態更新
};
この「選ばれなかった候補日を消す」処理があるだけで、カレンダーがスッキリし、ダブルブッキングのリスクが激減します。
3. プロダクトとしての「磨き込み」
機能ができたら、次は「使いたくなる見た目」と「見つけてもらう工夫」です。ここでもAIエージェントが大活躍しました。
OGP画像の作成
SNSでシェアされた時の顔となるOGP画像。デザインセンスに自信がなくても、AIにイメージを伝えるだけで生成してくれます。
プロンプト:
A modern, sleek, and professional Open Graph (OGP) image for a schedule management application named 'ScheduLinx'. The design should be clean and minimalist...
これを layout.tsx の metadata に設定するだけで、X (Twitter) での表示が劇的に良くなりました。
使い方ガイド (Help Modal)
機能が増えてきたので、初見ユーザー向けのガイドも実装しました。
「ヘッダーの?ボタンを押すとモーダルが出る」という仕様も、AIに依頼してサクッと実装。
SEO最適化
Next.js の Metadata API をフル活用して、JSON-LD(構造化データ)も埋め込みました。これで「日程調整ツール」として検索エンジンに正しく認識されるはずです。
const jsonLd = {
"@context": "https://schema.org",
"@type": "SoftwareApplication",
"name": "ScheduLinx",
"applicationCategory": "ProductivityApplication",
// ...
};
4. まとめ
AIエージェントとのペアプログラミングにより、**「アイデア出し」→「プロトタイプ」→「実用的なプロダクト」**への進化を、驚くべきスピードで実現できました。
特に、Googleカレンダー連携のような少し複雑なAPI処理も、
「こういうロジックにしたい」
と伝えるだけで、エラーハンドリングまで含めたコードを提案してくれるのは圧巻です。
ScheduLinxは現在ベータ版として公開中です。ぜひ使ってみてください!
- App: https://schedule-manager-beta.vercel.app
- GitHub: https://github.com/NaokiKenmochi/schedule-manager
フィードバックやPull Requestもお待ちしています!


