无法在 App 脚本中授权 Google 数据传输 API

Cannot authorize Google Data Transfer API in App Script

我有一个使用 Google's OAuth2 library to perform a variety of functions on a G suite domain. I wanted to add the ability to transfer user data using the Transfer API 的 Appscript 应用程序,但我无法授权该服务。我在授权 gmail、驱动器和目录 API 时没有遇到任何问题,并且我确保该服务在 GCP 项目中已启用。但是,我无法让我的 OAuth2 服务获得授权,每次我都会收到一条记录消息,指出我的服务帐户未获得授权。这里缺少什么?

这是我的代码:

const migrationScope = ['https://www.googleapis.com/auth/admin.datatransfer'];

function migrateUser(sourceUser, targetUser, type) {
  var url = 'https://www.googleapis.com/admin/datatransfer/v1/transfers';
  var service = getService_('superadmin_account@company.com', 'admin', migrationScope);
  var transferObject = {
    oldOwnerUSerId: getUserId(sourceUser), // this takes an email and returns the user ID which is required by the API
    newOwnerUserId: getUserId(targetUser),
    applicationDataTransfers: [
      {
        applicationTransferParams: [
          {
            value: type,
          }
        ],
        applicationId: 5********6 // Our App ID for Drive
      }
    ]
  }
  if (service.hasAccess()) {
    var response = UrlFetchApp.fetch(url, requestBuilder(service, transferObject, 'POST'));
    try {
      var result = JSON.parse(response.getContentText());
      return (result);
    }
    catch (e) {
      return (undefined);
    }
  } else { Logger.log("Service does not have access to migrate content."); }
}

function getService_(email, service, scopes) {
  return OAuth2.createService(service + ':' + email)
    .setTokenUrl('https://oauth2.googleapis.com/token').
    .setPrivateKey(PRIVATE_KEY)
    .setIssuer(CLIENT_EMAIL)
    .setSubject(email)
    .setPropertyStore(PropertiesService.getScriptProperties())
    .setScope(scopes);
}
function requestBuilder(service, payload, method) {
  return {
    method: method,
    contentType: 'application/json',
    headers: {
      Authorization: 'Bearer ' + service.getAccessToken()
    },
    payload: JSON.stringify(payload),
    muteHttpExceptions: true
  };
}

代码本身似乎没问题,假设 requestBuilder returns UrlFetch 调用的高级参数格式正确。

考虑到您遇到的错误类型,我认为您没有在管理控制台的 域范围委派 窗格中添加范围 https://www.googleapis.com/auth/admin.datatransfer

当使用服务帐户模拟其他用户时,您需要将服务帐户应该能够访问的任何范围添加到此窗格。在 GCP 项目上启用 API 或将范围添加到同意屏幕是不够的。您也需要将它们添加到那里。

为此,请按照指定的步骤进行操作 here:

Then, a super administrator of the G Suite domain must complete the following steps:

1. From your G Suite domain’s Admin console, go to Main menu > Security > API Controls.
2. In the Domain wide delegation pane, select Manage Domain Wide Delegation.
3. Click Add new.
4. In the Client ID field, enter the service account's Client ID. You can find your service account's client ID in the Service accounts page.
5. In the OAuth scopes (comma-delimited) field, enter the list of scopes that your application should be granted access to. For example, if your application needs domain-wide full access to the Google Drive API and the Google Calendar API, enter: https://www.googleapis.com/auth/drive, https://www.googleapis.com/auth/calendar.
6. Click Authorize.

重要提示:

  • 确保服务帐户正在模拟具有适当管理员权限的用户 (.setSubject(email)) 来实际传输数据。

参考: