node.jsgoogle-apigoogle-api-nodejs-client

Ownership transfer of Google Drive files using the node api fails with "Missing required nested field: resource"


With the Google APIs Node library, I have been trying to get the datatransfer api going, to transfer ownership of all the files and directories in Drive that a quitting volunteer might have created.

When I call the API, I get the catch exception, with the following as the important part:

  "data": {
    "error": {
      "code": 400,
      "message": "Missing required nested field: resource",
      "errors": [{
        "message": "Missing required nested field: resource",
        "domain": "global",
        "reason": "required"
      }]
    }
  },

I have no idea what "Missing required nested field: resource" means.

For the applicationId, I am using the Project Number from https://console.cloud.google.com/welcome?pli=1&invt=AbugjA&project=weconnectserverapp The new and old Owner user ids, are looked up on the fly with api calls that send the two owner's email addresses, and get back the ids. (Re-using a function that works well for other situations).

My code is:

  const auth = await getAuth();     // Get the oAuth2 object (this works fine for all my other API calls)
  const transferClient = google.admin({ version: 'datatransfer_v1', auth });
  
  const requestBody = {
    oldOwnerUserId: 107351012895020643169,
    newOwnerUserId: 116959854431469063864,
    applicationDataTransfers: [{
      applicationId: 1009999999717,
      applicationTransferParams: [
        {
          key: 'RELEASE_RESOURCES',
          value: [
            'TRUE',
          ],
        },
        {
          key: 'PRIVACY_LEVEL',
          value: [
            '{PRIVATE, SHARED}',
          ],
        },
      ],
    }],
  };

  try {
    serverResponse = await transferClient.transfers.insert(requestBody);
  } catch (e) {
    console.log('ERROR driveDriveFilesAndFoldersOwnership:', e);
  }

Any help, or a link to correct documentation would be greatly appreciated.


Solution

  • In reference to the documentation, the applicationId is the reference to Google's application Id (google drive, currents, calendar). Make sure to correct that.

    We need to make sure we understand that each application has different parameters. For Calendar the valid param is RELEASE_RESOURCES and for Drive the valid param is PRIVACY_LEVEL. It is explained in the documentation aforementioned. Therefore if you want to include both "private" and "shared" in the transfer params, each should be an item in the array.

    In regards to the main error: Missing required nested field: resource, this is an error presented because the request body is not included properly. When inspecting the required type for the insert method, it showed the following:

    Request body type

    That means that the correct way of sending the request body, should be like this:

    const requestBody = {
        oldOwnerUserId: 107351012895020643169,
        newOwnerUserId: 116959854431469063864,
        applicationDataTransfers: [{
            applicationId: 55656082996, //GOOGLE DRIVE
            applicationTransferParams: [
                {
                    key: 'PRIVACY_LEVEL',
                    value: ['PRIVATE', 'SHARED'],
                },
            ],
        }],
    };
    
    try {
        serverResponse = await transferClient.transfers.insert({requestBody: requestBody});
    } catch (e) {
        console.log('ERROR driveDriveFilesAndFoldersOwnership:', e);
    }
    

    I believe you should be able to run both Drive and Calendar data transfers at the same time, just make sure to include both transfer objects separate in the applicationDataTransfers property. Each one containing its valid applicationTransferParams as specified in the documentation.