1

I'm trying to access some google groups from the google-api using nodeJS and a service account file. I can't find a code sample that works quite like this. I've put together some code that seems to be working, but I keep getting an error 400 - Bad Request from the API without any clues what's wrong.

Am I using the right classes? Can I use a service account here? Am I missing scopes or something?

My code:

import { Auth, google } from "googleapis";
const main = async () => {
 const auth = new Auth.GoogleAuth({
 keyFile: "/path-to-service-account-file.json",
 scopes: "https://www.googleapis.com/auth/admin.directory.group.readonly",
 });
 const client = await auth.getClient();
 // Obtain a new drive client, making sure you pass along the auth client
 const admin = google.admin({ version: 'directory_v1', auth: client });
 const groups = await admin.groups.list();
 console.log(groups.data.groups);
}
main().then(() => process.exit(0)).catch(err => {
 console.error(err);
 process.exit(1);
});

The file is (I think) a standard service account file:

{
 "type": "service_account",
 "project_id": "groupmembers-*******",
 "private_key_id": "*********",
 "private_key": ...,
 "client_email": "test-admin-nodejs@groupmembers-****.iam.gserviceaccount.com",
 "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": "https://www.googleapis.com/robot/v1/metadata/x509/test-admin-nodejs%40groupmembers-******.iam.gserviceaccount.com"
}

When I run this code, I get the following response:

 status: 400,
 statusText: 'Bad Request',
 request: {
 responseURL: 'https://admin.googleapis.com/admin/directory/v1/groups'
 }

What's interesting to me is the bearer token it generates for me. The error also prints out the request info:

config: {
 url: 'https://admin.googleapis.com/admin/directory/v1/groups',
 method: 'GET',
 userAgentDirectives: [ [Object] ],
 paramsSerializer: [Function (anonymous)],
 headers: {
 'x-goog-api-client': 'gdcl/5.1.0 gl-node/17.4.0 auth/7.14.1',
 'Accept-Encoding': 'gzip',
 'User-Agent': 'google-api-nodejs-client/5.1.0 (gzip)',
 Authorization: 'Bearer ya29.c.b0AX***********************************************jzxc........................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................',
 Accept: 'application/json'
 },

I don't know if this is normal or relevant, but I've never seen a bearer token with a bunch of dots at the end.

asked Apr 21, 2022 at 18:05

1 Answer 1

1

A 400 error is not an authorization/authentication issue, but instead is a client request issue. According to the official documentation, there are some query parameters required for the api call. One of them is the customer query parameter:

The unique ID for the customer's Google Workspace account. In case of a multi-domain account, to fetch all groups for a customer, fill this field instead of domain. As an account administrator, you can also use the my_customer alias to represent your account's customerId. The customerId is also returned as part of the Users

Based on experience, it is implied you must use this value. Although the documentation should be better and it should explicitly say this is required. So, in summary, your request should look like this:

const groups = await admin.groups.list({
 customer: "my_customer"
});
console.log(groups.data.groups);
answered Apr 22, 2022 at 8:42
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.