0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

はじめに

週2くらいの頻度でよく夢を見るのですが、
夢日記の記録や占いが地味に手間でした。

  • メモ帳だと読み返しにくい
  • AIに占ってもらうとログが流れて残らない
  • アプリの夢診断はAI部分が有料

「じゃあ自分で自動化しよう」と思い、
Googleフォーム × GAS × Gemini の無料ツールを作りました。
同じような不満を抱えている方の参考になれば幸いです


目次


作ったもの・技術スタック

  • Googleフォームに夢日記を送信
  • Geminiが夢占いをし【キーワード+夢のまとめ】を自動生成
  • 占い結果をメールで通知
  • 過去の夢はスプレッドシートで一覧化

という自動ツールです。

以下の3つだけで実現できます:

  • Googleフォーム
  • Googleスプレッドシート
  • Google Apps Script

外部サーバー不要無料で完結します。


全体構成

  1. ユーザーがGoogleフォームで夢日記を送信
  2. 夢日記がスプレッドシートに追加
  3. Apps Script(onFormSubmit)が自動起動
  4. Gemini APIへ夢の内容を送信して解析
  5. 解析結果をスプレッドシートへ書き込み
  6. AI解析結果をメール送信(通知ONの場合)

※Apps Scriptのトリガー機能がすべて自動実行してくれます。


画面イメージ

  • フォーム
    image.png

  • スプレッドシート
    image.png

  • メール通知
    image.png



実装手順まとめ

① Googleフォームを作る

https://forms.google.com/
項目は3つだけでOKです。

  • 夢を見た日(Date)
  • タイトル(任意)
  • 夢の内容(段落)

フォームURLは「自分専用」で使うため、誰にも公開しなくてOKです。


② 送信先スプレッドシートを作成

Googleフォームの「スプレッドシートに保存」を押すと自動生成されます。
https://docs.google.com/spreadsheets/

列構成:

内容
A 送信日時(自動)
B 夢を見た日
C タイトル
D 夢の内容
E 夢占い結果(AI分析)←GASが自動で書き込む

このシートが “夢日記のアーカイブ” になります。


③ Apps Script の準備

Googleスプレッドシート → 拡張機能 → Apps Script を開きます。

