Action Script 伺服器服務狀態檢查

// 輸出JSON字串, MimeType 可參考:https://developers.google.com/apps-script/reference/content/mime-type
function PrintResponse(result, type) {
   if(!type || type == "json") {
      var JSONString = JSON.stringify(result);
      return ContentService.createTextOutput(JSONString).setMimeType(ContentService.MimeType.JSON);
   } else if(type == "string") {
      return ContentService.createTextOutput(result).setMimeType(ContentService.MimeType.TEXT);
   }
}

// 傳送Line Notify
function sendLineNotify(message, token){
  var options =  {
     "method"  : "post",
     "payload" : {"message" : message},
     "headers" : {"Authorization" : "Bearer " + token}
   };
   UrlFetchApp.fetch("https://notify-api.line.me/api/notify", options);
}

// 檢查URL回應,並返回HTTP code
function CheckUrlIsValid(url) {
   if(!url || url == "")  return "500";
   var options = {
     muteHttpExceptions: true,
     followRedirects: false
   };
  
   var response = UrlFetchApp.fetch(url.trim(), options);
   if(!response)
      return {"code": "-1", "message": "Url Error" };  
   else 
      return {"code":response.getResponseCode(), "message": response.getContentText() };   
}

// 檢查是否到執行時間/判斷是否要執行
function canRun(elems) {
   var d = new Date();
   if(elems[4] != "" && elems[4] != "*") {        // 年
      if(elems[4] != d.getFullYear())  return false;         // 有設定年分,但與目前年份不同-不執行
      if(elems[3] != "" && elems[3] != "*") {     // 月
         if(elems[3] != d.getMonth()+1)  return false;       // 有設定月份,但與目前月份不同-不執行
         if(elems[2] != "" && elems[2] != "*") {  // 日
            if(elems[2] != d.getDate())  return false;       // 有設定日期,但與目前日期不同-不執行
            if(elems[1] != "" && elems[1] != "*") { // 時
               if(elems[1] != d.getHours())  return false;   
               if(elems[0] != "" && elems[1] != "*") {  // 分
                  if(elems[0] != d.getMinutes()) return false;  // 有設定時間,但與目前時間不同-不執行
                  return true;
               } else return true;  // 分-未設定
            } else {  // 時-未設定
               if(elems[0] != "" && elems[1] != "*") {  // 分
                  if(elems[0] != d.getMinutes()) return false;  // 有設定時間,但與目前時間不同-不執行
                  return true;
               } else return true;  // 分-未設定              
            }
         } else {   // 日-未設定
            if(elems[1] != "" && elems[1] != "*") { // 時
               if(elems[1] != d.getHours())  return false;   
               if(elems[0] != "" && elems[1] != "*") {  // 分
                  if(elems[0] != d.getMinutes()) return false;  // 有設定時間,但與目前時間不同-不執行
                  return true;
               } else return true;  // 分-未設定
            } else {  // 時-未設定
               if(elems[0] != "" && elems[1] != "*") {  // 分
                  if(elems[0] != d.getMinutes()) return false;  // 有設定時間,但與目前時間不同-不執行
                  return true;
               } else return true;  // 分-未設定              
            }
         }
      } else {   // 月-未設定
         if(elems[2] != "" && elems[2] != "*") {  // 日
            if(elems[2] != d.getDate())  return false;       // 有設定日期,但與目前日期不同-不執行
            if(elems[1] != "" && elems[1] != "*") { // 時
               if(elems[1] != d.getHours())  return false;   
               if(elems[0] != "" && elems[1] != "*") {  // 分
                  if(elems[0] != d.getMinutes()) return false;  // 有設定時間,但與目前時間不同-不執行
                  return true;
               } else return true;  // 分-未設定
            } else {  // 時-未設定
               if(elems[0] != "" && elems[1] != "*") {  // 分
                  if(elems[0] != d.getMinutes()) return false;  // 有設定時間,但與目前時間不同-不執行
                  return true;
               } else return true;  // 分-未設定              
            }
         } else {   // 日-未設定
            if(elems[1] != "" && elems[1] != "*") { // 時
               if(elems[1] != d.getHours())  return false;   
               if(elems[0] != "" && elems[1] != "*") {  // 分
                  if(elems[0] != d.getMinutes()) return false;  // 有設定時間,但與目前時間不同-不執行
                  return true;
               } else return true;  // 分-未設定
            } else {  // 時-未設定
               if(elems[0] != "" && elems[1] != "*") {  // 分
                  if(elems[0] != d.getMinutes()) return false;  // 有設定時間,但與目前時間不同-不執行
                  return true;
               } else return true;  // 分-未設定              
            }
         }
      }
   } else {  // 年-未設定
      if(elems[3] != "" && elems[3] != "*") {     // 月
         if(elems[3] != d.getMonth()+1)  return false;       // 有設定月份,但與目前月份不同-不執行
         if(elems[2] != "" && elems[2] != "*") {  // 日
            if(elems[2] != d.getDate())  return false;       // 有設定日期,但與目前日期不同-不執行
            if(elems[1] != "" && elems[1] != "*") { // 時
               if(elems[1] != d.getHours())  return false;   
               if(elems[0] != "" && elems[1] != "*") {  // 分
                  if(elems[0] != d.getMinutes()) return false;  // 有設定時間,但與目前時間不同-不執行
                  return true;
               } else return true;  // 分-未設定
            } else {  // 時-未設定
               if(elems[0] != "" && elems[1] != "*") {  // 分
                  if(elems[0] != d.getMinutes()) return false;  // 有設定時間,但與目前時間不同-不執行
                  return true;
               } else return true;  // 分-未設定              
            }
         } else {   // 日-未設定
            if(elems[1] != "" && elems[1] != "*") { // 時
               if(elems[1] != d.getHours())  return false;   
               if(elems[0] != "" && elems[1] != "*") {  // 分
                  if(elems[0] != d.getMinutes()) return false;  // 有設定時間,但與目前時間不同-不執行
                  return true;
               } else return true;  // 分-未設定
            } else {  // 時-未設定
               if(elems[0] != "" && elems[1] != "*") {  // 分
                  if(elems[0] != d.getMinutes()) return false;  // 有設定時間,但與目前時間不同-不執行
                  return true;
               } else return true;  // 分-未設定              
            }
         }
      } else {   // 月-未設定
         if(elems[2] != "" && elems[2] != "*") {  // 日
            if(elems[2] != d.getDate())  return false;       // 有設定日期,但與目前日期不同-不執行
            if(elems[1] != "" && elems[1] != "*") { // 時
               if(elems[1] != d.getHours())  return false;   
               if(elems[0] != "" && elems[1] != "*") {  // 分
                  if(elems[0] != d.getMinutes()) return false;  // 有設定時間,但與目前時間不同-不執行
                  return true;
               } else return true;  // 分-未設定
            } else {  // 時-未設定
               if(elems[0] != "" && elems[1] != "*") {  // 分
                  if(elems[0] != d.getMinutes()) return false;  // 有設定時間,但與目前時間不同-不執行
                  return true;
               } else return true;  // 分-未設定              
            }
         } else {   // 日-未設定
            if(elems[1] != "" && elems[1] != "*") { // 時
               if(elems[1] != d.getHours())  return false;   
               if(elems[0] != "" && elems[1] != "*") {  // 分
                  if(elems[0] != d.getMinutes()) return false;  // 有設定時間,但與目前時間不同-不執行
                  return true;
               } else return true;  // 分-未設定
            } else {  // 時-未設定
               if(elems[0] != "" && elems[1] != "*") {  // 分
                  if(elems[0] != d.getMinutes()) return false;  // 有設定時間,但與目前時間不同-不執行
                  return true;
               } else return true;  // 分-未設定              
            }
         }
      }     
   }
   return true;
}

function DoCheck() {
   var lineToken = "...tlf5GAKbaNkYuicxS13e4lL";   // 應用系統服務監控
   var sheetID = "...leNdskjdOCyH0JMugl7wo0";
   var sheetName = "configure";
   var spreadSheet = SpreadsheetApp.openById(sheetID);  // 透過ID取得試算表   
   var sheet = spreadSheet.getSheetByName(sheetName);   // 取得試算表
   if(!sheet)  return;
   var lastRow = sheet.getLastRow();   
   var lastColumn = sheet.getLastColumn();    // 最後一欄
   var sheetData = sheet.getSheetValues(1, 1, lastRow, lastColumn);   // 開始row,開始Column,結束Rows,numColumns    // 此表示取得全部欄位
   var response, sysName, url, i, msg = "", status = "";
   var data = [];
  
   for(i = 1; i < lastRow; i++) {
      if(!canRun(sheetData[i])) continue;
      
      sysName = sheetData[i][5];
      if(!(url = sheetData[i][6]) || url == "")  continue;
     
      response = CheckUrlIsValid(url);
      if(response.code != "200") {
         msg += (msg != "" ? "\n" : "");
         data.push({"source": "APP", "systemName": sysName, "status": response.message});
         status += (status != "" ? "\n" : "") + sysName + ": " + response.message;
         msg += sysName + ";" + response.code;
         if(sheetData[i][10] == 1)  msg += ";" + response.message;
      } else {
         //msg += sysName + " " + response.code;
      }
      sheet.getRange(i+1, 8).setValue(response.code);
      sheet.getRange(i+1, 9).setValue(new Date());
      if(sheetData[i][10] == 1) sheet.getRange(i+1, 10).setValue(response.message);
  }
  if(msg != "") {  // 若有錯誤的話
     var url = "https://script.google.com/macros/s/...EhoMXB0on/exec";   // 另一個處理程序 doPost
     var formData = {
       "method": "post", 
       "contentType": "application/json",
       "payload": JSON.stringify({
          "systemName": "GoogleAS服務狀態偵測系統",
          "sheetID": "...FmHVdfuBbUDPvIOtmp2q0nOPwkMB-Th4I",
          "sheetName": "APP",
          "status": status,
          "lineNotifyToken": lineToken,
          "send2Dashboard": "Y",  // N
          "data": data
        })
     };
     response = UrlFetchApp.fetch(url, formData);
     Logger.log(response.getContentText());  // for debug
     return PrintResponse(response.getContentText(), "string");
     // msg = "GoogleAS服務狀態偵測系統\n" + (new Date()) + "\n" + msg;
     // sendLineNotify(msg, lineToken);   // 發送LINE訊息
  } else 
     return PrintResponse("", "string");
  
}