首页 文章

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

提问于
浏览
1

我正在使用Google App Maker中的效果评估应用 . 我们当前工具面临的挑战之一是,当一个人的经理发生变化或者一个人的名字发生变化时,它不会与我们的G Suite目录同步 - 他们现有的评估与该人的旧名称相关联,我们有手动更改 .

在我的新应用程序中,我有一个Employees数据源,其中包含最初通过Directory API填充的评估本身的关系 . 阅读文档here,似乎我应该能够在Users资源上设置一个监视来查找用户更新并解析它们,以便在Employees数据源中进行适当的名称和管理器更改 . 但是,我无法弄清楚接收URL应该是监视请求的内容 .

如果有人在Google App Maker中成功完成此操作,或者甚至仅在Google Apps脚本中完成此操作,我很想知道您是如何做到这一点的 .

编辑添加:

我创建了一个愚蠢的小GAS测试功能,看看我是否可以获得下面的@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);
}

地址是当前的Web应用程序URL .

编辑添加更多:自2014年9月以来,使用GAS接收Web钩子的能力一直是一个活跃的问题/功能请求 - https://issuetracker.google.com/issues/36761910 - 已经有一段时间了@dimu-designs .

4 回答

  • 3

    这是一个更全面的答案 .

    Google支持跨许多API的推送通知 . 然而,它们之间存在许多微妙(而不是那么微妙)的差异 . 利用webhooks的一些主要将其数据有效负载发送为HTTP头;例如Drive API和Calendar API . 其他人将其有效负载混合在HTTP标头和POST主体之间(例如:AdminDirectory API) . 它变得更加疯狂,一些API完全利用不同的机制(例如:GMail API利用Cloud PubSub) .

    每个都有细微差别,但您的目标是在GAS应用中利用AdminDirectory推送通知 . 为此,您需要一个GAS Web App,其URL可用作Web挂钩 endpoints .


    步骤1 - 将独立脚本部署为Web应用程序

    让我们从以下模板脚本开始,并从Apps脚本编辑器菜单 Publish > Deploy As Web App 将其部署为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 - 验证/验证域所有权和添加/注册域

    部署Web应用程序后,您现在必须验证并注册接收URL的域,在这种情况下也是Web应用程序URL . 此网址采用以下格式:

    https://script.google.com/macros/s/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx/exec

    从技术上讲,您不能拥有GAS Web应用程序URL的域名 . 值得庆幸的是,谷歌的App Script Gods确实提供了一种机制来验证和注册GAS Web应用程序URL .

    从Apps Script Editor菜单中选择 Publish > Register in Chrome Web Store . 向Chrome网上应用店注册已发布的网络应用也会验证网址的域名(无需使用搜索控制台) .

    验证后,您需要add the "domain" via the Domain verification page in the API Console . "domain"是网址中的所有内容'exec',因此您将添加如下所示的字符串:

    https://script.google.com/macros/s/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx/


    第3步 - 提出观察请求

    对于此步骤,应为App Script项目和API控制台启用AdminSDK / Directory API服务 .

    创建一个生成监视请求的函数(可以为其他事件类型重新设置):

    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
            }
        );
    }
    

    请注意,Directory API推送通知已过期,最长为启动 Watch 后6小时,因此必须定期续订以确保将通知发送到 endpoints URL . 通常,您可以使用基于时间的触发器每5个小时左右调用此函数 .


    步骤4 - 更新doPost(e)触发器以处理传入通知

    与其他API的推送机制不同,Directory API发送POST主体及其通知,因此保证在发送通知时触发doPost(e)方法 . 定制doPost(e)触发器来处理传入事件并重新部署Web应用程序:

    function doPost(e) {
    
        switch(e.parameter.event) {
            case "update":
                // do update stuff
                break;
    
            case "add":
                break;
    
            case "delete":
                break;
        }
    
        return ContentService.createTextOutput("POST message");
    
    }
    

    有一点值得记住 . 推送更新事件的通知只会告诉您用户的数据已更新,它不会告诉您确切的更改内容 . 但这是另一个问题的问题 .

    请注意,我遗漏了大量细节,但这应该足以让您启动并运行 .

  • 1

    您可以使用GAS和Admin SDK执行此操作 . Directory API支持Notifications(注意这是不推荐使用的,所以不确定是什么替换了这个功能) . 然后,您可以设置GMAIL脚本以执行通知所需的操作 .

    更新:目录API中还有PUSH notifications .

  • 1

    我能够使用基于Heroku的Node.js应用程序作为中间API为本地资源(电子表格)设置推送通知 . Node应用程序捕获自定义请求标头并构建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应用程序,但是,正如之前的海报所提到的,Apps Script Web应用程序无法访问自定义 Headers .

    启用Pub / Sub API并创建主题和订阅后,请转到API和服务 - >凭据 - >域验证 . 它为您提供了一些验证域名的选项,包括提供html文件 . 下载Google生成的文件 . 值得庆幸的是,Heroku使部署Node应用程序变得非常容易

    https://devcenter.heroku.com/articles/getting-started-with-nodejs

    验证域后,您可以将订阅推送数据推送到Heroku上的 endpoints 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应用程序并发布到它 .

    返回节点应用 . 请注意我的 endpoints 是https://yourapp.herokuapp.com/drivesub

    //The code for posting data to GAS web app. Of course, you need to
    // update your router with router['driveSub'] = handlers.driveSub
    
    handlers.driveSub = function(data, callback){
        var headers = data.headers;
        var options = {
            method:"POST",
            uri: your_gas_app_url, 
            json:{"headers":headers}
        };
        //Use NPM to install the request module
        request.post(options, function(err, httpResponse, body){
            console.log(err, body);
    
        });
        callback(200, data);
    
        }
    

    Apps脚本应用 - 不要忘记发布它 .

    function doPost(req) {
    
    var postData = req.postData["contents"];
    var headers = JSON.parse(postData)["headers"];
    //take action
    return 200;
    
    }
    
  • 1

    不幸的是,你不能,至少不能单独使用Apps Script .

    管理员目录推送通知需要Web挂钩URL endpoints 来接收通知 . 您可能认为部署GAS Web应用程序并将其URL用作 endpoints 就足够了 . 但管理员目录推送通知的事情是它的数据有效负载驻留在无法从GAS Web App访问的自定义HTTP标头中 . (这也适用于其他API的推送通知,包括Drive和Calendar API)

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


    EDIT

    在给出了一些想法,并审查了您的要求之后,我相信有一种方法可以通过使用GAS实现这一目标 .

    您可以通过setting the event parameter when initializing the watch为每个用户/域的特定事件(用例中的'update'事件)设置唯一的推送通知通道 . 因此,只有在发生更新事件时才会触发GAS Web应用程序;你真的不需要依赖HTTP头来确定事件类型 .

    如果要跟踪多个事件,只需为每个事件创建一个唯一的通道,并为每个事件使用相同的GAS Web应用程序 endpoints . 您可以通过检查POST请求中发送的事件参数来区分事件 . 这将消除对Heroku或Google Cloud Functions等中间人服务的需求 .

相关问题