スクリプトプロパティに以下3つを登録:

  • GEMINI_API_KEY(APIキーはhttps://aistudio.google.com/app/apikey から取得。無料枠でOK)
  • FIXED_EMAIL(占い結果を通知するメールアドレス ~@Gmail.com)
  • FORM_URL(夢日記送信用のGoogleフォームURL)

メアド・フォームURLはファイルにベタ書きでも問題ないと思います。
今回はQiitaにコードを載せるためスクリプトプロパティに記載しました。

サンプルコード:ここをクリック
dreamDiary.gs
/**
 * 夢の内容をGeminiに投げて夢占い結果を返す
 */
function callGeminiForDream_(dreamContent) {
  const apiKey = PropertiesService.getScriptProperties().getProperty('GEMINI_API_KEY');
  if (!apiKey) {
    throw new Error('GEMINI_API_KEY がスクリプトプロパティに設定されていません。');
  }

  // モデル名は必要に応じて変更
  const url = 'https://generativelanguage.googleapis.com/v1beta/models/gemini-2.0-flash:generateContent';

  const prompt = `
あなたは日本人の夢占い師です。
以下の夢の内容を読み、その夢が象徴している心理状態やメッセージを分析してください。
出力は必ず次のフォーマットだけにしてください。
・あいさつや前置き、まとめの一言などは書かないこと
・指定していない余計な文章や見出しは出力しないこと
【キーワード】
- キーワード1:このキーワードが象徴する意味を短く説明
- キーワード2:このキーワードが象徴する意味を短く説明
(キーワードの数は24個程度で調整してください)

【夢のまとめ】
この夢全体から読み取れる心理状態やメッセージを、
前向きなアドバイスも含めて、36文程度で日本語でまとめてください

【夢の内容】
${dreamContent}
`.trim();

  const payload = {
    contents: [
      { parts: [{ text: prompt }] }
    ]
  };

  const params = {
    method: 'post',
    contentType: 'application/json',
    payload: JSON.stringify(payload),
    muteHttpExceptions: true
  };

  const response = UrlFetchApp.fetch(url + '?key=' + encodeURIComponent(apiKey), params);
  const text = response.getContentText();
  let data;

  try {
    data = JSON.parse(text);
  } catch (e) {
    throw new Error('Gemini APIレスポンスのJSON解析に失敗しました: ' + text);
  }

  const candidates = data.candidates;
  if (!candidates || !candidates[0] || !candidates[0].content) {
    throw new Error('Gemini APIから有効なレスポンスが得られませんでした: ' + text);
  }

  const parts = candidates[0].content.parts || [];
  const resultText = parts.map(p => p.text || '').join('\n').trim();

  return resultText || '(AIの応答を取得できませんでした)';
}

function onFormSubmit(e) {
  
  const sheet = e.range.getSheet();
  const row = e.range.getRow();
  const lastCol = sheet.getLastColumn();
  const values = sheet.getRange(row, 1, 1, lastCol).getValues()[0];

  const timestamp    = values[0]; // A: 送信日時
  const dreamDate    = values[1]; // B: 夢を見た日(Date型のことが多い)
  const dreamTitle   = values[2]; // C: タイトル
  const dreamContent = values[3]; // D: 内容

  // スプレッドシート全体のオブジェクト
  const ss = SpreadsheetApp.getActiveSpreadsheet();

  // 占い結果送信先メールアドレス(スクリプトプロパティから)
  const FIXED_EMAIL = PropertiesService.getScriptProperties().getProperty('FIXED_EMAIL');
  // GoogleフォームURL(スクリプトプロパティから)
  const FORM_URL = PropertiesService.getScriptProperties().getProperty('FORM_URL');
  // GoogleスプレッドシートURL
  const sheetUrl = ss.getUrl();

  // 「夢を見た日」をyyyy/MM/dd形式にする
  const tz = Session.getScriptTimeZone();
  const dreamDateObj = (dreamDate instanceof Date) ? dreamDate : new Date(dreamDate);
  const dreamDateStr = Utilities.formatDate(dreamDateObj, tz, 'yyyy/MM/dd');

  // 「設定」シートからメール通知フラグ取得
  const settingsSheet = ss.getSheetByName('設定');
  let mailFlag = 'OFF'; // デフォルト
  if (settingsSheet) {
    mailFlag = String(settingsSheet.getRange('B1').getValue()).trim().toUpperCase();
  }

  // 1. Geminiで夢占い結果を生成
  let result;
  try {
    result = callGeminiForDream_(dreamContent);
  } catch (err) {
    result = '【エラー】夢占い結果の取得に失敗しました:' + err.message;
  }

  // 2. シートE列に結果を書き込み
  const RESULT_COL = 5;
  sheet.getRange(row, RESULT_COL).setValue(result);

  // 3. 通知フラグONの場合のみメール送信
  if (mailFlag === 'ON' && FIXED_EMAIL) {
    const subject = `【夢占い結果_自動通知_${dreamDateStr}】`;

    const body =
      '▼夢を見た日\n' + dreamDateStr + '\n\n' +
      '▼夢のタイトル\n' + (dreamTitle || '(タイトルなし)') + '\n\n' +
      '▼夢の内容\n' + dreamContent + '\n\n' +
      '▼夢占い結果(AI分析)\n' + result + '\n\n' +
      '▼過去の夢日記一覧(スプレッドシート)\n' + sheetUrl + '\n\n' +
      '▼新しく夢日記をつける(Googleフォーム)\n' + FORM_URL + '\n\n' +
      '※このメールは、Apps Scriptで自動生成されています。';

    MailApp.sendEmail(FIXED_EMAIL, subject, body);
  }
}

AIへの出力はこのフォーマットに統一

【キーワード】
XXX:意味
XXX:意味

【夢のまとめ】
XXXXX

余計な説明や挨拶は出さないようプロンプトで固定しています。


④ フォーム送信時のトリガーを設定

  1. Apps Script左側メニューの「トリガー」(時計アイコン)をクリック
  2. 右下の「トリガーを追加」を押す
  3. 以下のように設定する
項目 設定内容
実行する関数 onFormSubmit
実行するデプロイ ヘッド(デフォルトのまま)
イベントのソース スプレッドシートから
イベントの種類 フォーム送信時
  1. 「保存」をクリック
  2. 最初だけ Google が権限を確認してくるので「許可する」を押す

これで、フォーム送信時に以下の処理が自動実行されます。

  • フォーム入力情報の取得
  • GeminiへAPIリクエスト
  • Googleスプレッドシートへの書き込み
  • メール通知

⑤メール通知ON・OFFもシートで切替可能に

スプレッドシートに「設定」シートを新規作成し、

A1 B1
メール通知 ON

とするだけで、

  • ON → メール送る
  • OFF → ログを残すだけ

を切替できます。

普段はON、深夜にテストするときはOFF、など運用が楽になります。

私がものぐさで設定をいじるのが手間なので追加しました。
トリガー設定、ファイル修正でも問題ないです


まとめ

今回は、日常の小さな困りごとだった

「夢日記を続けたいけど、占い・記録・管理が手間」

を、Googleフォーム、スプレッドシート、Apps Script、Geminiの組み合わせで自動化しました。

  • キーワード&まとめが読み返しやすい
  • 過去の夢はシートで一覧化できる

この2点は私にとって大きなメリットとなり、
ほんのちょっと、
日常がラクになりました。

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?