今回、クライアント側のみでフォームに入力されたコードを事前に決められたコードかどうかを判断したい、という要望がありました。
が、適切なコードかどうかをクライアントサイドに埋め込んでしまうと問題があるので、どうしたらいいかを考えた結果、Google Apps Scriptを使ってSpreadSheetに記載されたコードとのマッチングを行う、という方法に辿り着きました。
今回はその方法と簡単なコードのメモを残したいと思います。
##実際の動作デモ
jsdo.itの動作デモ
Google SpreadSheetデータサンプル
jsdo.itのサンプルに、SpreadSheetに記載されてるコードを入力してCheckボタンを押すと、バリデーションしてくれます。
##手順
実際の手順については以下のフローを踏みます。
- Google Spreadsheetを新規作成
- Spreadsheetのスクリプトエディタ(※1)からGASの新規プロジェクトを作成
- 公開したいコードをバージョン管理(※2)としてバージョンを割り振る
- 外部公開設定にて、公開したいバージョンを指定する(※3)
- 公開用URLが発行される
- 外部からこのURLにアクセスする
という手順です。
GASはWebアプリケーションとして外部に公開することができるようになっていて、これを上記手順を踏むことで外部からアクセスすることができるようになります。
実際のサンプルコードは以下です。
##サンプルコード
function doGet(e) {
return makeContent(makeResponse(e, "GET"));
}
function doPost(e) {
return makeContent ( makeResponse(e,"POST"));
}
function checkId(id) {
var ss = SpreadsheetApp.openById('0ArR-uXirGVyWdFJ1WFZyclpMRzA5dmhnaVMxa29zNlE');
var sheet = ss.getSheetByName('sheet1');
var range = sheet.getRange(1, 1, sheet.getLastRow(), 1);
var values = range.getValues();
var result = false;
values.forEach(function (row) {
row.forEach(function (val) {
if (result) {
return;
}
if (val === id) {
result = true;
return;
}
});
});
return result;
}
function test() {
Logger.log(checkId('abca'));
}
function makeResponse (e, type) {
var valid = checkId(e.parameter.presentCode);
e.parameter.valid = valid;
var s = JSON.stringify({type: type, params: e});
if (!e.parameter.callback) {
return {mime:ContentService.MimeType.JSON, content: s};
}
else {
return {mime: ContentService.MimeType.JAVASCRIPT, content: e.parameter.callback + "(" + s + ");" };
}
}
function makeContent( content) {
return ContentService.createTextOutput(content.content).setMimeType(content.mime);
}
外部からアクセスがあった際に呼び出されるのがdoGet
とdoPost
です。
引数にはQueryなどの情報が渡されるため、ここから指定の情報を読み取り、なにがしかの処理をしてreturn
でコンテンツを返してやれば、無事、レスポンスが返ってくるという塩梅です。
コードを見てもらうと分かりますが、JSON形式でもJSONP形式でもレスポンスを返すことができるので、かなり柔軟に返却する内容を制御することが出来ます。
とりあえずの動作テストなのでだいぶ適当な部分や、拾ってきたコードそのままなところがありますが、動くことは確認できました。
参考にしたのはこちらのサイト
ここのコードを参考に、SpreadSheetにアクセスして判定を返す、というのを作りました。
##問題点
問題としてはレスポンスが遅めなので、アクセスが集中したり、レスポンスが大事なコンテンツには使えません。
が、ちょっとしたDBを外から簡単にいじれる、みたいなことに意味がある案件とかには使えそうです。