Google DriveのラベルをGoogle Apps Scriptで操作する方法【GAS】

2021年6月ベータ版としてリリースされたGoogle Driveのファイルに対する「ラベル」機能。この機能、Google WorkspaceではBusiness Standard以上でないと利用ができません。これは単なるメタデータとしてラベルではなく、DLP(データ損失防止)の目的であったり、組織で一貫したラベルをつけることで、コンテンツに特別な意味を持たせる、また、これをもとに検索をするといった事ができるようになります。

今回このラベルをAPIを使ってGoogle Apps Scriptから操作してみます。

今回利用するスプレッドシート等

現在は既にv2としてリリースされており、Business Standard以上の契約であれば利用が可能になっています。このラベルは2タイプあり

  1. バッチラベル - 1個のみ作成可能(機密などの非常に特別な組織一貫で指定する)
  2. 標準ラベル - 最大100個作成可能な一般的なラベル。テキストボックスやオプション、日付などのコントロールを追加可能

ラベル割当は編集者権限があれば誰でも可能ですが、ラベルそのものの作成や編集はAdmin権限の管理者のみしか行なえません(ユーザにやらせたら無秩序になる為。カレンダーのリソースと同じですね)。

※フォルダにラベルを付けることはできません

※他の組織がオーナーのファイルにラベルをつけることは出来ません。

事前準備

Admin Consoleで許可する

この機能はGoogle WorkspaceのAdmin Consoleで許可してあげなければ利用する事ができません。

  1. Admin Consoleにログインする
  2. 左サイドバーから、アプリ=>Google Workspace=>ドライブ・ドキュメント=>ラベルを開く
  3. ラベルをオンにするにチェックを入れて保存をクリック

図:ラベル機能をオンにする

ラベルを手動で作成しておく

前述の項目の中に「ラベルを管理」というリンクが小さく存在しています。これをクリックして、手動で作成しておく事が可能です。このページから以下の手順で数種類のタイプのものが作れます。前述の通りバッチラベルは1個のみが作れるので、通常は「機密情報」などの特別なものだけをこれで作成し、その他は標準ラベルで作ります。管理者のみが作成や管理が可能です。

  1. ラベルページを開く
  2. 新しいラベルボタンをクリックする
  3. 標準の新規作成ボタンをクリックする
  4. ラベル名をつける(今回は電帳法対応としました)
  5. ファイルのコピーをする際の動作を指定(今回はラベルはコピーしないようにしました)
  6. フィールドの項目を追加をクリックする
  7. 今回複数選択のオプションリストで作ってみます。オプションリストの+をクリックする
  8. 項目を追加をクリック
  9. フィールド名には書類のタイプとして付けて、オプションリストはオプションリストとして指定する
  10. 項目の選択を必須にするにチェック
  11. 選択肢1をクリックして名前を追加
  12. 選択肢を追加をクリックする
  13. 選択肢2をクリックして次の項目を追加(これを必要な数だけ繰り返す)
  14. 候補の対象ではドライブか?共有ドライブか?を指定。今回は共有ドライブを指定しました。
  15. デフォルト分類やVaultの保持ルールは必要に応じて指定(自動的に付与するルールです)
  16. 最後に右上の権限をクリックする
  17. 組織ユーザに対してどこまで設定させるかの権限。通常はラベルの適用と値の設定を許可します(管理者のみ指定可能ということも可能)。今回はラベルを候補として表示可能にしました。
  18. 公開をクリックする

ラベルは1つに対して複数のフィールドを持たせて1つの塊とすることもできます。

さて、実際に手動でラベルを付けてみます。ドライブのファイルをクリックし、右側の詳細バーの下のほうに「ラベルをつける」という項目があるので、クリックする。ここで「電子帳簿」と検索すると候補が出てくるので、選ぶ(次回からは候補のリストとして出てくる)。

ラベルは1つのファイルに複数つけることも可能なので、しっかり分類をしておき検索性を良くすると良いでしょう。

図:手動ラベル作成画面

図:ラベル作成中の様子

図:ラベルを付けた様子

