是否可以从 Google App Maker/Google Apps Script 观看 Directory API 更改? [英] Is it possible to watch Directory API changes from Google App Maker/Google Apps Script?

查看:27
本文介绍了是否可以从 Google App Maker/Google Apps Script 观看 Directory API 更改?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在 Google 应用制作工具中开发一个性能评估应用.我们当前工具面临的挑战之一是,当一个人的经理发生变化或一个人更名时,它不会与我们的 G Suite 目录同步——他们现有的评估与该人的旧姓名相关联,我们有手动更改.

在我的新应用中,我有一个员工数据源,其中包含与最初通过目录 API 填充的评估本身的关系.阅读文档这里,似乎我应该能够在用户资源上设置监视以查找用户更新并解析它们以在我的员工数据源中进行适当的名称和经理更改.但是,我无法弄清楚观看请求的接收 URL 应该是什么.

如果有人在 Google 应用制作工具中成功地完成了这项工作,甚至仅在 Google Apps 脚本中完成了这项工作,我很想知道您是如何做到的.

编辑添加:

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

function setUserWatch() {var optionalArgs = {事件":更新"};变量资源 = {"id": "10ff4786-4363-4681-abc8-28166022425b","type": "web_hook",地址":https://script.google.com/a/.../...hXlw/exec"};AdminDirectory.Users.watch(资源);}

地址是当前的网络应用 URL.

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

解决方案

这是一个更全面的答案.

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

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

<小时>

第 1 步 - 将独立脚本部署为 Web 应用

让我们从以下模板脚本开始,然后从 Apps Script Editor 菜单将其部署为 Web App Publish >部署为 Web 应用:

/** HTTP GET 请求处理程序 */函数 doGet(e) {return ContentService.createTextOutput("GET 消息");}/** HTTP POST 请求处理程序 */函数 doPost(e) {return ContentService.createTextOutput("POST 消息");}

<小时>

第 2 步 - 验证/验证域所有权并添加/注册域

<块引用>

注意:自 2019 年 8 月起,无法再使用此方法验证 GAS Web App URL.Google Cloud Functions 可能是可行的替代.

部署网络应用程序后,您现在必须验证并注册接收网址的域,在本例中也是网络应用程序网址.此网址采用以下形式:

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

从技术上讲,您不能拥有 GAS 网络应用程序 url 的域.幸运的是,Google 的 App Script Gods 确实提供了一种机制来验证和注册 GAS 网络应用网址.

从 Apps 脚本编辑器菜单中选择 Publish >在 Chrome 网上应用店注册.向 Chrome 网上应用店注册已发布的网络应用程序也会验证 URL 的域(无需摆弄搜索控制台).

验证后,您需要通过域验证页面添加域"API 控制台.域"是 url 中不包含exec"的所有内容,因此您将添加一个如下所示的字符串:

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

<小时>

第 3 步 - 提出观看请求

对于此步骤,应为您的应用脚本项目和 API 控制台启用 AdminSDK/Directory API 服务.

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

