#背景と目的
- 大学で担当している授業で、Google アプリをあれこれ利用している。
- Googleフォームを使って、ハンドルネームを登録してもらうことにした。
- ハンドルネームの 重複を避けたい 。
- Googleフォームの 回答の検証 機能を利用して実現したい。
#もくろみ
- Googleフォームの送信時に発火するトリガーを仕掛け、すでに送信されたハンドルネームのリスト作って、これらに一致するハンドルネームの送信を拒否するようにする。
-
回答の検証は決まった数種類しかなく、関数を書いてカスタムの検証を設定することはできない。
- もっとも自由なのは正規表現。正規表現でなんとかするしかない。
- 正規表現で既存のハンドルネームに一致しないような回答の検証を設定できればいいはず。
- これを、Google Apps Script(GAS)で実装する。
#Googleフォームで使える正規表現
- いろいろ試行錯誤した結果、Googleフォームの回答の検証では、正規表現の否定的先読み
?!(foo|bar)
は使えないことがわかった。 - 代わりに、正規表現パターンに一致しない条件での検証が可能。
#GASの実装
- Googleフォームを編集して、右上の〔⁝〕からプルダウンメニューを引きだし、クリプトエディタを呼びだす。
- 以下のようにスクリプトを書いて保存する。
コード.gs
function setHandlenameValidation() {
var thisForm = FormApp.getActiveForm();
// 既存の回答を全部引っ張ってきて、ハンドルネームを取りだす。ハンドルネームは2番目のItemに格納されている。
// エスケープした既存ハンドルネームのリスト escapedHandlenameList を作成
var escapedHandlenameList = []
var responseList = thisForm.getResponses();
for ( var i = 0; i < responseList.length; i++ ){
escapedHandlenameList.push(
responseList[i].getItemResponses()[1]
.getResponse().replace(/[\\^$.*+?()[\]{}|\ ]/g, '\\$&')
);
}
// 正規表現のパターン文字列 validationExpression を生成
var validationExpression = escapedHandlenameList.map(element => `${element}`).join('|')
validationExpression = "^(" + validationExpression + ")$";
// TextValidation オブジェクト textValidation を作成
// requireTextDoesNotMatchPattern() で、正規表現パターンに一致「しない」ことを検証の条件にできる。
var textValidation = FormApp.createTextValidation()
.setHelpText('すでに使われているハンドルネームです。')
.requireTextDoesNotMatchPattern( validationExpression )
.build();
// textValidation を2番目の Item に登録
var formItems = thisForm. getItems()[1]
.asTextItem().setValidation( textValidation );
}
- メニューの 実行 → 関数を実行 から書いた関数を実行して、正しく動作することを確認する。
#トリガーの設定
動作状況の確認
- GASダッシュボード上のプロジェクト名からのプルダウンメニューで実行数をクリックすると、トリガーの実行状況を確認できる。実行に失敗した場合、ステータス欄に失敗しましたと表示される。
#問題点
- 回答の検証の内容はフォームを開く際に確定する。そのため、ユーザーがwebブラウザでフォームを開いてから送信するまでの間に他のユーザーが送信したハンドルネームとの重複は検証できない。
- サーバ側では検証は行われないので、こうした状況が発生すると、重複するハンドルネームが登録されてしまう。
- GASでこれを回避するのはおそらく難しい。
- 重複が発生した場合にハンドルネームの末尾に適当な文字列を付加するなどして重複を避け、GmailApp を使ってそのことをユーザーに知らせるくらいが限界か。
- 筆者のケースは、大学の授業で履修者はおよそ250人で、人数が増えることもなく、アクセス頻度や登録数もさほどではないので、重複に関してはマニュアル対応することにしている(発生頻度はとても低いと考えられるので)。