简体   繁体   中英

Google Apps Script / Slack - async or a quick response

I'm building a Slack App for staff doing daily checkins. Staff checkin using the /checkin slash command in Slack. Slack requires a response to the slash command within 3 seconds. If it doesn't then it gives an operation_timeout error to the person who initiated the command.

In my setup the slash command fails the first time for every user, but always works the second time. Rather than rely on this issue going away, is there a way to make sure that the script responds within 3 seconds? Google Apps Script seems a bit slow with it. Even returning a simple response seems slow.

Can I return a quick response to Slack first, and then process the data afterwards? It seems my logUser function is taking longer to execute than the 3s. Or can it be run in a non-blocking way? But even with that, it does seem the response is unreasonably slow.

 function doPost(request){ var params = request.parameters; var user = params.user_id; var text = params.text; if(text == ''){ logUser(user); return ContentService.createTextOutput(':white_check_mark: Checked In; Thank you! <@' + user + '> '); } }

Edit: I think I can use ScriptApp.newTrigger("logUser").timeBased().after(200).create(); to delay the running of logUser, to allow the message to be returned to Slack early. But then I lose the ability to give a parameter to the logUser function?

Edit: logUser function as requested

 function logUser(user){ var checkinSheet = getTodaySheet(); var name = getNameFromId(user); var date = new Date(); var time = date.getTime(); checkinSheet.appendRow([name, user[0], "TRUE"]); }

logUser is selecting the correct Google Sheet (we have one for every day), checking the SlackID of the person who initiated the Slack command against an employee spreadsheet, finding the name of the person who initiated it, and then posting that name into the correct Google Sheet. This can be time consuming, so I can understand why this blocks the response.

Can logUser be run after returning the response to Slack?

Answer:

Use the PropertiesService to store the user's name to the script's properties and then run the function logUser() after you have returned to Slack.

More Information:

You can store information directly as a script property and then use this in your logUser() function to log the users in. It will require a little reworking of your current code but the bsaic run down will be as follows:

  • On POST, store the userId as a script property
  • Set a time-based trigger to run logUser() in an unspecified amount of time in the future
  • Return your content to Slack

Then on trigger of logUser() :

  • Grab the current Script Properties
  • Go through each one individually and log them to the sheet
  • Delete the property after the user has been logged.

Code:

Firstly in your doPost() :

function doPost(request){
  var params = request.parameters;
  var user = params.user_id;
  var text = params.text;

  if(text == ''){
    PropertiesService.getScriptProperties().setProperty(user, "logged-in");
    ScriptApp.newTrigger("logUser").timeBased().after(200).create();
      
    return ContentService.createTextOutput(':white_check_mark: Checked In! Thank you! <@' + user + '> ');
  } 
}

Then for your logUser() function:

function logUser(){
  var checkinSheet = getTodaySheet();
  var usersToLogIn = PropertiesService.getScriptProperties().getKeys();
  var date = new Date();
  var time = date.getTime();

  usersToLogIn.forEach(function(user) {
    var name = getNameFromId(user);
    checkinSheet.appendRow([name, user[0], "TRUE"]);
    PropertiesService.getScriptProperties().deleteProperty(user);
  });  
}

I hope this is helpful to you!

References:

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM