Q.Man
Google Spread Sheetで作成したツールを販売したい。けど、スプレッドシートを複製されて、無料配布されてしまう…。どうにか対策できないかな?
P.Man
あ、その悩みなら解決できると思うよ?
Google Spread SheetにGAS(Google Apps Script)を埋め込んで、汎用性の高いツールを作ったから販売したい!と考えている方にとって、スプレッドシートの複製・再配布は天敵ですね。これを防止する方法を紹介します。
スプレッドシート複製の対策
スプレッドシートには「スプレッドシートID」というものが存在します。このシートIDで複製シートを見分ける仕組みをプログラムに実装します。
実装方法
それでは、具体的な実装方法を解説していきます。
1:スプレッドシートID管理用のスプレッドシートを準備
まず、スプレッドシートID管理用にスプレッドシートを準備しましょう。公開設定は「リンクを知っている人全員」にします。シートの中身はこんな感じです。
赤線部分がスプレッドシートIDです。※購入日や購入者識別IDは不要
2:GASにスプレッドシートID比較処理を挿入
続いて、GASにスプレッドシートIDの比較処理を実装します。利用する情報は以下。
- スプレッドシートID管理用スプレッドシートのシートID
- GAS実行シートのシートID
次のような関数を実装します。
//スプレッドシートID管理用スプレッドシートのシートID const LICENCESHEETID = 'スプレッドシートID管理用スプレッドシートのシートID'; //スプレッドシートID管理用スプレッドシートのシート名 const SHEETNAME = 'license'; //スプレッドシートID管理用スプレッドシート上の参照する列 const COL_SHEETID = 4; //関 数:checkLicense //引 数:sheetId > GASが実行されるシートID //戻り値:0:スプレッドシートIDが正しい、-1:スプレッドシートIDが正しくない function checkLicence_(sheetId){ //スプレッドシートID管理用スプレッドシートを取得 let ss = SpreadsheetApp.openById(LICENCESHEETID); let sheet = ss.getSheetByName(SHEETNAME); //登録されている最大行を特定 let mxR = sheet.getRange(sheet.getMaxRows(), COL_SHEETID).getNextDataCell(SpreadsheetApp.Direction.UP).getRow(); if(mxR < 1 ){mxR = sheet.getMaxRows()}; //シートIDを配列valuesに格納 let values = sheet.getRange(2,COL_SHEETID,mxR,COL_SHEETID).getValues().flat(); //valuesの値を引数「sheetId」と比較 for(value of values){ if(value === sheetId){ return 0; } } return -1; }
この「checkLicence_」を販売したいGASのスクリプト先頭に挿入しましょう。実装例は以下です。
function main(){ //GAS実行シートのシートIDを取得 let ss = SpreadsheetApp.getActiveSpreadsheet(); let sheet = ss.getSheetByName(WSNAME); let sheetId = ss.getId(); //checkLicenceで複製シートか確認「-1」は複製シート if(checkLicence_(sheetId) === -1){ Browser.msgBox('本スプレッドシートは不正にコピーされているため利用権限がありません。'); return 0; //強制終了 } //↓↓ココから下が本来の処理 }
3:お客さんに配布するシートIDを追加する
最後に、お客さんに配布するスプレッドシートのシートIDを、スプレッドシートID管理用スプレッドシートに追記します。
最後に
GASプログラムの実行シートを固定し、複製を防止する方法を紹介しました。ただ、このままプログラムを配布すると、GASを読めてしまう人には簡単に仕掛けを解除されてしまいますので、プログラムの隠蔽も必要です。
隠蔽方法について、また別の記事で紹介します。不明点があればコメントにお願いします!
コメント