Google Apps Script の
Google Analytics AddOn の
実装した
参考
Google Analytics AddOn に ついて
今回機能とGoogle Analytics AddOn
の
Menu部
ダイアログ部
上記 AddOn は
作った もの
作成した
Code.gs
function onOpen() { var ui = SpreadsheetApp.getUi(); var addon = ui.createAddonMenu(); addon.addItem('Schedule', 'onClickSchedule'); addon.addToUi(); } function onInstall() { onOpen(); } function onClickSchedule() { var htmlOutput = HtmlService.createHtmlOutputFromFile("updateScheduleUi") .setWidth(600).setHeight(100); SpreadsheetApp.getUi().showModalDialog(htmlOutput, 'Schedule Ping'); }
updateScheduleUi.html
以下ダイアログUI部の
これは、
<html> <head> <script src="//www.google.com/jsapi"></script><script>window.parent.maeExportApis_();</script> <link rel="stylesheet" href="https://ssl.gstatic.com/docs/script/css/add-ons.css"> <style> body { margin: 0; } form { overflow: hidden; } select { margin: 0 6px; padding-left: 6px; } .form-row { margin: 10px 0 20px; } .form-action { margin: 30px 0 0; } </style> </head><body style=""><form id="schedule"> <div id="automate-container" class="form-row"> <label> <input name="automate" type="hidden" value="0"> <input id="automate" name="automate" type="checkbox" value="1"> Enable reports to run automatically. </label> </div> <div class="form-row" id="automate-options-container" style="display:none"> <label id="interval-container"> Schedule reports to run <select id="interval" name="interval"> <option value="0"> every hour </option> <option value="1" selected=""> every day </option> <option value="2"> every week </option> <option value="3"> every month </option> </select> </label> <label id="dayOfWeek-container" style="display:none"> on <select id="dayOfWeek" name="dayOfWeek"> <option value="0" selected=""> Monday </option> <option value="1"> Tuesday </option> <option value="2"> Wednesday </option> <option value="3"> Thursday </option> <option value="4"> Friday </option> <option value="5"> Saturday </option> <option value="6"> Sunday </option> </select> </label> <label id="dayOfMonth-container" style="display:none"> on the <select id="dayOfMonth" name="dayOfMonth"> <option value="0" selected=""> 1st </option> <option value="1"> 2nd </option> <option value="2"> 3rd </option> <option value="3"> 4th </option> <option value="4"> 5th </option> <option value="5"> 6th </option> <option value="6"> 7th </option> <option value="7"> 8th </option> <option value="8"> 9th </option> <option value="9"> 10th </option> <option value="10"> 11th </option> <option value="11"> 12th </option> <option value="12"> 13th </option> <option value="13"> 14th </option> <option value="14"> 15th </option> <option value="15"> 16th </option> <option value="16"> 17th </option> <option value="17"> 18th </option> <option value="18"> 19th </option> <option value="19"> 20th </option> <option value="20"> 21st </option> <option value="21"> 22nd </option> <option value="22"> 23rd </option> <option value="23"> 24th </option> <option value="24"> 25th </option> <option value="25"> 26th </option> <option value="26"> 27th </option> <option value="27"> 28th </option> <option value="28"> 29th </option> <option value="29"> 30th </option> <option value="30"> 31st </option> </select> </label> <label id="hourOfDay-container"> between <select id="hourOfDay" name="hourOfDay"> <option value="0"> midnight – 1 a.m. </option> <option value="1"> 1 a.m. – 2 a.m. </option> <option value="2"> 2 a.m. – 3 a.m. </option> <option value="3"> 3 a.m. – 4 a.m. </option> <option value="4" selected=""> 4 a.m. – 5 a.m. </option> <option value="5"> 5 a.m. – 6 a.m. </option> <option value="6"> 6 a.m. – 7 a.m. </option> <option value="7"> 7 a.m. – 8 a.m. </option> <option value="8"> 8 a.m. – 9 a.m. </option> <option value="9"> 9 a.m. – 10 a.m. </option> <option value="10"> 10 a.m. – 11 a.m. </option> <option value="11"> 11 a.m. – noon </option> <option value="12"> noon – 1 p.m. </option> <option value="13"> 1 p.m. – 2 p.m. </option> <option value="14"> 2 p.m. – 3 p.m. </option> <option value="15"> 3 p.m. – 4 p.m. </option> <option value="16"> 4 p.m. – 5 p.m. </option> <option value="17"> 5 p.m. – 6 p.m. </option> <option value="18"> 6 p.m. – 7 p.m. </option> <option value="19"> 7 p.m. – 8 p.m. </option> <option value="20"> 8 p.m. – 9 p.m. </option> <option value="21"> 9 p.m. – 10 p.m. </option> <option value="22"> 10 p.m. – 11 p.m. </option> <option value="23"> 11 p.m. – midnight </option> </select> </label> </div> <div class="form-action"> <button class="action" type="submit">Save</button> <button onclick="google.script.host.close()" type="button">Cancel</button> </div> </form> <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script> <script> $('#schedule').on('submit', function(e) { e.preventDefault(); var formData = $(this).serializeArray(); google.script.run .withSuccessHandler(google.script.host.close) .withFailureHandler(alert) .updateSchedule(formData); }); $('#automate').on('click', function() { if ($(this).is(':checked')) { $('#automate-options-container').show(); google.script.host.setHeight($(document.body).height()); } else { $('#automate-options-container').hide(); google.script.host.setHeight($(document.body).height()); } }); $('#interval').on('change', function() { switch (+$(this).val()) { case 0: $('#dayOfWeek-container').hide(); $('#dayOfMonth-container').hide(); $('#hourOfDay-container').hide(); break; case 1: $('#dayOfWeek-container').hide(); $('#dayOfMonth-container').hide(); $('#hourOfDay-container').show(); break; case 2: $('#dayOfWeek-container').show(); $('#dayOfMonth-container').hide(); $('#hourOfDay-container').show(); break; case 3: $('#dayOfWeek-container').hide(); $('#dayOfMonth-container').show(); $('#hourOfDay-container').show(); break; } }); google.script.host.setHeight($(document.body).height()); </script> </body></html>
updateSchedule.gs
var KEY = "trigger"; var FUNCTION_NAME = "pingSitemap"; var weekDay = [ScriptApp.WeekDay.MONDAY, ScriptApp.WeekDay.TUESDAY, ScriptApp.WeekDay.WEDNESDAY, ScriptApp.WeekDay.THURSDAY, ScriptApp.WeekDay.FRIDAY, ScriptApp.WeekDay.SATURDAY, ScriptApp.WeekDay.SUNDAY ] function updateSchedule(formData) { var formData = toJson_(formData); Logger.log(JSON.stringify(formData)) if (formData != null) { if (formData.automate == 0) { deleteTrigger_(); } else if (formData.automate == 1) { if (formData.interval == 0) { deleteTrigger_(); var triggerId = ScriptApp.newTrigger(FUNCTION_NAME).timeBased() .everyHours(1) .create().getUniqueId(); setTrigger_(triggerId); } else if (formData.interval == 1) { deleteTrigger_(); var triggerId = ScriptApp.newTrigger(FUNCTION_NAME).timeBased() .atHour(formData.hourOfDay) .everyDays(1) .inTimezone(Session.getTimeZone()) .create().getUniqueId(); setTrigger_(triggerId); } else if (formData.interval == 2) { deleteTrigger_(); var triggerId = ScriptApp.newTrigger(FUNCTION_NAME).timeBased() .onWeekDay(weekDay[formData.dayOfWeek]) .atHour(formData.hourOfDay) .nearMinute(30) .create().getUniqueId(); setTrigger_(triggerId); } else if (formData.interval == 3) { deleteTrigger_(); var triggerId = ScriptApp.newTrigger(FUNCTION_NAME).timeBased() .onMonthDay(formData.dayOfMonth) .atHour(formData.hourOfDay) .nearMinute(30) .create().getUniqueId(); setTrigger_(triggerId); } else { throw new Error("Illegal Argments..."); } } } } //serializeArrayをjsonに変換する function toJson_(formData) { var result = {}; var automateValue = 0; formData.forEach(function(elem, i) { if(elem["name"] == "automate" && elem["value"] == 1) { automateValue = 1; } result[elem.name] = elem.value; }); result["automate"] = automateValue; return result; } //指定したkeyに保存されているトリガーIDを使って、トリガーを削除する function deleteTrigger_() { var triggerId = PropertiesService.getScriptProperties().getProperty(KEY); if(!triggerId) return; ScriptApp.getProjectTriggers().filter(function(trigger){ return trigger.getUniqueId() == triggerId; }) .forEach(function(trigger) { ScriptApp.deleteTrigger(trigger); }); PropertiesService.getScriptProperties().deleteProperty(KEY); } //トリガーを発行 function setTrigger_(triggerId){ //あとでトリガーを削除するためにトリガーIDを保存しておく PropertiesService.getScriptProperties().setProperty(KEY, triggerId); }
組み込んで 使用する 際に 変更が 必要な 箇所
SpreadsheetApp.getUi().showModalDialog(htmlOutput, 'Schedule Ping');
'Schedule Ping'
がダイアログの タイトルに 影響します。 変更が 必要な 場合は 変更してください。 var FUNCTION_NAME = "pingSitemap";
スケジュール実行時に実行する function名に なります。 実装する function名に 変更してください。
勉強に なったこと
AddOn の メニュー追加に ついて
スプレッドシート起動時に
onOpen の 処理が 発火する
onOpen
内で、SpreadsheetApp.getUi().createAddonMenu();
で、AddOnMenuを 作成し、 addItem()
していく。
addToUi()
を実行しないと、 画面には 反映されない。 onInstall() は
AddOnの インストール時に 発火する
参考にした 何かの サンプル実装で、 onOpen()を 実行して おり 踏襲で 問題ないかと 思い 同じく onOpen()を 呼び出すように しています。 JQuery#serializeArray() に
ついて
オブジェクトをjson の 配列に 変換してくれる メソッドです。
使ったことなかったので、 jsonが 返ってくると 思い 込んで 実装して、 結構は まりました。
HTML上でformを JQuery#serializeArray()で 変換した 後に、
Apps Script側で、以下の メソッドで json に 変換するようにしました。
automate
をスペシャルロジックで 処理しているのは、 html側の 実装都合です。
//serializeArrayをjsonに変換する function toJson_(formData) { var result = {}; var automateValue = 0; formData.forEach(function(elem, i) { if(elem["name"] == "automate" && elem["value"] == 1) { automateValue = 1; } result[elem.name] = elem.value; }); result["automate"] = automateValue; return result; }
- スケジュール実行用の
トリガー登録に ついて
ScriptApp.newTrigger(FUNCTION_NAME)
実行後、メソッドチェーンで 月次、 週次、 日次等で スケジュール登録しています。
Class Trigger | Apps Script | Google Developers を参考にしながら 実装は 進めました。
使い回しは
以上です。
コメント