Как установить триггер по времени (часы) для функции, которой нужно отправлять параметры? - PullRequest
1 голос
/ 03 августа 2020

Я пытаюсь запустить функцию с триггером, управляемым по времени (часами). Моя проблема в том, что функции нужны переменные, отправленные ей в качестве параметров. Обычно, если я не использую триггер, я просто отправляю его напрямую вот так.

<script>
    function runFunction(){
    google.script.run.myFunction(x,y,z);
    }
</script>

А на стороне сервера я легко их вызываю.

function myFunction(x,y,z){
var a = x;
var b = y;
var c = z;
Logger.log(a+b+c);
}

Но когда я использую управляемый по времени (часовой) триггер для запуска функции, как я могу ввести x,y,z в функцию.

Я поискал и увидел один метод создания scriptProperties из параметры в функции триггера:

EDITED Это фактический код.

Клиентская сторона.

<script>
    function sendCall() {
    
      var testNumber = document.getElementById('numberCall').value;
      var testGroup = document.getElementById('groupsCall').value;
      var testtime = document.getElementById('scheduleCall').value;
      var now = document.getElementsByName('sendTimeCall')[0].checked;
      
      var number;
      if(testNumber == ''){
      number = null;
      }else{
      number = testNumber;
      }
      
      var group;
      if(testGroup == ""){
      group = null;
      }else{
      group = testGroup;
      }
      
        var time;
      if(testtime == ''){
      time = null;
      }else{
      time = testtime;
      }
    
      var file = document.getElementsByName('audio')[0].files[0];
      
      var name = file.name;
    
      var reader = new FileReader(); 
      reader.onload = function (e) {   
      var content = reader.result;
    
     google.script.run.withSuccessHandler(success2).triggerCall(group, number, content, time, now, name);
     return false;
      }
          reader.readAsDataURL(file); 
        }
</script>

Сторона сервера - функция триггера.

function triggerCall(group, number, content, time, now, name){

var scriptProperties = PropertiesService.getScriptProperties();
scriptProperties.setProperties({
  'GROUP_CALL': group,
  'AUDIO': content,
  'NUMBER_CALL': number,
  'FILE_NAME': name
});

var status;
if(now){
status = 'Call Sent';
}else{
status = 'Call Scheduled';
}

if(now){
return makeCall(status);
}else{
// Set here the date you want to schedule the one-time trigger
var rawdate = time;
var today_D = new Date(new Date().toLocaleString("en-US", {timeZone: "America/New_York"}));
var scheduled_D = new Date(rawdate);
var time_af = Math.abs(scheduled_D - today_D) / 36e5;

ScriptApp.newTrigger("makeCall")
.timeBased()
.after(time_af * 60 *60 * 1000)
.create();
}
return status;
}

Сторона сервера - вот функция, которая фактически выполняет работу.

function makeCall(status) {

var scriptProperties = PropertiesService.getScriptProperties();
var blob = scriptProperties.getProperty('AUDIO');
var number = scriptProperties.getProperty('NUMBER_CALL');
var group = scriptProperties.getProperty('GROUP_CALL');
var name = scriptProperties.getProperty('FILE_NAME');

var fullNumber;
if(group){
var ss = SpreadsheetApp.openById('xxxxxxxxxxxxxxxxxxx');
var sheet = ss.getSheetByName(group)
var length = sheet.getLastRow();
var values = sheet.getRange(1, 1, length).getValues();
fullNumber = values.flat();

}else{

  var num = number;
  var prefix = '+1';
  var removeDashes = num.replace(/-/g,"");
  var format = prefix + removeDashes;
  var comma = format.replace(/ /g, ' +1');
  fullNumber = comma.split(' ')
}
  
   //upload file to drive
  var folder = DriveApp.getFolderById('xxxxxxxxxxxxxxxxxxxxxx');  
  var blob = blob.split(",");
  var blob = Utilities.newBlob(Utilities.base64Decode(blob[1]), 'audio/mpeg', name);
  var file = folder.createFile(blob); 
     
  file.setSharing(DriveApp.Access.ANYONE_WITH_LINK, DriveApp.Permission.VIEW);
  
  var id = file.getId();

for (var i = 0; i < fullNumber.length; i++){

    //the url with HTTP request to create a call and parameters
  var callsUrl = "https://api.twilio.com/2010-04-01/Accounts/ACxxxxxxxxxxxxxxxx/Calls.json";
   
  var payload = {
    "To": fullNumber[i],
    "From" : "+177777777",
    "Twiml" : "<Response><Play>https://docs.google.com/uc?export=play&amp;id=" + id + "</Play></Response>",
  };
  
  var options = {
    "method" : "post",
    "payload" : payload
  };
  
  options.headers = {    
    "Authorization" : "Basic " + Utilities.base64Encode("xxxxxxxxxxx:xxxxxxxx")
  };
  UrlFetchApp.fetch(callsUrl, options);
  }  
  scriptProperties.deleteProperty('AUDIO');
  scriptProperties.deleteProperty('NUMBER_CALL');
  scriptProperties.deleteProperty('GROUP_CALL');
  scriptProperties.deleteProperty('FILE_NAME');
  return status;
}  

