Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Google API for getting maximum number of licenses in a Google Apps domain

I have a Google Apps Script function used for setting up accounts for new employees in our Google Apps domain.

The first thing it does is makes calls to the Google Admin Settings API and retrieves the currentNumberOfUsers and maximumNumberOfUsers, so it can see if there are available seats (otherwise a subsequent step where the user is created using the Admin SDK Directory API would fail).

It's been working fine until recently when our domain had to migrate from Postini to Google Vault for email archiving.

Before the migration, when creating a Google Apps user using the Admin SDK Directory API, it would increment the currentNumberOfUsers by 1 and the new user account user would automatically have access to all Google Apps services.

Now after the migration, when creating a Google Apps user, they aren't automatically assigned a "license," so I modified my script to use the Enterprise License Manager API and now it assigns a "Google-Apps-For-Business" license. That works fine.

However, the currentNumberOfUsers is now different from the number of assigned licenses, and "Google-Apps-For-Business" is only one of several different types of licenses available.

I can get the current number of assigned "Google-Apps-For-Business" licenses by running this:

var currentXml = AdminLicenseManager.LicenseAssignments.listForProductAndSku('Google-Apps', 'Google-Apps-For-Business', 'domain.com', {maxResults: 1000});
    
var current = currentXml.items.toString().match(/\/sku\/Google-Apps-For-Business\/user\//g).length;

But the number that produces is different from currentNumberOfUsers.

All I really need to do now is get the maximum number of owned "Google-Apps-For-Business" licenses so the new employee setup script can determine whether there are any available.

I checked the API Reference documentation for the following APIs but...

Enterprise License Manager API → Doesn't have a method for getting the maximum or available number of licenses.

Google Admin Settings API → Doesn't deal with licenses, only "users."

Admin SDK Directory API User resource → Doesn't deal with licenses.

Google Apps Reseller API → This API seems to have what I need, but it's only for Reseller accounts.

I know I can program my new employee setup script to just have a try/catch seeing if it would be able to create the user and assign the license, and end the script execution gracefully if it can't, but that doesn't seem efficient.

Also, part of the old script was that if there were less than X seats available, it would email me a heads-up to order more. I can program a loop that attempts to repeatedly create dummy users and assign them licenses and count the number of times it can do that before it fails, then delete all the dummy users, but, once again, that's not efficient at all.

Any ideas?

Update 3/11/2020: Since the Admin Settings API had shut down a few years ago I've been using the Enterprise License Manager API to get the current number of used licenses, like this:

function getCurrentNumberOfUsedGoogleLicenses(skuId) {

  var success = false, error = null, count = 0;

  var adminEmail = '[email protected]';
  var gSuiteDomain = adminEmail.split('@')[1];

  // for more information on the domain-wide delegation:
  // https://developers.google.com/identity/protocols/OAuth2ServiceAccount#delegatingauthority
  // the getDomainWideDelegationService() function uses this: 
  // https://github.com/gsuitedevs/apps-script-oauth2
  var service = getDomainWideDelegationService('EnterpriseLicenseManager: ', 'https://www.googleapis.com/auth/apps.licensing', adminEmail);

  if (skuId == 'Google-Apps-Unlimited') var productId = 'Google-Apps';
  else                                  return { success: success, error: "Unsupported skuId", count: count };

  var requestBody                = {};
  requestBody.headers            = {'Authorization': 'Bearer ' + service.getAccessToken()};
  requestBody.method             = "GET";
  requestBody.muteHttpExceptions = false;

  var data, pageToken, pageTokenString;

  var maxAttempts     = 5;
  var currentAttempts = 0;
  var pauseBetweenAttemptsSeconds = 3;

  loopThroughPages:
  do {

    if (typeof pageToken === 'undefined') pageTokenString = "";
    else                                  pageTokenString = "&pageToken=" + encodeURIComponent(pageToken);

    var url = 'https://www.googleapis.com/apps/licensing/v1/product/' + productId + '/sku/' + skuId + '/users?maxResults=1000&customerId=' + gSuiteDomain + pageTokenString;

    try {

      currentAttempts++;

      var response = UrlFetchApp.fetch(url, requestBody);

      var result = JSON.parse(response.getContentText());

      if (result.items) {

        var licenseAssignments = result.items;
        var licenseAssignmentsString = '';

        for (var i = 0; i < licenseAssignments.length; i++) {

          licenseAssignmentsString += JSON.stringify(licenseAssignments[i]);

        }

        if (skuId == 'Google-Apps-Unlimited') count += licenseAssignmentsString.match(/\/sku\/Google-Apps-Unlimited\/user\//g).length;

        currentAttempts = 0; // reset currentAttempts before the next page

      }

    } catch(e) {

      error = "Error: " + e.message;

      if (currentAttempts >= maxAttempts) {

        error = 'Exceeded ' + maxAttempts + ' attempts to get license count: ' + error;

        break loopThroughPages;

      }

    } // end of try catch

    if (result) pageToken = result.nextPageToken;

  } while (pageToken);

  if (!error) success = true;

  return { success: success, error: error, count: count };

}

However, there still does not appear to be a way to get the maximum number available to the domain using this API.

like image 908
Employee Avatar asked Apr 30 '15 07:04

Employee


People also ask

What is the user limit of licenses purchase in business plans?

You have Business Starter, Business Standard, and Business Plus and have reached the limit of 300 users.

How many users can you have on G suite Basic?

With Basic and Business organizations can add 50 users in a call, while Enterprise can, in addition to adding 100 users, record meetings and save them to Drive. Moreover, Enterprise-users can dial-in from a phone.

Which API can you use to list create and modify Google Workspace users?

The Directory API is used to create and manage resources attached to your Google Workspace domain, such as users, org charts, and groups.


1 Answers

Use CustomerUsageReports.

jay0lee is kind enough to provide the GAM source code in Python. I crudely modified the doGetCustomerInfo() function into Apps Script thusly:

function getNumberOfLicenses() {
  var tryDate = new Date();
  var dateString = tryDate.getFullYear().toString() + "-" + (tryDate.getMonth() + 1).toString() + "-" + tryDate.getDate().toString();
  while (true) {
    try {
      var response = AdminReports.CustomerUsageReports.get(dateString,{parameters : "accounts:gsuite_basic_total_licenses,accounts:gsuite_basic_used_licenses"});
      break;
    } catch(e) {
      //Logger.log(e.warnings.toString());
      tryDate.setDate(tryDate.getDate()-1);
      dateString = tryDate.getFullYear().toString() + "-" + (tryDate.getMonth() + 1).toString() + "-" + tryDate.getDate().toString();
      continue;
    }
  };
  var availLicenseCount = response.usageReports[0].parameters[0].intValue;
  var usedLicenseCount = response.usageReports[0].parameters[1].intValue;
  Logger.log("Available licenses:" + availLicenseCount.toString());
  Logger.log("Used licenses:" + usedLicenseCount.toString());
  return availLicenseCount;
}
like image 91
browly Avatar answered Nov 06 '22 15:11

browly