図:検索画面で指定ができる

GAS側で追加する

今回はDrive APIおよびDrive Labels APIの2つを追加する必要があるため、GASのスクリプトエディタ上で以下の2つを追加しておきます。

  1. スクリプトエディタの左サイドバーのサービスの+をクリック
  2. Drive APIをまず追加する
  3. 次に、Drive Labels APIを追加する。バージョンはv2betaを指定してみた。
  4. IDが空なので今回は「Dlabels」を指定した

図:Drive Labels APIを追加してる様子

図:初回認証時にこう表示される

ソースコード

GASで検索する

これまでのGASでファイルを検索する場合の課題として、膨大なファイルの中から特定の条件で絞り込みをする場合大抵はファイル名に工夫をして検索であったりしてたわけですが、ファイル名での工夫は次第に苦しくなってきます。そこでラベル条件を指定するだけでスパっと一覧が取得できるようになると、GASで操作するのも楽になります。

こちらに検索ワードのドキュメントが用意されています。但し、DriveAppのsearchFilesではドキュメントにラベルに関する記載が無い為、検索する為にはDrive API v2のincludeLabelsを使って検索をする必要があるようです。

//DriveAppでラベルをもとにファイルを検索する
function searchLabelman(){
  //ラベルIDと検索パラメータを指定
  var labelid = 'ここにラベルのIDを指定する'
  var param = '\'labels/' + labelid + '\' in labels';
  var teamDriveId = "共有ドライブのルートのIDを指定する"

  //指定の共有ドライブ内の対象のラベルのついたファイルだけ検索
  const fileList = Drive.Files.list({
      includeLabels: labelid,
      q: param,
      corpora:"teamDrive",
      teamDriveId:teamDriveId,
      includeItemsFromAllDrives:true,
      supportsAllDrives:true
  });
  
  console.log(fileList)

}
  • DriveAppではラベルで検索が出来ないので、Drive API v2を利用して検索を実行します。
  • ラベル名ではなくラベルのIDを元にクエリパラメータを構築して指定が必要です。
  • 今回は指定の共有ドライブ内を検索対象として指定するので、teamDriveIdにドライブルート直下のIDを指定します。
  • Drive.Files.listで検索する。このとき、includeLabelsにラベルのIDを指定する
  • オプションとしてincludeItemsFromAllDrivesをtrueにする必要があります。
  • 同じくsupportsAllDrivesをtrueにする必要があります。
  • corporaは共有ドライブだけを対象にするので、teamDriveを指定します。
  • teamDriveIdにteamDriveIdの変数に格納した値を指定する
  • labelidはカンマ区切りで、paramではand演算子で繋げば複数のラベル指定が可能です

これで、指定の共有ドライブ内で指定のラベルを付けたファイルの一覧を取得できます。また、マイドライブ等も検索対象にするならば

const fileList = Drive.Files.list({
      includeLabels: labelid,
      q: param,
      includeItemsFromAllDrives:true,
      supportsAllDrives:true
});

という形で指定すれば、共有ドライブ + マイドライブを検索対象になります。マイドライブだけを対象にするならば以下のような形でほとんどのオプションを外せば検索することが可能です。

const fileList = Drive.Files.list({
      includeLabels: labelid,
      q: param,
});

Google Apps Scriptでファイルフォルダの探索【GAS】

Google Apps Scriptでカスタムプロパティを使う【GAS】

ラベルの管理

ラベル一覧を取得する

Admin Consoleから追加しておいたラベルのリストを取得します。このラベルのIDをもとに検索をしたり、適用したりするので、リスト一覧の取得は必須です。

