如何使用 Google Apps Script webapp 发送延迟响应(Slack api)?

Gin*_*ckx 1 asynchronous google-apps-script slack-api

我们有一个处理 Slack 斜杠命令的小型 Google Apps Script webapp。它直接从 Slack 执行一些方便的操作,例如向我们的工作表添加、更新和查询记录。大多数时候一切正常。但是,Slack API 需要在不到 3 秒的时间内收到请求的答复,否则它将超时。我们的 Google Apps 脚本并不总是能够在那个时间范围内做出响应,随着我们的工作表增长或我们的查询变得更加复杂,这种情况只会变得更糟。

Slack API 允许使用延迟响应的异步调用,但这意味着 Google Apps 脚本需要立即响应(在 3 秒内)并在后台执行一些工作。

现在这是问题

我不知道如何在 Google Apps Script 中进行异步调用

我知道 Google Apps Script 不支持 Workers 并且我下面的解决方案因为ReferenceError: 'google' is not defined碰壁。(只需忽略 Payload 类,它会格式化 Slack 响应)

function doPost(request) {
  var responseUrl = request.parameter.response_url

  // This is how I try to circumvent the lack of threads in Google Apps Script
  google.script.run

  // Send an asynchronous slack response with result
  .withSuccessHandler(function(payload) {
    UrlFetchApp.fetch(responseUrl, {
      'method' : 'post',
      'contentType': 'application/json',
      'payload' : payload.toString()
    });
  })

  // Send an asynchronous slack response with error message
  .withFailureHandler(function(payload) {
    UrlFetchApp.fetch(responseUrl, {
      'method' : 'post',
      'contentType': 'application/json',
      'payload' : payload.toString()
    });
  })

  // do work in the background
  .sleep(5);
  
  return new Payload("Let me think about this...").asResponse();
}

function sleep(seconds) {
  Utilities.sleep(1000 * seconds);
  return new Payload("I waited for " + seconds + " seconds");
}
Run Code Online (Sandbox Code Playgroud)

有谁知道如何使这项工作?是否有其他解决方案来处理 Google Apps 脚本中的异步请求?

Hen*_*reu 5

我也不知道 Apps Script 中有任何线程,正如您所注意到的,google.script.run它只适用于 Apps Script 前端。

作为一种解决方法,您可以使用 Google 表单作为您的“任务队列”。我将一个简单的 G-Form 和一个问题放在一起,并检查了它的最终版本以获得适当的参数名称和 URL。然后我设置了一个可安装的表单提交触发器来运行我的脚本。这是我的 POC 代码:

function doPost(e) {
  var form = 'https://docs.google.com/forms/d/e/1FAIpQLScWBM<my-form-id>CRxA/formResponse';
  UrlFetchApp.fetch(form, {method:'POST', payload:'entry.505669405=' + e.parameter.example});
  return ContentService.createTextOutput('OK');
}

function onForm(e) {
  //triggered async from doPost via a Google Forms
  SpreadsheetApp.getActive().getSheetByName('Sheet1').appendRow(e.values);
}
Run Code Online (Sandbox Code Playgroud)

它在我的测试中运行良好,应该足以满足您的用例。