google-apps-scriptgoogle-admin-sdkgoogle-data-api

How to execute Data Transfer API?


I have few accounts where I need to transfer the ownership to another account. I have the list listed in google sheets with all the email addresses. I am using the code below to hopefully execute it but I am not sure what to use to execute the code.

function dataTransfer() {
      var ss = SpreadsheetApp.openById("SHEETID")
      var sheet = ss.getSheetByName("SHEETNAME");
      var start = 2;
      var end = sheet.getLastRow();
      
      var range = sheet.getRange(start,1,end,sheet.getLastColumn());
      var values = range.getValues();
      
      for (var i = 0; i < values.length-1; i++) {
        
        /* transfer the data ownership to */
        var A = "aUser@company1.com";
        var B = "bUser@company1.com";
        var C = "cUser@company1.com";
       
        var email = values[i][0];
        var company = values[i][1];
        var status = values[i][3];
        
        if (status === "Complete") {continue;}
        
        if (company == "A") {
            /* transfer of the ownership of user data between users. */
          var transferObject = {
            "kind": "admin#datatransfer#DataTransfer",
            "oldOwnerUserId": email,
            "newOwnerUserId": A,
            "applicationDataTransfers": [
              {
                "applicationId": XXXXXX,
                "applicationTransferParams": [{
                  "key": "PRIVACY_LEVEL",
                  "value": [
                    "PRIVATE",
                    "SHARED"
                  ]
                }],     
              "applicationId": XXXXX,
                "applicationTransferParams": [{
                  "key": "RELEASE_RESOURCES",
                  "value": true
                }],
              }],
          }
          **admin.datatransfer....** /* what do I use here to execute the above code */
          sheet.getRange(start+i,4,1,1).setValue("Complete");      
        }
    }
  }
}

Solution

  • Answer:

    Using UrlFetchApp you need to make a POST request to https://admin.googleapis.com/admin/datatransfer/v1/transfers. You have to set up a GCP Project and enable the Data Transfer API to do this.

    More Information:

    The prerequisites for using the Data Transfer API, as per this page state (emphasis my own):

    You need the following basic configuration before you can use the Data Transfer API:

    • Have a Google account and create an administrator. The API applies to Google Workspace, Education, Government, Reseller, and ISP accounts.
    • Be familiar with your Google Workspace Admin console found at admin.google.com. For more information about the Admin console, see Use your Admin console.
    • Enable API access from the Google Workspace Admin console in order to make requests to the Data Transfer API.

    You can do this by going to console.cloud.google.com and creating a new project from the drop-down menu next to Google Cloud Platform on the upper menu bar.

    Then, using the hamburger menu follow ≡ > APIs & Services > Library and search for Admin SDK API. Click on the matching result, and on the new page click the ENABLE button.

    Next, you will need to link this GCP Project to your Apps Script Project.

    Going back to the Hamburger menu, follow ≡ > Home > Dashboard and copy the 12-digit project number displayed in under the Project info area.

    Going back to your Script, follow the Resources > Cloud Platform project... menu item, paste in that 12-digit number and click Set Project. This will link your Apps Script Project to the newly created GCP project wit the enabled API.

    You can safely close this modal now.

    As per the documentation on the transfers.insert method:

    Inserts a data transfer request.

    HTTP request

    POST https://admin.googleapis.com/admin/datatransfer/v1/transfers

    Request body

    The request body contains an instance of DataTransfer.

    Code:

    Firstly, as a quick code fix, the applicationDataTransfers/applicationTransferParams/value needs to be an array of strings, and so should be:

    "applicationId": XXXXX,
      "applicationTransferParams": [
        {
          "key": "RELEASE_RESOURCES",
          "value": [
            "TRUE"
          ]
        }
      ],
    // ...
    

    As well as this, the oldOwnerUserId and newOwnerUserId values must be the user ID values obtained from the users.list endpoint. The Google email address does not work as a replacement for this. A full example request would be as follows:

    var payload = {
      "kind": "admin#datatransfer#DataTransfer",
      "oldOwnerUserId": "113412843513541354193",
      "newOwnerUserId": "118387348413214353832",
      "applicationDataTransfers": [
        {
          "applicationId": "14186345432",
          "applicationTransferParams": [
            {
              "key": "PRIVACY_LEVEL",
              "value": [
                "PRIVATE",
                "SHARED"
              ]
            }
          ]
        },
        {
          "applicationId": "546343454353",
          "applicationTransferParams": [
            {
              "key": "RELEASE_RESOURCES",
              "value": [
                "TRUE"
              ]
            }
          ]
        }
      ]
    }
    

    As for making the HTTP request:

    const url = "https://admin.googleapis.com/admin/datatransfer/v1/transfers"; 
      
    var headers ={
      "Authorization": 'Bearer ' + ScriptApp.getOAuthToken(),
    };
        
    var options = {
      "method": "POST",
      "headers": headers,
      "contentType": "application/json",
      "payload": JSON.stringify(payload)
    };    
    

    Important Note: As you are using the API directly with the Script's token as your OAuth Token, you will need to update the Apps Script manifest with your required scopes.

    Follow the View > Show manifest file menu item, and add your scopes to the project. The full manifest file should look something like this:

    {
      "timeZone": "Europe/Paris",
      "dependencies": {
      },
      "exceptionLogging": "STACKDRIVER",
      "runtimeVersion": "V8",
      "oauthScopes": [
        "https://www.googleapis.com/auth/script.external_request",
        "https://www.googleapis.com/auth/admin.datatransfer"
      ]
    }
    

    The script.external_request is required so you can call UrlFetchApp, and the admin.datatransfer is the scope required to make the call to the directory insert endpoint.

    References: