👀

【GAS】ドキュメントからコメントを取得する

2023/10/08に公開

はじめに

こんにちは、志摩です。
業務の自動化をしたくてGoogleAppsScriptに手を出してみたものの、やりたいことの日本語の資料が少ないように思ったので、自分がやったことだけでも残しておきます。

作業内容

業務の自動化の中で困った内容は以下の3点です。

  1. ドキュメントのテンプレートファイルがあるので、コメント付きでコピーしたい。
  2. 本文(ヘッダー、フッター含む)の特定の文字列を置換したい。
  3. 既にある表の末尾に行を追加したい。

今回は1.のテンプレートをコメント付きでコピーする方法を説明していきます。
(当方v2のため、v3だとメソッド名やプロパティ名が違う部分もあるかと思いますがご了承ください)

準備

まずはコピー用のフォーマットを用意します。

テンプレートファイルの中身はこんな感じ。
余力があれば2.3.もまとめようと思うので色々盛り盛りです。
今回のメインであるコメントもアンカー付きで複数用意しておきます。

コーディング

まずはフォーマットファイルをコピーします。
ここは本論ではないのでちゃちゃっと書きます。
TEMP_FILE_IDCOPY_TO_FOLDER_IDはそれぞれファイルIDとフォルダIDを定数でおいてます。

  const tempFile = DriveApp.getFileById(TEMP_FILE_ID); // テンプレートファイルの取得
  const copyToFolder = DriveApp.getFolderById(COPY_TO_FOLDER_ID); // コピー先フォルダ

  // フォルダ名の作成(接頭辞の削除)
  const copyFileName = tempFile.getName().replace('【テンプレート】', '');

  // フォルダを指定してコピーする。
  const copyFile = tempFile.makeCopy(copyFileName, copyToFolder);
  const copyFileId = copyFile.getId(); 

次にコメントを取得します。
コメントの取得にはDrive APIを使用します。
Drive.Commentsがコメントを取得するクラスです。

  // 元ファイルのコメントを取得する
  let commentList = Drive.Comments.list(TEMP_FILE_ID);
  
  // コメントをコピーする。
  commentList.items.forEach(function (comment) {
    let replies = comment.replies;
    delete comment.replies; //  item.repliesを削除しないとエラーになる。
    let commentId = Drive.Comments.insert(comment, copyFileId).commentId;
  });

コピー先のファイルを見てみると、うまく取得できたようです。
ただ、このままだと「解決済み(resolved)」になっているコメントまで取得&コピーしてしまいます。

上記のコメントのような場合はまだ良いのですが、解決済みのコメントにメンションがあるとファイルをコピーする度にメンション先に通知が飛んでしまいます。
そのため、statusがopenのコメントのみ、コピーするように修正します。

  // 元ファイルのコメントを取得する
  let commentList = Drive.Comments.list(TEMP_FILE_ID);
  
  // コメントをコピーする。
  commentList.items.forEach(function (comment) {
    let replies = comment.replies;
    delete comment.replies; //  item.repliesを削除しないとエラーになる。

    if (comment.status == 'open') {
      let commentId = Drive.Comments.insert(comment, copyFileId).commentId;
    }
  });

これで無事、解決済みのコメントは排除してコメントをコピーできました。
では、コメントに返信がついている場合はどうでしょう。
コメントの返信はcomment.repliesに入っているので、それをコピーしたコメントに設定してあげます。

  // 元ファイルのコメントを取得する
  let commentList = Drive.Comments.list(TEMP_FILE_ID);
  
  // コメントをコピーする。
  commentList.items.forEach(function (comment) {
    let replies = comment.replies;
    delete comment.replies; //  item.repliesを削除しないとエラーになる。

    if (comment.status == 'open') {
      let commentId = Drive.Comments.insert(comment, copyFileId).commentId;

      // 返信のコピー
      replies.forEach(function (reply) {
        Drive.Replies.insert(reply, copyFileId, commentId);
      });
    }
  });

delte item.replies;はしないと何故かエラーになるのでしておきます。(おまじない…)
最終的に上記のコードになりました。

おわりに

末筆ではありますが、少しでもGoogleAppsScriptで悩む人が減りますように……

参考資料

・Google Workspace APIガイド
https://developers.google.com/drive/api/reference/rest/v2/comments?hl=ja
・Google Docsをコピーするときにコメントや返事も一緒にコピーしたい
https://qiita.com/tanaike/items/e71fb4dcc2f3182bef56

Discussion