//現在のラベルリストを取得
function getAllLabellist() {
  //全ラベルリストを取得
  let labellist = Dlabel.Labels.list();
  let labelarr = labellist.labels;

  //値を配列に加えていく
  let array = [];
  for(let i = 0;i<labelarr.length;i++){
    //レコードを一個取り出す
    let rec = labelarr[i];

    //一時配列を用意する
    let temparr = [
      rec.id,
      rec.labelType,
      rec.properties.title,
      rec.properties.description
    ]

    //配列に追加
    array.push(temparr);
  }

  //シートを取得
  let sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("labelman");
  let ss = sheet.getRange("A2:D");

  //シートをクリアする
  ss.clearContent();

  //シートに書き込みする
  let lastColumn = array[0].length;  //カラムの数を取得する
  let lastRow = array.length;      //行の数を取得する
  sheet.getRange(2,1,lastRow,lastColumn).setValues(array); 

  //フィールド一覧を取得する
  let fields = [];;
  for(let j = 0;j<array.length;j++){
    //レコードを一個取り出す
    let rec = array[j];

    //ラベルIDを取得する
    let label = rec[0];

    //フィールドデータを取得する
    let tempfield = getLabelinfo(label);

    //配列を結合する
    fields = fields.concat(tempfield);
  }

  //シートを取得
  let sheet2 = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("fieldman");
  let ss2 = sheet2.getRange("A2:D");

  //シートをクリアする
  ss2.clearContent();

  //シートに書き込みする
  let lastColumn2 = fields[0].length;  //カラムの数を取得する
  let lastRow2 = fields.length;      //行の数を取得する
  sheet2.getRange(2,1,lastRow2,lastColumn2).setValues(fields); 


  //終了メッセージ
  let ui = SpreadsheetApp.getUi();
  ui.alert("ラベル一覧を取得しました。");
  return 0;
}
  • Dlabels.Labels.listでラベルの一覧をガッツリ取得できます。
  • 返り値からlabelsの中に配列が入ってるので、そこから値を取得しつつ、さらにその中のpropertiesがラベル名等が入ってる配列なので拾ってまとめる
  • 最後にシートに一括書き出しする
  • フィールド一覧の取得については後述で詳しく解説します。

図:無事に一覧を取得することが出来た

フィールドIDを取得する

ラベルは必ずしも1個の値を持ってるとは限りません。1つのラベルの中にテキストボックスや日付ピッカーなど複数を含めることが出来ます。これらをまとめて1つのラベルとしてるのです。これらの項目はフィールドと呼ばれ、いくつかのコントロールで構成されています。これらのフィールドのIDが適用時に必要となる為、一覧で取得しておく必要があります。

//Field_idを取得する関数
function getLabelinfo(labelid){
  //ラベルID
  let labelname = "labels/" + labelid;

  //フルのラベル情報を取得する
  var ret = Dlabels.Labels.get(
    labelname,
    {
      view: "LABEL_VIEW_FULL"
    }
  )

  //フィールド情報を取得
  let array = [];
  let fields = ret.fields;
  let fieldid = "";

  for(let i = 0;i<fields.length;i++){
    //レコードを一個取り出す
    let rec = fields[i];

    //フィールドIDを取得
    fieldid = rec.id

    //一時配列を用意
    let temparr = [
      labelid,
      rec.id,
      rec.properties.displayName
    ]

    //フィールドタイプを特定する
    //text, date, integer, selectの4つで対応
    let option = "";

    if(rec.textOptions == "" || rec.textOptions == undefined){
      //スルー
    }else{
      option = "TEXT"
    }
    
    if(option == ""){
      if(rec.integerOptions == "" || rec.integerOptions == undefined){
        //スルー
      }else{
        option = "INTEGER"
      }
    }

    if(option == ""){
      if(rec.selectionOptions == "" || rec.selectionOptions == undefined){
        //スルー
      }else{
        option = "SELECTION"

        //セレクトボックスの中身を取得
        let choice = rec.selectionOptions.choices
        
        //書類タイプシートに書き出し
        let choicess = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("selection");
        let ssman = choicess.getRange("A2:D");
        ssman.clearContent();

        let choicearr = []
        for(var j = 0;j<choice.length;j++){
          //レコードを一個取り出す
          let crec = choice[j];

          //一時配列を用意
          let temparr = [
            labelid,
            fieldid,
            crec.id,
            crec.properties.displayName
          ]

          choicearr.push(temparr)

        }

        //シートに書き込みする
        let lastColumn = choicearr[0].length;  //カラムの数を取得する
        let lastRow = choicearr.length;      //行の数を取得する
        choicess.getRange(2,1,lastRow,lastColumn).setValues(choicearr); 
      }
    }

    if(option == ""){
      if(rec.dateOptions == "" || rec.dateOptions == undefined){
        //スルー
      }else{
        option = "DATE"
      }
    }

    //option名を追加
    temparr.push(option)


    //書き込み配列に追加
    array.push(temparr);
  }

  //終了メッセージ
  return array;
}
  • 前述のラベル一覧で取得したラベルのIDを引数で取得します。
  • Dlabels.Labels.getでラベルの中にあるフィールドデータを取得します。オプションでLABEL_VIEW_FULLを指定すると詳細なフィールドデータが、配列で取得することが出来ます。
  • フィールドのIDの他にフィールドのタイプを取得したいところですが、そのようなプロパティが無いのでtext, date, integer, selectionそれぞれの値を見て入っていればoptionに入れるようにしています。
  • 途中、rec.selectionOptionsではセレクトボックスの各選択肢のIDを取得していますがこれは後述します。
  • このフィールドIDは適用時に必要となるため、スプレッドシートのfieldmanシートに記録しておきます。

