Flutter Claude API Google Calendar 自分用メモ

超ズボラ日記アプリ 開発計画メモ

· SEADICE  ·  明日の開発用メモ

明日すぐ開発に入れるように全部まとめておく。認証まわりで迷わないようにするのが目的。

アプリのコンセプト

「開いたら日記が書けてる」アプリです。アプリを開くだけでClaudeが今日の日記を自動生成し、広告を見て投稿するだけでGoogle Calendarに記録されます。入力ゼロでも日記が完成します。

「開いたら日記が書けてる」 — 日記が続かない人のための最強ズボラ日記アプリ。

最大のポイント: アプリを開くだけでいい。入力ゼロでも日記が完成する。


技術スタック

Flutter + Claude API(Haiku)+ Google Calendar API + AdMobで構成します。サーバー不要で1回の日記生成コストは約0.3〜1円です。

役割使うものコスト
UIフレームワークFlutter(iOS/Android)無料
日記の自動生成Claude API(Haiku)1回約0.3〜1円
データ保存Google Calendar API無料
認証Google Sign-In無料
収益化AdMob(動画リワード広告)収益になる側

サーバー不要。Claude APIとAdMobだけで回る。


アプリ起動時のフロー

起動時にGoogle Calendarから過去30件を取得し、未投稿日の日記をClaude APIで自動生成します。ユーザーは一言追加して広告を見るだけで投稿完了です。

1
アプリを開く
Google Sign-Inのトークンを確認。未ログインなら認証画面へ。
2
Google Calendarから過去の日記を取得
専用カレンダー「超ズボラ日記」の直近30件のイベントを取得。
3
未投稿の日付を検出
今日・昨日分のイベントがなければ「未投稿」として扱う。
4
Claude APIで日記を自動生成
曜日・天気・前回の日記の文体から今日の日記を生成。
5
ユーザーに表示
生成された日記を見せる。一言追加したければ入力欄に書ける。
6
広告を見て「投稿」
リワード広告(15〜30秒)を視聴完了 → Google Calendarにイベントとして保存。

Google認証まわり(ここが一番複雑)

Google Cloud ConsoleでCalendar APIを有効化し、OAuth 2.0クライアントIDをiOS・Android別に発行します。Calendarへの書き込みはセンシティブスコープのため、ストア公開前にOAuth審査(数週間)が必要です。

必要なもの

必要なスコープ(権限)

スコープ用途審査レベル
calendar.readonly過去の日記を読み込むセンシティブ
calendar.events日記をイベントとして書き込むセンシティブ

注意: Calendar への書き込みは「センシティブなスコープ」扱い。ストア公開前にGoogleのOAuth審査(verification)が必要。審査には数週間かかる。開発中・テスト中は自分のGoogleアカウントだけで動かせる(テストユーザーとして登録)。

Google Cloud Console の手順

Step 1
プロジェクト作成

console.cloud.google.com → 新しいプロジェクト → 名前は「zuboro-diary」など

Step 2
Google Calendar API を有効化

APIとサービス → ライブラリ → 「Google Calendar API」を検索 → 有効にする

Step 3
OAuth同意画面を設定
  • APIとサービス → OAuth同意画面
  • ユーザーの種類:「外部」を選択
  • アプリ名・メールアドレスを入力
  • スコープに calendar.events を追加
  • テストユーザーに自分のGmailを追加(審査前はこれだけが使える)
Step 4
OAuth クライアントID を発行
  • 認証情報 → 認証情報を作成 → OAuthクライアントID
  • iOS用:バンドルID(例:win.seadice.zuborodiary)を入力
  • Android用:パッケージ名 + SHA-1フィンガープリントを入力
  • 発行されたクライアントIDをFlutterプロジェクトに設定

FlutterでのGoogle Sign-In実装

# pubspec.yaml に追加
google_sign_in: ^6.x.x
googleapis: ^13.x.x
http: ^1.x.x
final GoogleSignIn _googleSignIn = GoogleSignIn(
  scopes: [
    'https://www.googleapis.com/auth/calendar.events',
  ],
);

// サインイン
final account = await _googleSignIn.signIn();
final auth = await account!.authentication;
final accessToken = auth.accessToken;

Google Calendar にイベントを書き込む

// googleapis パッケージを使う
final authClient = GoogleHttpClient({'Authorization': 'Bearer $accessToken'});
final calendarApi = calendar.CalendarApi(authClient);

final event = calendar.Event()
  ..summary = '今日の日記'  // タイトル(一言要約)
  ..description = diaryText  // 本文
  ..start = calendar.EventDateTime(date: DateTime.now())
  ..end = calendar.EventDateTime(date: DateTime.now());

await calendarApi.events.insert(event, 'primary');

専用カレンダーを作る場合は 'primary' の代わりにカレンダーIDを使う。ユーザーのメインカレンダーを汚さない方が親切。


Claude APIで日記を生成する

claude-haiku-4-5を使い、過去5〜10件の日記をプロンプトに入れることでユーザーの文体を模倣します。1回の生成コストは約0.3円、ファインチューニング不要です。

