Google apps script 是否可以从Google App Maker/Google Apps脚本中查看目录API的更改?

Google apps script 是否可以从Google App Maker/Google Apps脚本中查看目录API的更改?,google-apps-script,google-app-maker,Google Apps Script,Google App Maker,我正在谷歌AppMaker中开发一个性能评估应用程序。我们当前工具面临的挑战之一是,当一个人的经理发生变化或一个人的姓名发生变化时,它无法与我们的G套件目录同步——他们现有的评估与该人的旧姓名链接,我们必须手动更改 在我的新应用程序中,我有一个Employees数据源,其中包含与最初通过目录API填充的评估本身的关系。在阅读文档时,似乎我应该能够在Users资源上设置一个监视,以查找用户更新并解析它们,从而在Employees数据源中进行适当的名称和经理更改。但是,我不知道接收watch请求的U

我正在谷歌AppMaker中开发一个性能评估应用程序。我们当前工具面临的挑战之一是,当一个人的经理发生变化或一个人的姓名发生变化时,它无法与我们的G套件目录同步——他们现有的评估与该人的旧姓名链接,我们必须手动更改

在我的新应用程序中,我有一个Employees数据源,其中包含与最初通过目录API填充的评估本身的关系。在阅读文档时,似乎我应该能够在Users资源上设置一个监视,以查找用户更新并解析它们,从而在Employees数据源中进行适当的名称和经理更改。但是,我不知道接收watch请求的URL应该是什么

如果有人在GoogleAppMaker中成功地做到了这一点,甚至仅仅在GoogleApps脚本中,我很想知道你是如何做到的

编辑以添加:

我创建了一个愚蠢的小气体测试函数,看看是否可以让下面的@dimu designs解决方案起作用。不幸的是,我刚刚收到一个错误的请求。以下是我所拥有的:

function setUserWatch() {
  var optionalArgs = {
    "event": "update"
  };

  var resource = {
    "id": "10ff4786-4363-4681-abc8-28166022425b",
    "type": "web_hook",
    "address": "https://script.google.com/a/.../...hXlw/exec"
  };
  AdminDirectory.Users.watch(resource);
}
Address是当前的web应用程序URL

编辑以添加更多内容:
自2014年9月以来,使用GAS接收web钩子的(in)功能一直是一个活跃的问题/功能请求—————————————————————————————————————————————————————————————————————————————————。目录API支持(请注意,此功能计划弃用,因此不确定是什么替代了此功能)。然后,您可以设置一个GMAIL脚本来处理通知


更新:还有来自目录API的消息。

不幸的是,您不能,至少不能仅使用应用程序脚本

管理员目录推送通知需要web钩子URL端点来接收通知。您可能认为部署GAS web应用程序并将其URL用作端点就足够了。但管理员目录推送通知的问题是,它的数据负载驻留在自定义HTTP头中,无法从GAS Web应用程序访问这些头。(这也适用于跨其他API(包括驱动器和日历API)的推送通知)

不过,您可以将Google云功能(GCP服务)与GAS结合使用,但您必须了解Node.js的使用方法


编辑

在考虑了一下,并回顾了您的需求之后,我相信有一种方法可以通过使用天然气来实现这一点

您可以通过为每个用户/域的给定事件(用例中的“更新”事件)设置唯一的推送通知通道。因此,仅当发生更新事件时才会触发GAS web应用程序;您实际上不需要依赖HTTP头来确定事件类型


如果要跟踪多个事件,只需为每个事件创建一个唯一的通道,并为每个事件使用相同的GAS Web app端点。通过检查POST请求中发送的事件参数来区分事件。这将消除对中间人服务(如Heroku或Google云功能)的需求

我能够使用基于Heroku的Node.js应用程序作为中间API为本地资源(电子表格)设置推送通知。节点应用程序捕获自定义请求头并构建GAS web应用程序的doPost(e)功能要使用的有效负载

构造监视请求的代码很简单

  //get the unique id
  var channelId = Utilities.getUuid();  
  //build the resource object    
  var resource = {  
    "id": channelId,
    "type": "web_hook",
    "address": "https://yourapp.herokuapp.com/drivesub    
  }

//watch the resource
Drive.Files.watch(resource, fileId);
挑战在于验证该域地址。有很多方法可以验证独立(非文件绑定!)GAS web应用程序,但是,正如前面的海报所提到的,应用程序脚本web应用程序无法访问自定义标题

启用发布/订阅API并创建主题和订阅后,转到API和服务->凭据->域验证。它为您提供了一些验证域的选项,包括提供html文件。下载谷歌生成的文件。谢天谢地,Heroku使部署节点应用程序变得非常容易

验证域后,您可以将订阅数据推送到Heroku上的端点URL

我只是为路由处理程序创建了js文件,并专门为域验证创建了一个

handlers.verifyDomain = function(callback){
    //Synchronously read from the static html file. Async method fs.readFile() doesn't make the file available to the router callback
    var file = fs.readFileSync('./google/google_file.html');
    callback(200, file); 
}
然后在路由器对象中包含处理程序,如下所示:

var router = {
    "google_file.html": handlers.verifyDomain
}
最后,在服务器启动函数中,从URL获取路径(有多种方法),并执行处理程序

    var routeHandler = router(path);
    routerHandler(function(statusCode, file){ 
      //do something 
     });
返回域验证工具并加载HTML页面以验证URL。验证后,剩下的唯一步骤是创建GAS web应用程序并发布到其中

返回到节点应用程序。注意,我的端点是

应用程序脚本应用程序-不要忘记发布它

function doPost(req) {

var postData = req.postData["contents"];
var headers = JSON.parse(postData)["headers"];
//take action
return 200;

}

这是一个更全面的答案

Google支持在他们的许多API上推送通知。然而,它们之间有许多细微的差别。一些利用Webhook的应用程序主要以HTTP头的形式发送数据有效负载;例如,驱动器API和日历API。其他人在HTTP头和POST正文(例如:AdminDirectory API)之间混合有效负载。它变得更加疯狂,一些API完全利用了不同的机制(例如:GMail API利用了Cloud PubSub)

每个应用程序都有细微差别,但您的目标是在GAS应用程序中利用AdminDirectory推送通知。要做到这一点,您需要一个GAS Web应用程序,其URL可以用作Web钩子端点


步骤1-将独立脚本部署为Web应用程序 让我们从以下模板脚本开始,并从应用程序脚本编辑器菜单将其部署为Web应用程序
发布>部署为Web应用程序

/** HTTP GET request handler */
function doGet(e) {
    return ContentService.createTextOutput("GET message");
}

/** HTTP POST request handler */
function doPost(e) {
    return ContentService.createTextOutput("POST message");
}

步骤2-验证/验证域所有权并添加/注册域 注意:自2019年8月起,无法再使用此方法验证GAS Web应用程序URL。谷歌云功能可能是可行的 另类/** HTTP GET request handler */ function doGet(e) { return ContentService.createTextOutput("GET message"); } /** HTTP POST request handler */ function doPost(e) { return ContentService.createTextOutput("POST message"); }
function startUpdateWatch() {
    var channel = AdminDirectory.newChannel(),
        receivingURL = "https://script.google.com/macros/s/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx/exec",
        gSuiteDomain = "[business-name].com",
        event = "update";

    channel.id = Utilities.getUuid();
    channel.type = "web_hook";
    channel.address = receivingURL + "?domain=" + gSuiteDomain + "&event=" + event;
    channel.expiration = Date.now() + 21600000; // max of 6 hours in the future; Note: watch must be renew before expiration to keep sending notifications

    AdminDirectory.Users.watch(
        channel, 
        {
            "domain":gSuiteDomain,
            "event":event
        }
    );
}
function doPost(e) {

    switch(e.parameter.event) {
        case "update":
            // do update stuff
            break;

        case "add":
            break;

        case "delete":
            break;
    }

    return ContentService.createTextOutput("POST message");

}