見出し画像

【自動日記ツール】Googleでアップスクリプトの作成:前編


年末に今年一年を振り返るために、毎日の出来事が自動的に日記として生成されていてほしいのだ。

そんな欲望をもとに考えた一連の仕組みがあるので、今日は、それを紹介します。

本記事だけを読んでも意味がわからないと思いますが、もし、興味のある方は、一連の流れを以下の記事にしていますので、こちらをご参照ください。


今回は、ついに、本ツールの本懐になるGoogle Apps Script、通称GASの設定になります。

全工程のうち、以下のチャートに当たる部分の設定を一気に行います。

スクリプトプロパティの設定

  • 「歯車マーク プロジェクトの設定」を開きます

  • 画面下部にスクロールすると、「スクリプト プロパティ」というものがありますので、「スクリプト プロパティを追加」を押下します。

  • スクリプト プロパティには、以下の内容を入れてください。

    • このとき、「プロパティ」の名前は、ここで指定している文字と、一字一句間違えないように入れます

      • GCalendarID

      • GDrive

      • Gmail

      • OpenAI_key

    • GASで呼び出す名前になるため、間違えた名前で呼ぶと動かないためです

  • GCalendarID

    • 情報を取得するカレンダーです

    • 以下のサイトを参考にカレンダーIDを見つけて、「値」に入力します

  • GDrive

    • 作成された日記の保存先になります

      • 作成された日記は、Googleドキュメントとして、設定されたドライブに保存されます

    • 以下のサイトを参考にドライブIDを見つけて、「値」に入力します

  • Gmail

    • 日記が作成されたら、ここで設定されたメアドあてに連絡が届きます

    • ご自身のメールアドレスを「値」に入力します

  • OpenAI_key

    • 日記やイラストを作成するために使用します

    • 以下のサイトを参考にAPIkeyを発行して、「値」に入力します


全工程を指示するGASの設定

今回の設計では、今後の応用がきくように、各Scriptをわけています。
全部わけずに、GASをコピペしていくだけでも動くと思いますが、エラーがおきたときの確認や、OpenAIが仕様を変えた際などに、あとから入れ替えたりすることを考えると、分けておいておいたほうが良いんだろうと勝手に思ってます。

日記の内容は対象のスプレッドシートにある「inputData」シート内のセル「B2」から取得するようにされています。
スプレッドシートの構成を変える際は、このコードの中も修正するように注意します。


  • 「+」マークから「スクリプト」を選択し、新しい「~~.gs」を作ります。

    • この名前は好きな名前で構いません。

    • 今回は、毎日日記を書いてもらうので、「daily」としました。


「daily.gs」の内容に、以下をコピペします

function generateDailyDiaryAndIllustrateEvent() {
  // 日記の内容とヘッダー情報を準備
  const {combinedContent, headers} = prepareDiaryComponents('B2');
  
  // APIエンドポイントのURL
  const apiUrl = 'https://api.openai.com/v1/chat/completions';
  const imageUrlApi = 'https://api.openai.com/v1/images/generations';
  
  // 日記を生成するためのAPIリクエストオプションを構築
  const diaryOptions = buildApiRequestOptions(headers, combinedContent);
  
  // 日記内容を取得
  const diaryContent = fetchDiaryContent(apiUrl, diaryOptions);
  if (!diaryContent) return; // 日記の内容が取得できなかった場合、処理を終了
  
  // 日記の内容をGoogleドキュメントに保存し、ドキュメントIDを取得
  const docId = saveDiaryToDocument(diaryContent, 'diary');
  
  // 特徴的な出来事を抽出
  const extractedEvent = extractEventFromDiary(apiUrl, headers, diaryContent);
  if (!extractedEvent) return; // 特徴的な出来事が抽出できなかった場合、処理を終了

  // 抽出された特徴的な出来事に関するログ出力
  console.log(`抽出された特徴的な出来事: ${extractedEvent}`);
  
  // 特徴的な出来事からイラスト化プロンプトを作成
  const illustrationPrompt = createIllustrationPrompt(extractedEvent);

  // 作成されたイラスト化プロンプトに関するログ出力
  console.log(`イラスト化プロンプト: ${illustrationPrompt}`);
  
  // イラストをリクエストするためのオプションを構築
  let imageOptions = buildImageRequestOptions(illustrationPrompt);
  
  // DALL-Eにイラストをリクエストし、Googleドキュメントの冒頭に挿入
  requestIllustration(imageUrlApi, imageOptions, docId);
}

このコードが、文中に記載のとおり、日記を作成してから保存するまでの工程を全て指示するGASになります。
そのため、イラストの作成は不要な方は、その部分だけ省いても動きます。多分。

日記を書くGASの設定

おなじように、日記を書くGASを設定します

ここでは、「inputData」シート内のセル「B2」の内容と、「prompt」シート内のセル「B2」の内容をあわせてGPTに送ることで、日記の生成を指示しています。

日記はスプレッドシートに記載しているpromptをもとに生成されますが、たまには違うまとめ方でまとめてほしいようなときもあると思うので、色々なpromptをためせるように、スプレッドシートで管理するようにしてみました。
(「関西弁で日記を書いて」など変化をつけたい際に、毎回コードの中身を修正するのは大変だろうということです)

