見出し画像

自動化したい その12


前回までのあらすじ

見出し修正スクリプト、ここに降臨!
GoogleドキュメントとNoteを繋ぐ、奇跡の架け橋、見出し修正スクリプト!
波乱万丈の自動化プロジェクト、ついにクライマックス!

主人公・俺は、GoogleドキュメントからNoteへの自動化という難題に挑んでいた。
立ちはだかる壁、見出しの修正。
だが、諦めない心が奇跡を生む!
Google Apps Scriptという名の秘宝を手に、俺たちは不可能を可能にする。
見出し修正スクリプト、ここに降臨!
Googleドキュメント本体に宿る、無限の可能性。
果たして、自動化プロジェクトの結末は!?
乞うご期待!

生成と見出しのハイブリッド

前回調べた見出し修正と、Gemini生成スクリプトのハイブリッドがこれ。
見出しについては大見出しと小見出しの2つであるため、修正パターンは■と◆で指定する。
また、Gemini生成スクリプトで設定しているスクリプトプロパティによるAPIKEYとドキュメントIDを設定している。

// メニューにFunctionという名前のボタンを作成
function onOpen() {
  const ui = DocumentApp.getUi();
  ui.createMenu('Function')
      .addItem('01_Geminiによる文章の修正', 'correctDocumentWithGemini')
      .addItem('02_見出しスタイルの適用', 'applyHeading')
      .addItem('03_見出し目印の削除', 'delMark')
      .addToUi();
}

//  見出しスタイルの適用
function applyHeading() {
  const body = DocumentApp.getActiveDocument().getBody();

  //  apply style
  var range_elem1 = body.findText('■');
  while (range_elem1) {
    range_elem1.getElement().getParent().asParagraph().setHeading(DocumentApp.ParagraphHeading.HEADING1);
    range_elem1 = body.findText('■', range_elem1);
  }

  var range_elem3 = body.findText('◆');
  while (range_elem3) {
    range_elem3.getElement().getParent().asParagraph().setHeading(DocumentApp.ParagraphHeading.HEADING3);
    range_elem3 = body.findText('◆', range_elem3);
  }
}

//  見出し目印の削除
function delMark() {
  const body = DocumentApp.getActiveDocument().getBody();
  body.replaceText("■", "");
  body.replaceText("◆", "");
}

// Geminiによる文章の修正
function correctDocumentWithGemini() {
  // スクリプトプロパティからドキュメントのIDとAPIキーを取得
  var documentId = PropertiesService.getScriptProperties().getProperty('DOCID');
  var apiKey = PropertiesService.getScriptProperties().getProperty('APIKEY');

  // ドキュメントを取得
  var document = DocumentApp.openById(documentId);

  // テキストを取得
  var text = document.getBody().getText();

  // GeminiのAPIのエンドポイントURLを設定
  var apiUrl = `https://generativelanguage.googleapis.com/v1beta/models/gemini-pro:generateContent?key=${apiKey}`;

  // プロンプトに加え、Gemini APIリクエストに必要なペイロードを設定
  var payload = {
    "contents": [
      {"role": "user","parts": { "text": text }}
    ],
  };

  // payloadやHTTP通信種別、認証情報をoptionで設定
  var options = {
    'payload': JSON.stringify(payload),
    'method' : 'POST',
    'muteHttpExceptions': true,
    'contentType':'application/json'
  };

  // Gemini APIにAPIリクエストを送り、結果を変数に格納
  var response = JSON.parse(UrlFetchApp.fetch(apiUrl, options).getContentText()); 

  // レスポンスを解析
  var correctedText = response.candidates[0].content.parts[0].text;

  // ドキュメントに反映
  document.getBody().appendParagraph('\n' + correctedText);
}

試してみよう

設定したGoogleドキュメントを使用して、文章を生成してみる。

■条件はこんな感じ


■メニュー化された生成実行
■ここまでは問題なし
■いよいよ見出し変換
■・・・orz

なぜだ、なぜ全部が「見出し1」になってしまう…
見出しの適用自体は出来ているから、スクリプトが改行が認識できていないのかな?
それじゃあ、見出しの部分に手動で改行してみる。

■こんなかんじ
■こういう結果になった

真ん中の部分が見出し3になった理由が分からないが、Geminiで生成した文章の改行コードに、改行コード以外の何かが含まれているんかな?
実際、生成された文章をメモ帳に貼り付けて、メモ帳の文章をGoogleドキュメントに貼り付けてから見出し修正を実行すると、綺麗に修正されるんだよね。

実現方法

整理すると、スクリプトで実現する必要がある項目は2つ。
①Geminiの生成結果をプレーンテキストで貼り付ける。
②改行コードをGoogleドキュメント版に置換する。(追加?)
これを考慮したスクリプトはこちら。

// メニューにFunctionという名前のボタンを作成
function onOpen() {
  const ui = DocumentApp.getUi();
  ui.createMenu('Function')
      .addItem('01_Geminiによる文章の修正', 'correctDocumentWithGemini')
      .addItem('02_見出しスタイルの適用', 'applyHeading')
      .addItem('03_見出し目印の削除', 'delMark')
      .addToUi();
}

//  見出しスタイルの適用
function applyHeading() {
  const body = DocumentApp.getActiveDocument().getBody();

  //  apply style
  var range_elem1 = body.findText('■');
  while (range_elem1) {
    var paragraph = range_elem1.getElement().getParent().asParagraph();
    paragraph.setHeading(DocumentApp.ParagraphHeading.HEADING1);
    paragraph.appendText('\n');
    range_elem1 = body.findText('■', range_elem1);
  }

  var range_elem3 = body.findText('◆');
  while (range_elem3) {
    var paragraph = range_elem3.getElement().getParent().asParagraph();
    paragraph.setHeading(DocumentApp.ParagraphHeading.HEADING3);
    paragraph.appendText('\n');
    range_elem3 = body.findText('◆', range_elem3);
  }
}

//  見出し目印の削除
function delMark() {
  const body = DocumentApp.getActiveDocument().getBody();
  body.replaceText("■", "");
  body.replaceText("◆", "");
}

// Geminiによる文章の修正
function correctDocumentWithGemini() {
  // スクリプトプロパティからドキュメントのIDとAPIキーを取得
  var documentId = PropertiesService.getScriptProperties().getProperty('DOCID');
  var apiKey = PropertiesService.getScriptProperties().getProperty('APIKEY');

  // ドキュメントを取得
  var document = DocumentApp.openById(documentId);

  // テキストを取得
  var text = document.getBody().getText();

  // GeminiのAPIのエンドポイントURLを設定
  var apiUrl = `https://generativelanguage.googleapis.com/v1beta/models/gemini-pro:generateContent?key=${apiKey}`;

  // プロンプトに加え、Gemini APIリクエストに必要なペイロードを設定
  var payload = {
    "contents": [
      {"role": "user","parts": { "text": text }}
    ],
  };

  // payloadやHTTP通信種別、認証情報をoptionで設定
  var options = {
    'payload': JSON.stringify(payload),
    'method' : 'POST',
    'muteHttpExceptions': true,
    'contentType':'application/json'
  };

  // Gemini APIにAPIリクエストを送り、結果を変数に格納
  var response = JSON.parse(UrlFetchApp.fetch(apiUrl, options).getContentText()); 

  // レスポンスを解析
  if (response && response.candidates && response.candidates.length > 0 && response.candidates[0].content.parts && response.candidates[0].content.parts.length > 0) {
    var correctedText = response.candidates[0].content.parts[0].text;

    // ドキュメントに反映
    var body = document.getBody();
    var lines = correctedText.split('\n');
    for (var i = 0; i < lines.length; i++) {
      var element = body.appendParagraph(lines[i]);
      element.setHeading(DocumentApp.ParagraphHeading.NORMAL);
    }
  } else {
    Logger.log('Error: Invalid response from the API');
  }
}

Gemini曰く、「Googleドキュメントでは、改行は通常、新しい段落として扱われます。したがって、改行を含むテキストを追加するには、各行を別々の段落として追加する必要があります。」とのこと。
なるほどー。

実行結果

■これでいけるはず

生成ぽちっとな。

■ここからー

見出し適用、ぽちっとな。

■おお!
■まぁ、そうなるよね

無事、完成。
見出しの目印にしている■と◆の削除スクリプトも問題なし。
いやぁ、良かった良かった。

課題

・命令文の■も見出しに変換されるのを防ぎたい。
・見出し目印削除も一緒にしちゃえばいいんじゃね。

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