Проблема в том, что когда я запускаю приведенный выше код без ввода файла, он работает, но когда я запускаю его, как указано выше, функция не работает. Я устранил некоторые проблемы, и я думаю, что это связано с передачей файла как URL-адреса данных с помощью метода свойств. Есть ли ограничение на длину строки, которой может быть ЗНАЧЕНИЕ?

в ореховой скорлупе это 2 пункта моего вопроса.

  1. Любые другие идеи, как отправлять параметры к сработавшей функции
  2. Как я мог это сделать, используя PropertiesService.

1 Ответ

3 голосов
/ 03 августа 2020

Я хотел бы предложить следующую модификацию.

Пункты модификации:

  • Я думаю, что причина вашей проблемы может быть связана с максимальным размером данных для PropertiesService. На текущем этапе кажется, что «Общий объем хранилища свойств» равен «500 КБ / хранилище свойств». Я подумал, что в этом случае, когда вы загружаете файл, размер файла может быть больше, чем он.
  • Чтобы удалить вашу проблему, как насчет создания content как временного файла и размещения идентификатора файла в PropertiesService?

Когда указанные выше точки отражаются в вашем скрипте, он становится следующим.

Шаблон 1:

В этом шаблоне content сохраняется как временной файл и используется в функции makeCall().

triggerCall()
function triggerCall(group, number, content, time, now, name){
  var scriptProperties = PropertiesService.getScriptProperties();
  var tempFile = DriveApp.createFile("tempFile.txt", content, MimeType.PLAIN_TEXT);  // Added
  scriptProperties.setProperties({'GROUP_CALL': group,'AUDIO': tempFile.getId(),'NUMBER_CALL': number,'FILE_NAME': name});  // Modified
  var status;
  if(now){
    status = 'Call Sent';
  }else{
    status = 'Call Scheduled';
  }
  if(now){
    return makeCall(status);
  }else{
    var rawdate = time;
    var today_D = new Date(new Date().toLocaleString("en-US", {timeZone: "America/New_York"}));
    var scheduled_D = new Date(rawdate);
    var time_af = Math.abs(scheduled_D - today_D) / 36e5;
    ScriptApp.newTrigger("makeCall").timeBased().after(time_af * 60 *60 * 1000).create();
  }
  return status;
}
makeCall()
function makeCall(status) {
  var scriptProperties = PropertiesService.getScriptProperties();
  var tempfileId = scriptProperties.getProperty('AUDIO');  // Modified
  var number = scriptProperties.getProperty('NUMBER_CALL');
  var group = scriptProperties.getProperty('GROUP_CALL');
  var name = scriptProperties.getProperty('FILE_NAME');
  var fullNumber;
  if(group){
    var ss = SpreadsheetApp.openById('xxxxxxxxxxxxxxxxxxx');
    var sheet = ss.getSheetByName(group)
    var length = sheet.getLastRow();
    var values = sheet.getRange(1, 1, length).getValues();
    fullNumber = values.flat();
  }else{
    var num = number;
    var prefix = '+1';
    var removeDashes = num.replace(/-/g,"");
    var format = prefix + removeDashes;
    var comma = format.replace(/ /g, ' +1');
    fullNumber = comma.split(' ')
  }
  var folder = DriveApp.getFolderById('xxxxxxxxxxxxxxxxxxxxxx');
  
  var tempFile = DriveApp.getFileById(tempfileId);  // Added
  var text = tempFile.getBlob().getDataAsString();  // Added
  tempFile.setTrashed(true);  // Added
  var blob = text.split(",");  // Modified
  var blob = Utilities.newBlob(Utilities.base64Decode(blob[1]), 'audio/mpeg', name);
  var file = folder.createFile(blob);

  file.setSharing(DriveApp.Access.ANYONE_WITH_LINK, DriveApp.Permission.VIEW);
  var id = file.getId();
  for (var i = 0; i < fullNumber.length; i++){
    var callsUrl = "https://api.twilio.com/2010-04-01/Accounts/ACxxxxxxxxxxxxxxxx/Calls.json";
    var payload = {"To": fullNumber[i],"From" : "+177777777","Twiml" : "<Response><Play>https://docs.google.com/uc?export=play&amp;id=" + id + "</Play></Response>"};
    var options = {"method" : "post","payload" : payload};
    options.headers = {"Authorization" : "Basic " + Utilities.base64Encode("xxxxxxxxxxx:xxxxxxxx")};
    UrlFetchApp.fetch(callsUrl, options);
  }  
  scriptProperties.deleteProperty('AUDIO');
  scriptProperties.deleteProperty('NUMBER_CALL');
  scriptProperties.deleteProperty('GROUP_CALL');
  scriptProperties.deleteProperty('FILE_NAME');
  return status;
}