セレクトボックスの値一覧を取得する

更に、セレクトボックスの場合、適用する場合には「選択肢の値」ではなく「選択肢のID」で指定しないとエラーとなるため、これも別途取得しておく必要性があります。selectionシートにその中身を記録します。

前述後半の記述の以下の部分がセレクトボックスの値を取得する項目です

//セレクトボックスの中身を取得
let choice = rec.selectionOptions.choices

let choicearr = []
for(var j = 0;j<choice.length;j++){
  //レコードを一個取り出す
  let crec = choice[j];

  //一時配列を用意
  let temparr = [
    labelid,
    fieldid,
    crec.id,
    crec.properties.displayName
  ]

  choicearr.push(temparr)

}
  • selectionOptionsのchoicesがセレクトボックスの項目で配列で選択肢が入っています。
  • 選択肢名がdisplayNameですが、適用時に利用するのはIDのほうなので注意。

ラベルを適用する

対象のファイルに対して、ラベルを適用し各フィールドに値をセットするには以下のようなコードを利用します。text, integerやdateについてはそのまま値をセットすれば良いのですが、selectionについては値をセットするのではない点が嵌りどころ。

サンプルの中で用意してあるsetLabelsという関数で書き込み用の引数の値をまとめて、setDriveLabelに渡してあげています。

//対象のファイルに対してラベルと値を付ける
function setDriveLabel(fileid,labelid,fieldman,values){
  let request = {
    "labelModifications": [
      {
        "labelId": labelid,
        "fieldModifications": [
          {
            "fieldId": fieldman[0],
            "setSelectionValues": [
              values[0]
            ]
          },
          {
            "fieldId": fieldman[1],
            "setDateValues": [
              values[1]
            ]
          },
          {
            "fieldId": fieldman[2],
            "setIntegerValues": [
              values[2]
            ]
          },
          {
            "fieldId": fieldman[3],
            "setTextValues": [
              values[3]
            ]
          },
        ]
      }
    ]
  }

  //ラベル付与実行
  const updateResponse = Drive.Files.modifyLabels(request,fileid)
  
  //終了処理
  return 0;
}
  • 引数にファイルのID、適用するラベルのID、そのラベルのフィールドID配列、書き込む値のvaluesの配列を取ります。フィールドのID配列とvaluesの配列は順番を一致させておきます
  • 日付はyyyy-mm-ddの形式である必要があるので注意
  • 各項目はsetTextValuesといったようなプロパティをコントロール別で使うので注意。
  • セレクトボックスだけは値ではなく、選択肢のIDで指定が必要なので要注意。
  • 最後にDrive APIのmomdifyLabelsにてリクエストボディとファイルのIDを指定するとラベルを適用して値を書き込みます。

図:ラベルを適用し値を書き込めました

関連リンク

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)