function startUpdateWatch() {var channel = AdminDirectory.newChannel(),receiveURL = "https://script.google.com/macros/s/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx/exec",gSuiteDomain = "[企业名称].com",事件=更新";channel.id = Utilities.getUuid();channel.type = "web_hook";channel.address = receivedURL + "?domain=" + gSuiteDomain + "&event=" + event;channel.expiration = Date.now() + 21600000;//未来最多 6 小时;注意:手表必须在到期前续订才能继续发送通知AdminDirectory.Users.watch(渠道,{域":gSuiteDomain,事件":事件});}

请注意,Directory API 推送通知有一个过期时间,最长为 6 小时,从开始观看开始,因此必须定期更新,以确保将通知发送到端点 URL.通常,您可以使用基于时间的触发器每 5 小时左右调用一次此函数.

<小时>

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

与其他 API 的推送机制不同,Directory API 会随通知一起发送 POST 正文,因此保证在发送通知时会触发 doPost(e) 方法.定制 doPost(e) 触发器以处理传入事件并重新部署网络应用:

function doPost(e) {开关(e.parameter.event){案例更新"://做更新的东西休息;案例添加":休息;案例删除":休息;}return ContentService.createTextOutput("POST 消息");}

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

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

I'm working on an performance evaluation app in Google App Maker. One of the challenges we have with our current tool is that it doesn't sync with our G Suite directory when a person's manager changes or when a person has a name change -- their existing evaluations are linked to the person's old name and we have to change manually.

In my new app, I have an Employees datasource that includes a relation to the evaluation itself that was initially populated via the Directory API. Reading the documentation here, it seems as though I should be able to set up a watch on the Users resource to look for user updates and parse through them to make the appropriate name and manager changes in my Employees datasource. What I can't figure out, though, is what the receiving URL should be for the watch request.

If anyone has done this successfully within Google App Maker, or even solely within a Google Apps Script, I'd love to know how you did it.

EDITED TO ADD:

I created a silly little GAS test function to see if I can get @dimu-designs solution below to work. Unfortunately, I just get a Bad Request error. Here's what I have:

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 is the current web app URL.

EDITED TO ADD MORE: The (in)ability to use GAS to receive web hooks has been an active issue/feature request since Sep 2014 -- https://issuetracker.google.com/issues/36761910 -- which has been @dimu-designs on top of for some time.

解决方案

This is a more comprehensive answer.

Google supports push notifications across many of their APIs. However there are many subtle (and not so subtle) differences between them. Some that leverage webhooks send their data payloads primarily as HTTP headers; for example Drive API and Calendar API. Others mix their payloads across HTTP headers and a POST body(ex: AdminDirectory API). And its gets even crazier, with some APIs utilizing different mechanisms altogether (ex: GMail API leverages Cloud PubSub).

There are nuances to each but your goal is to leverage AdminDirectory push notifications in a GAS app. To do that you need a GAS Web App whose URL can serve as a web-hook endpoint.


STEP 1 - Deploy A Stand-Alone Script As A Web App

Let's start with the following template script and deploy it as a Web App from the Apps Script Editor menu Publish > Deploy As Web App:

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

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


STEP 2 - Verify/Validate Domain Ownership And Add/Register Domain

NOTE: As of August 2019, GAS Web App URLs can no longer be verified using this method. Google Cloud Functions may be a viable alternative.

With the web app deployed you now have to verify and register the domain of the receiving url, which in this case is also the web app url. This url takes the following form:

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

Technically you cannot own a GAS web app url's domain. Thankfully the App Script Gods at Google do provide a mechanism to verify and register a GAS web app url.

From the Apps Script Editor menu select Publish > Register in Chrome Web Store. Registering a published web app with the Chrome Web Store also validates the URL's domain (no need to fiddle with the search console).

Once validated you need to add the "domain" via the Domain verification page in the API Console. The "domain" is everything in the url sans the 'exec', so you'll add a string that looks like this:

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


STEP 3 - Make a watch request

For this step the AdminSDK/Directory API service should be enabled both for your App Script project and in the API Console.

Create a function that generates a watch request (this can be retooled for other event types):

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

Note that Directory API push notifications have an expiration, the max being 6 hours from starting the watch so it must be renewed periodically to ensure notifications are sent to the endpoint URL. Typically you can use a time-based trigger to call this function every 5 hours or so.


STEP 4 - Update doPost(e) trigger to handle incoming notifications

Unlike the push mechanisms of other APIs, the Directory API sends a POST body along with its notifications, so the doPost(e) method is guaranteed to be triggered when a notification is sent. Tailor the doPost(e) trigger to handle incoming events and re-deploy the web app:

function doPost(e) {

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

        case "add":
            break;

        case "delete":
            break;
    }

    return ContentService.createTextOutput("POST message");

}

There is one caveat to keep in mind. Push notifications for update events only tell you that the user's data was updated, it won't tell you exactly what was changed. But that's a problem for another question.

Note that there are a ton of details I left out but this should be enough to get you up and running.

这篇关于是否可以从 Google App Maker/Google Apps Script 观看 Directory API 更改?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