2014-04-25

利用 Google Script 將 Blogger 備份到 Google Drive

在 Google Drive 中建立『指令碼』



然後選擇『空白專案』



貼上以下程式碼
/*
Ref:
https://developers.google.com/apps-script/reference/drive/drive-app
https://developers.google.com/apps-script/reference/drive/file
https://developers.google.com/apps-script/reference/drive/folder
https://developers.google.com/apps-script/reference/url-fetch/url-fetch-app
https://developers.google.com/apps-script/reference/url-fetch/o-auth-config
https://developers.google.com/apps-script/reference/base/blob
https://developers.google.com/apps-script/reference/utilities/utilities

*/

var _backupKeepAmount = 10;
var _backupFolderName = 'blogger_backup';
var _backupFolder;



function main(){
  var folders = DriveApp.getFoldersByName(_backupFolderName);

  if(folders.hasNext()){
    _backupFolder = folders.next();
  }else{
    _backupFolder = DriveApp.createFolder(_backupFolderName);
  }


  setAuth();

  backupBlogger('{my_blog_1}', '{blog_id}', false);
  backupBlogger('{my_blog_2}', '{blog_id}', false);

  MailApp.sendEmail(Session.getActiveUser().getEmail(), 'Backup Blogger To Google Drive', Logger.getLog());
}


/**
 * @param {String} prefixName 備份檔名的前綴
 * @param {String} blogId
 * @param {Boolean} isBigSize 如果備份的檔案超過 10M,請設為 true
 */
function backupBlogger(prefixName, blogId, isBigSize){
  logMsg('Backup Start', prefixName);


  /* 取得之前的備份清單 */
  var files = _backupFolder.getFilesByType('application/xml');
  var beforeFiles = [];
  while (files.hasNext()) {
    var file = files.next();
    if(file.getName().indexOf(prefixName) == -1){ continue; }

    beforeFiles.push(file);
  }

  beforeFiles.sort(function (a, b) {
    return b.getName().localeCompare(a.getName());
  });


  /* 下載並儲存檔案 */
  var isChange;
  if(isBigSize){
    isChange = downloadAndSaveBigSizeArchiveXml(prefixName, blogId, beforeFiles[0]);
  }else{
    isChange = downloadAndSaveArchiveXml(prefixName, blogId, beforeFiles[0]);
  }

  /*沒有異動結束處理*/
  if(!isChange){ return; }


  /* 刪除舊檔案 */
  var oleFiles = beforeFiles.slice(_backupKeepAmount);
  for(var i=0; i < oleFiles.length; i++){
    oleFiles[i].setTrashed(true);
  }


  logMsg('Backup Complete', prefixName);
}




function logMsg(status, msg){
  Logger.log('%s | %s', status, msg);
}



function setAuth(){
  var scope = "https://www.blogger.com/feeds/";
  var oAuthConfig = UrlFetchApp.addOAuthService("blogger");
  oAuthConfig.setRequestTokenUrl("https://www.google.com/accounts/OAuthGetRequestToken?scope="+scope);
  oAuthConfig.setAuthorizationUrl("https://www.google.com/accounts/OAuthAuthorizeToken");
  oAuthConfig.setAccessTokenUrl("https://www.google.com/accounts/OAuthGetAccessToken");

//  oAuthConfig.setConsumerKey("anonymous");
//  oAuthConfig.setConsumerSecret("anonymous");
}



function getArchiveXmlResponse(blogId){
  var options = {
      "oAuthServiceName" : "blogger",
      "oAuthUseToken" : "always"
  };

  var url = 'https://www.blogger.com/feeds/' + blogId + '/archive';
  var response = UrlFetchApp.fetch(url, options);

  /*下載失敗,錯誤記錄*/
  if(response.getResponseCode() != 200){
    logMsg('Download Failed', response.getAllHeaders().toSource());
    return null;
  }

  return response;
}


function downloadAndSaveArchiveXml(prefixName, blogId, beforeFile){
  var response = getArchiveXmlResponse(blogId);
  if(!response){ return false; }

  var downloadContent = response.getContentText();

  /* 檢查檔案異動 */
  if(beforeFile){
    var content = beforeFile.getBlob().getDataAsString();

    if(beforeFile && Math.abs(content.length -downloadContent.length) < 100){
      logMsg('Not Change', prefixName);
      return false;
    }
  }

  /* 儲存下載 */
  var fileName = Utilities.formatDate(new Date(), "+8", "yyyyMMdd_HHmmss'.xml'");
  _backupFolder.createFile(prefixName + '_' + fileName, downloadContent, 'application/xml');

  return true;
}



function downloadAndSaveBigSizeArchiveXml(prefixName, blogId, beforeFile){
  var response = getArchiveXmlResponse(blogId);
  if(!response){ return false; }


  /* 儲存下載 */
  var fileName = Utilities.formatDate(new Date(), "+8", "yyyyMMdd_HHmmss'.xml'");
  var downloadBlob = response.getBlob();
  downloadBlob.setName(prefixName + '_' + fileName);
  downloadBlob.setContentType('application/xml');
  var downloadFile = _backupFolder.createFile(downloadBlob);


  /* 檢查檔案異動 */
  if(beforeFile && Math.abs(beforeFile.getSize() - downloadFile.getSize() ) < 1000){
    downloadFile.setTrashed(true);
    logMsg('Not Change', prefixName);
    return false;
  }

  return true;
}


修改 {my_blog_1} 及 {blog_id},{my_blog_1} 是備份檔名的前綴,{blog_id} 則可以在文章管理的網址上找到



儲存檔案,並取名為『Backup Blogger To Google Drive』




先來測試一下備份是否能正常執行,請選擇執行的函數為『main』,並按下『執行』,然後先為此程式授權





如果都沒問題,接著來設定排程,選擇『啟動程序』



新增一個觸發程序



選擇執行的函數『main』,然後時間定在晚上 11 點,接著選擇『通知』



這個設定主要是發生錯誤的時候可以寄送通知

0 回應: