概要
GSuiteで複数ドメインをまたいで共有したスプレッドシートや、Googleアカウントで作成したスプレッドシートで、編集している人の名前を設定・取得するための方法です。
背景
スプレッドシートで、編集している人の情報を取得する方法として、Class Session のSession.getActiveUser().getEmail()や Session.getEffectiveUser().getEmail() を利用する方法が一般的です。
例えば、
などがあります。
しかし、Session.getActiveUser().getEmail() は、GSuiteの同じドメインでないと、正しく取得できません。
However, these restrictions generally do not apply if the developer runs the script themselves or belongs to the same G Suite domain as the user.
Session.getEffectiveUser().getEmail() は挙動がわかりづらいですが、スクリプトを実行した人の情報を取得します。onEdit であれば、トリガーの設定は各自という扱いになるのでうまく取得できます。しかし、トリガーを開発者が設定した場合は、開発者の情報になってしまいます。他の人に共有していた場合でも、開発者になってしまう。
Gets information about the user under whose authority the script is running. If the script is a web app set to "execute as me" (the developer), this returns the developer's user account.
というわけで、複数ドメインの人たちとスプレッドシートを共有している場合や、そもそもGSuiteではなく、個人のGoogleアカウントを使っている場合でも、編集している人の情報を設定・取得するためのスクリプトを作ってみました。
実際の動き
アカウントの情報を取得できないのであれば、入力してもらおうという作戦です。
スプレッドシートを共有すると、他の人も同じ動きになります。名前を入力すると、その名前で履歴が残ります。
ソースコード
/*
* ユーザー名を設定・取得する
* PropertiesService.getUserProperties(); を利用
*/
function getUser() {
var properties = PropertiesService.getUserProperties();
var user = properties.getProperty('user');
// 既にユーザー名が保存されていたらそれを返す
if (user) { return user; }
// ユーザー名が設定されていなければ、入力してもらう
while (user == null || user == 'cancel' || user == '') { // 文字が入力されるまで表示
user = Browser.inputBox("あなたの名前を入力してください");
}
properties.setProperty("user", user); // ユーザー名を保存
return user;
}
/*
* ユーザー名を再設定する
*/
function setUser() {
var properties = PropertiesService.getUserProperties();
var user = properties.getProperty('user');
user = Browser.inputBox('あなたの名前を入力してください' + '(現在の名前: ' + user + ')');
if (user != null && user != 'cancel' && user != '') {
properties.setProperty("user", user); // ユーザー名を保存
}
return user;
}
/*
* スプレッドシートを開いたときにイベントを発動
*/
function onOpen(e) {
// スプレッドシート開いた時に名前が入力されているか確認
getUser();
// メニューに追加
SpreadsheetApp
.getActiveSpreadsheet()
.addMenu("設定", [
{name: "名前を変更", functionName: "setUser"}
]);
}
/*
* 編集時にイベントを発動
*/
function onEdit(e) {
var range = e.range;
var value = e.value;
// セルの値が空欄の場合、replace()するとエラーになるので文字列に変えておく
if (value == undefined) { value = ''; }
range.setNote(
range.getNote() + '\n' // これまでのノートを先頭につける
+ Utilities.formatDate(new Date(), 'Asia/Tokyo', 'yy/MM/dd HH:mm') // 編集日付
+ ': '
+ value.replace(/\r?\n/g, ' ') // 改行を削除して現在のセルの値
+ ' (' + getUser() + ')' // 編集した人の名前
);
}
雑な解説
名前は自己申告で入力なので、嘘つくこともできるので、あくまでも性善説で運用する必要があります。しかし、これが故に匿名ユーザーでも利用することができるので、わりと便利です。
人ごとに入力値を保存するのに、PropertiesService.getUserProperties() を利用しています。ひこざるさん: Google Apps Scriptで設定ファイルの保存・読込 にわかりやすいサンプルがあります。
ここでは、onEdit()を使っていますが、トリガーを自分で設定しても正しく動きます。