google-apps-scriptgoogle-cloud-platformgoogle-oauthadd-ongoogle-apps-marketplace

Getting an error when trying to query the installations of add-on


Goal:

I have a public Google Workspace Marketplace editor add-on for Google Forms. I would like to query the installations and uninstallations via the Google Workspace Marketplace API within Google Apps Script.

Approach:

Script:

const serviceAccount = {
  "type": "service_account",
  "project_id": "<<MY PROJECT ID>>",
  "private_key_id": "<<MY PRIVATE KEY>>",
  "private_key": "<<MY PRIVATE KEY>>",
  "client_email": "<<MY CLIENT EMAIL>>",
  "client_id": "<<MY CLIENT ID>>",
  "auth_uri": "https://accounts.google.com/o/oauth2/auth",
  "token_uri": "https://oauth2.googleapis.com/token",
  "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
  "client_x509_cert_url": "<<MY CERT URL>>"
};

const { private_key, client_email, project_id } = serviceAccount;

const createService = (name, serviceAccount, scopes, userToImpersonate) => {
  return OAuth2.createService(name)
    .setSubject(userToImpersonate)
    .setTokenUrl('https://accounts.google.com/o/oauth2/token')
    .setPrivateKey(serviceAccount.private_key)
    .setIssuer(serviceAccount.client_email)
    .setPropertyStore(PropertiesService.getScriptProperties())
    .setCache(CacheService.getUserCache())
    .setLock(LockService.getUserLock())
    .setScope(scopes);
};

const sendRequest = (url, oauthParams) => {
  const { serviceName, serviceAccount, scopes, userToImpersonate } =
    oauthParams;

  const oauthService = createService(
    serviceName,
    serviceAccount,
    scopes,
    userToImpersonate
  );

  if (!oauthService.hasAccess()) {
    console.log('ERROR IS ' + oauthService.getLastError());
    return;
  }

  const headers = {
    Authorization: `Bearer ${oauthService.getAccessToken()}`,
  };

  const options = {
    method: 'get',
    headers,
    muteHttpExceptions: true,
  };

  return UrlFetchApp.fetch(url, options).getContentText();
};

const getLicenseNotifications = () => {
  const url = 'https://appsmarket.googleapis.com/appsmarket/v2/licenseNotification/<<MY APP ID>>?maxResults=2';
  const oauthParams = {
    serviceName: 'GWMservice',
    serviceAccount,
    scopes: ['https://www.googleapis.com/auth/appsmarketplace.license'],
    userToImpersonate: '<<MY USER>>@<<MY DOMAIN>>.com',
  };

  console.log(sendRequest(url, oauthParams));
};

Google Apps Script manifest:

{
  "timeZone": "Europe/Berlin",
  "dependencies": {
    "libraries": [
      {
        "userSymbol": "OAuth2",
        "version": "43",
        "libraryId": "1B7FSrk5Zi6L1rSxxTDgDEUsPzlukDsi4KGuTMorsTQHhGBzBkMun4iDF"
      }
    ]
  },
  "exceptionLogging": "STACKDRIVER",
  "runtimeVersion": "V8",
  "oauthScopes": [
    "https://www.googleapis.com/auth/appsmarketplace.license",
    "https://www.googleapis.com/auth/script.external_request"
  ]
}

Error:

I am receiving the following error:

{
  "error": {
    "code": 503,
    "message": "Temporary error. Please try later.",
    "errors": [
      {
        "message": "Temporary error. Please try later.",
        "domain": "global",
        "reason": "backendError"
      }
    ]
  }
}

Solution

  • Unfortunately this is a case of the documentation being wrong (as of April 8th, 2023). The maxResults parameter is actually expressed as max-results and the same applies to start-token. Once you change the query parameter retrieval (and pagination) should work.