使うモデル

日記生成は claude-haiku-4-5 が最適。安くて速い。1回あたり約0.3円。

プロンプト設計

システムプロンプト:
あなたはユーザーの代わりに日記を書くAIです。
ユーザーの文体・語調を学習して、その人らしい日記を書いてください。

ユーザーの過去の日記(文体参考):
{過去5件の日記本文}

今日の情報:
- 日付:{YYYY年MM月DD日(曜日)}
- 天気:{天気APIから取得 or 不明}
- ユーザーからの一言:{入力テキスト or なし}

上記をもとに、200〜300文字の自然な日記を1つ書いてください。
ユーザーが何も入力していない場合でも、その日らしい日記を作ってください。

天気の取得

無料で使える天気API:Open-Meteo(APIキー不要)

// 位置情報から天気を取得
https://api.open-meteo.com/v1/forecast?latitude={lat}&longitude={lon}&daily=weathercode&timezone=Asia/Tokyo

位置情報の取得には geolocator パッケージを使う。許可が取れなければ天気なしで生成すればいい。


AdMob リワード広告の実装

「投稿」ボタンを押すと動画リワード広告(15〜30秒)が流れ、視聴完了後にGoogle Calendarへの書き込みが実行されます。広告ロード失敗時は直接投稿してUXを守ります。

仕組み

「投稿」ボタンを押すと動画リワード広告が流れる。視聴完了後にGoogle Calendarへの書き込みが実行される。

# pubspec.yaml
google_mobile_ads: ^5.x.x
// リワード広告をロード
RewardedAd.load(
  adUnitId: 'ca-app-pub-xxx/yyy',
  request: const AdRequest(),
  rewardedAdLoadCallback: RewardedAdLoadCallback(
    onAdLoaded: (ad) => _rewardedAd = ad,
    onAdFailedToLoad: (error) => _postDiary(), // 広告失敗時は直接投稿
  ),
);

// 広告を表示して投稿
_rewardedAd?.show(
  onUserEarnedReward: (ad, reward) => _postDiary(),
);

広告のロードに失敗した場合は広告なしで直接投稿する。UXを壊さないことを優先。


ユーザーの文体を学習する仕組み

ファインチューニングは不要です。Google Calendarから過去5〜10件の日記をプロンプトの「文体参考」に入れるだけで、使えば使うほど「自分っぽい」日記が生成されます。

Fine-tuningは使わない。プロンプトに過去の日記を入れるだけで文体が自然に寄っていく。

さらに精度を上げたい場合は、ユーザーが「これは自分らしくない」とフィードバックできるボタンを付けて、再生成できるようにする。


OAuth審査(ストア公開前に必要)

Calendarへの書き込みはセンシティブスコープのため、一般公開前にGoogleのOAuth審査が必要です。審査には数週間かかるため、App Store申請と並行して早めに申請します。

Calendar への書き込みはセンシティブスコープなので、一般公開前にGoogleの審査が必要。

段階できること審査
開発中テストユーザー(自分)だけ使える不要
ストア公開誰でも使える必要(数週間)

審査に必要なもの

戦略: まず審査なしで自分用として作り切る。動くものができてからApp Store申請 → 同時にOAuth審査を出す。審査待ちの間はTestFlightで配布できる。


実装の順番(明日からの作業順)

Day1でGoogle認証、Day2でClaude API連携、Day3でAdMob実装、Day4でApp Store申請準備の4日間スケジュールです。

Day 1
基本UIとGoogle認証
  • Flutterプロジェクト作成(flutter create zuboro_diary
  • Google Cloud Console でプロジェクト作成・Calendar API有効化
  • google_sign_in パッケージでログイン実装
  • ログイン後にCalendarのイベント一覧を取得して表示
Day 2
Claude API で日記生成
  • http パッケージで Claude API を叩く
  • 過去の日記をプロンプトに入れて生成
  • 生成された日記をUIに表示
  • 一言追加できる入力欄を実装
Day 3
AdMob + 投稿機能
  • AdMob アカウント作成・アプリ登録
  • リワード広告のロード・表示
  • 視聴完了後にGoogle Calendarへ書き込み
  • 投稿完了のフィードバックUI
Day 4
仕上げ・App Store申請準備
  • アイコン・スプラッシュ画面
  • プライバシーポリシー作成
  • App Store Connect にアプリ登録
  • TestFlightでテスト
  • OAuth審査の申請(並行して)

明日やること チェックリスト

Google Cloud ConsoleのプロジェクトとCalendar API設定が最初のボトルネックです。以下の順序で進めれば1日でGoogle Sign-Inまで動きます。


APIキーの管理

Claude APIキーはFlutterコードにべた書きしてはいけません。--dart-defineでビルド時に渡すか、Cloud Functions経由でAPIを叩く方法が安全です。

絶対にやってはいけない: Claude APIキーをFlutterコードにべた書きしない。GitHubに上げると漏洩する。

対策:

← ブログ一覧に戻る