また、APIKeyは、「スクリプトプロパティ」から参照するようにコードに設定されています。
コードの中に直接書いてしまうと、万が一、コードが流出してしまった際に大変なことになりえるということなので、注意します。

今回のコードであれば、肝になる部分の、「日記の内容」「prompt」「アドレス」などなどが、コードの中には含まれませんので安心安全です。

ただ、、、、
こちら、現在は「'gpt-4-turbo-preview'」を使用しています。
あくまでプレビュー版ですので、ご理解の上、ご利用ください。

ちゃんとしたpromptで日記を指示していれば、3.5でも十分なアウトプットになります。
「ちゃんとしたprompt」は、以下で販売していますのでご参考にされてください(宣伝)

https://note.com/kamicup/n/ndfe203624960


function prepareDiaryComponents(activityRange) {
  const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('inputData');
  const activityData = sheet.getRange(activityRange).getValue();
  const promptData = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('prompt').getRange('B2').getValue();
  const combinedContent = promptData + activityData; // B2と活動データを結合
  const headers = {
    'Authorization': 'Bearer ' + ScriptProperties.getProperty('OpenAI_key'),
    'Content-type': 'application/json',
    'X-Slack-No-Retry': 1
  };
  
  return {combinedContent, headers};
}

function buildApiRequestOptions(headers, combinedContent) {
  return {
    'muteHttpExceptions': true,
    'headers': headers,
    'method': 'POST',
    'payload': JSON.stringify({
      'model': 'gpt-4-turbo-preview',
      'max_tokens': 1500,
      'temperature': 0.7,
      'messages': [
        {
          'role': 'system',
          'content': combinedContent
        }
      ]
    })
  };
}


function fetchDiaryContent(apiUrl, options) {
  const response = UrlFetchApp.fetch(apiUrl, options);
  const jsonResponse = JSON.parse(response.getContentText());
  
  if (jsonResponse.error && jsonResponse.error.code === 'insufficient_quota') {
    console.log('クォータ超過のため、APIリクエストに失敗しました。');
    return null;
  }
  
  if (jsonResponse.choices && jsonResponse.choices.length > 0) {
    return jsonResponse.choices[0].message.content;
  } else {
    console.log('APIレスポンスにchoicesが含まれていません。');
    return null;
  }
}


ドキュメントを保存するGASの設定

作成された日記は、Googleドキュメントに保存します。
タイトルは「diary_yyyymmdd」です。

また、ドキュメントが保存されたら、設定しているメールアドレスあてにメールが届きます。
ユーザーは、毎日、カレンダーにスケジュールを入れるだけで、日記が自動作成されるという体験を得ることが出来ます。

function saveDiaryToDocument(diaryContent, docType) {
  const gDriveId = ScriptProperties.getProperty('GDrive');
  const folder = DriveApp.getFolderById(gDriveId);
  const today = Utilities.formatDate(new Date(), Session.getScriptTimeZone(), 'yyyyMMdd');
  const docTitle = `${docType}_${today}`;
  const doc = DocumentApp.create(docTitle);
  doc.getBody().setText(diaryContent);
  const docFile = DriveApp.getFileById(doc.getId());
  folder.addFile(docFile);
  
  sendDocumentCreationNotification(docTitle, docFile.getUrl());
  return doc.getId();
}

function sendDocumentCreationNotification(docTitle, docUrl) {
  const email = ScriptProperties.getProperty('Gmail'); // スクリプトプロパティからメールアドレスを取得
  const subject = '新しい日記ドキュメントが作成されました';
  const body = `タイトル: ${docTitle}\nURL: ${docUrl}\n\nこのドキュメントをチェックしてください。`;

  MailApp.sendEmail({
    to: email,
    subject: subject,
    body: body
  });
}


テストで実行してみる

ここまでできたら、一度、テストしてみます。
「diary.gs」を開いて、「選択した関数を実行」を押してみます。

まだ、イラスト作成のコードを入れていないので、処理が途中でとまり、エラーにはなりますが、ドキュメントの保存がされ、メールが届くはずです。

届かなかったときは、以下の設定に何らかの異常が発生していると要因が考えられます。
1: スクリプトプロパティの設定
2: GASコードの記載
3: APIkeyの取得
4: openAIとの契約(課金)
5: スクリプト実行権限

もし上記「5」であれば、以下の流れで解決できるかもしれませんので、お試しください


「権限を確認」を実行
自分のアカウントを選ぶ
「詳細」から「〜〜に移動」を実行。
※キャプチャのマスク部分には、自分のメールアドレスが表示されていると思います。
※そのことをもって、「自分が作成したGASであること」が確認できます。
※仮に自分のメールアドレスではなかった場合は、何かを誤ってるので「安全なページに戻る」します。
スクロールして「許可」を押下します

テスト結果を確認する

うまくいけば、Googleドキュメントファイルが作成され、また、設定したメールアドレスあてにメールがとどいているはずです。


この記事が気に入ったらサポートをしてみませんか?