Шаблон 2:

В этом шаблоне content сохраняется в файл как декодированные данные и используется в функции makeCall().

triggerCall()
function triggerCall(group, number, content, time, now, name){
  var scriptProperties = PropertiesService.getScriptProperties();

  var folder = DriveApp.getFolderById('xxxxxxxxxxxxxxxxxxxxxx');  // Added
  var blob = content.split(",");  // Added
  var blob = Utilities.newBlob(Utilities.base64Decode(blob[1]), 'audio/mpeg', name);  // Added
  var file = folder.createFile(blob);  // Added
  scriptProperties.setProperties({'GROUP_CALL': group,'AUDIO': file.getId(),'NUMBER_CALL': number,'FILE_NAME': name});  // Modified
  
  var status;
  if(now){
    status = 'Call Sent';
  }else{
    status = 'Call Scheduled';
  }
  if(now){
    return makeCall(status);
  }else{
    var rawdate = time;
    var today_D = new Date(new Date().toLocaleString("en-US", {timeZone: "America/New_York"}));
    var scheduled_D = new Date(rawdate);
    var time_af = Math.abs(scheduled_D - today_D) / 36e5;
    ScriptApp.newTrigger("makeCall").timeBased().after(time_af * 60 *60 * 1000).create();
  }
  return status;
}
makeCall()
function makeCall(status) {
  var scriptProperties = PropertiesService.getScriptProperties();
  var fileId = scriptProperties.getProperty('AUDIO');  // Modified
  var number = scriptProperties.getProperty('NUMBER_CALL');
  var group = scriptProperties.getProperty('GROUP_CALL');
  var name = scriptProperties.getProperty('FILE_NAME');
  var fullNumber;
  if(group){
    var ss = SpreadsheetApp.openById('xxxxxxxxxxxxxxxxxxx');
    var sheet = ss.getSheetByName(group)
    var length = sheet.getLastRow();
    var values = sheet.getRange(1, 1, length).getValues();
    fullNumber = values.flat();
  }else{
    var num = number;
    var prefix = '+1';
    var removeDashes = num.replace(/-/g,"");
    var format = prefix + removeDashes;
    var comma = format.replace(/ /g, ' +1');
    fullNumber = comma.split(' ')
  }

  var file = DriveApp.getFileById(fileId);  // Modified

  file.setSharing(DriveApp.Access.ANYONE_WITH_LINK, DriveApp.Permission.VIEW);
  var id = file.getId();
  for (var i = 0; i < fullNumber.length; i++){
    var callsUrl = "https://api.twilio.com/2010-04-01/Accounts/ACxxxxxxxxxxxxxxxx/Calls.json";
    var payload = {"To": fullNumber[i],"From" : "+177777777","Twiml" : "<Response><Play>https://docs.google.com/uc?export=play&amp;id=" + id + "</Play></Response>"};
    var options = {"method" : "post","payload" : payload};
    options.headers = {"Authorization" : "Basic " + Utilities.base64Encode("xxxxxxxxxxx:xxxxxxxx")};
    UrlFetchApp.fetch(callsUrl, options);
  }  
  scriptProperties.deleteProperty('AUDIO');
  scriptProperties.deleteProperty('NUMBER_CALL');
  scriptProperties.deleteProperty('GROUP_CALL');
  scriptProperties.deleteProperty('FILE_NAME');
  return status;
}

Примечание:

  • В этом модифицированном сценарии при загрузке файла content сохраняется как временный файл, а идентификатор файла помещается в PropertiesService. При запуске makeCall content извлекается по идентификатору файла, конвертируется в большой двоичный объект и сохраняется как файл. И временный файл удаляется. Этим можно снять ограничение PropertiesService.
  • Но на текущем этапе максимальный размер большого двоичного объекта скрипта Google Apps составляет 50 МБ (52 428 800 байт). Поэтому, когда размер загруженного файла превышает 50 МБ, возникает ошибка. В этом случае файл конвертируется в данные base64. Итак, максимальный размер - это размер данных base64. Будьте внимательны.

Ссылка:

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...