🐾

GAS+スプレッドシートでアクセスログを残すCollaboflowカスタマイズ

2023/04/29に公開

はじめに

コラボフローで、いつ誰がどの申請書を閲覧したのか確認できるよう、ログを残すカスタマイズをしてみたのでご紹介します!

ログは簡易的なものとし、Googleスプレッドシートへ1アクセス1行で登録してみます。
閲覧したユーザーのIDや文書IDを、JavaScriptカスタマイズでGoogle Apps Script(GAS)宛に送信し、GASでスプレッドシートへ書き込むことにしました。
以下が概要図です。

主な処理

IPアドレスの取得

申請書閲覧時に先ずはJavaScriptカスタマイズで、閲覧者のIPアドレスを取得します。
JavaScriptやGASでは接続元のIPアドレスを取得できないため、外部サービス「ipinfo.io」のAPIでIPアドレスを取得します。

const fetchIpAddress = async() => {
  return await fetch('https://ipinfo.io?callback')
  .then(response => response.json())
  .then(json => json.ip);
}

ログ(閲覧情報)をGASへ送信

次に閲覧した申請書の「文書ID」、閲覧者の「ユーザーID」「IPアドレス」「ユーザーエージェント(ブラウザ情報)」を、JavaScriptカスタマイズでGAS実行用のURLに送信します。
ユーザー情報を取得する関数は、コラボフローで用意されてます。

const loginUser = collaboflow.getLoginUser();
const logData = {
  'document_id' : e.document_id,
  'user_id' : loginUser.userid,
  'ip_address' : ipAddress,
  'user_agent' : navigator.userAgent
};
const gasURL = '{GASデプロイ先URL}';

collaboflow.proxy.post(gasURL, {}, logData, 'json')
.then(response => {
  console.log('logging', response);
});

ログ書き込み用のシート作成

送信されたログをGASのdoPost()関数で受け付けたら、ログを書き込むシートを用意します。
シートを追加する関数はinsertSheet()で、今回は年月毎に1シート作成するようにしてみました。
既に該当月のシートが存在する場合はgetSheetByName()関数で取得し、再利用します。

function getSpreadSheet() {
  const spreadSheet = SpreadsheetApp.openById(SpreadsheetApp.getActiveSpreadsheet().getId());
  const sheetName = Utilities.formatDate(new Date(), 'JST', 'yyyy年MM月');
  let sheet = spreadSheet.getSheetByName(sheetName);

  if (sheet === null) {
    sheet = spreadSheet.insertSheet(sheetName, 0);
    sheet.appendRow(['日時', '文書ID', 'ユーザーID', '接続元IP', 'ユーザーエージェント']);
  }

  return sheet;
}

ログの書き込み

用意したシートへ、日時とログ情報をGASのappendRow()関数で1行追記します。

function writeAccessLog(sheet, log) {
  const ua = HtmlService.getUserAgent();
  const dateTime = Utilities.formatDate(new Date(), 'JST', 'yyyy/MM/dd HH:mm:ss');
  sheet.appendRow([dateTime, log.document_id, log.user_id, log.ip_address, ua]);
}

準備と設定手順

スプレッドシートファイルとGASの準備

  1. Googleドライブに新規スプレッドシートを作成します。
  2. 「拡張機能>Apps Script」から以下コードを設定して保存します。
ログを書き込むGoogle Apps Script
function doPost(e) {
  const log = JSON.parse(e.postData.getDataAsString());
  if (!isValidInput(log)) {
    return outputText({'success':false});
  }

  const sheet = getSpreadSheet();
  writeAccessLog(sheet, log);

  return outputText({'success':true});
}	

function isValidInput(log) {
  if (!log.document_id) {
    return false;
  }

  if (!log.user_id) {
    return false;
  }

  if (!log.ip_address) {
    return false;
  }

  if (!log.user_agent) {
    return false;
  }

  return true;
}

function getSpreadSheet() {
  const spreadSheet = SpreadsheetApp.openById(SpreadsheetApp.getActiveSpreadsheet().getId());
  const sheetName = Utilities.formatDate(new Date(), 'JST', 'yyyy年MM月');
  let sheet = spreadSheet.getSheetByName(sheetName);

  if (sheet === null) {
    sheet = spreadSheet.insertSheet(sheetName, 0);
    sheet.appendRow(['日時', '文書ID', 'ユーザーID', '接続元IP', 'ユーザーエージェント']);
  }

  return sheet;
}

function writeAccessLog(sheet, log) {
  const dateTime = Utilities.formatDate(new Date(), 'JST', 'yyyy/MM/dd HH:mm:ss');
  sheet.appendRow([dateTime, log.document_id, log.user_id, log.ip_address, log.user_agent]);
}

function outputText(result) {
  console.log(result);
  return ContentService.createTextOutput(JSON.stringify(result));
}
  1. 「デプロイ>新しいデプロイ」のメニューから、以下設定でデプロイします。
    • デプロイタイプ:ウェブアプリ
    • 次のユーザーとして実行:自分
    • アクセスできるユーザー:全員
  2. Apps Scriptの信頼確認画面が表示されたら、承認します。
  3. デプロイで発行されるURLをJavaScriptカスタマイズで利用するため、コピーして控えます。

JavaScriptカスタマイズファイルの作成と設定

  1. 以下コードを貼り付けてjsファイルを作成します。
    ※gasURLは、デプロイで発行されたURLに書き換えてください。
ログを書き込むGoogle Apps Script
  'use strict';

  const gasURL = '{GASデプロイ先URL}';
  const events = [
    'request.detail.show',
    'request.judgement.show'
  ];

  collaboflow.events.on(events, function(e) {
    const fetchIpAddress = async() => {
      return await fetch('https://ipinfo.io?callback')
      .then(response => response.json())
      .then(json => json.ip);
    }

    const writeAccessLog = async() => {
      const ipAddress = await fetchIpAddress();
      const loginUser = collaboflow.getLoginUser();
      const logData = {
        'document_id' : e.document_id,
        'user_id' : loginUser.userid,
        'ip_address' : ipAddress,
        'user_agent' : navigator.userAgent
      };

      collaboflow.proxy.post(gasURL, {}, logData, 'json')
      .then(response => {
        console.log('logging', response);
      });
    }

    writeAccessLog();
  });
})();
  1. 以下ガイドを参考に、コラボフローでjsファイルを申請書フォームに設定します。

実行と確認

  1. 対象フォームで新規文書を申請します。
  2. 申請された申請書を判定者などのユーザーで開きます。
  3. Googleスプレッドシートを確認します。

    これでいつ誰がどの申請書を閲覧したのか確認できるようになりました!!!

おわりに

コラボフローのJavaScriptカスタマイズはモバイル表示では動作対象外など制限事項があるため、今回のアクセスログはあくまで参考程度の情報となります。
ですがGoogleスプレッドシートにデータ記録する仕組みは、お手軽データベースとしていろいろ活用できそうです。
以下のGAS連携もステキでした☆彡

コラボスタイル Developers

Discussion