The main issue you are having is that you are using JavaScript. Client side JavaScript does not have the ability to store login information for future use. Which means that every time your users return they will need to login and authorize your application again.
I would suggest that you switch to a server sided language which will allow your users to login and for you to store a refresh token for them enabling you to request a new access token when ever you need to. node.js for example would work as well.
Remember though only users who have admin access on your workspace account are going to be able to do this the user will need to have access
Node.js Quickstart
The following is a quick example for node.js, its for an installed app but will show you how things need to be put together for refreshing your access token.
// npm install googleapis@105 @google-cloud/[email protected] --save
// npm install googleapis
const fs = require('fs');
const path = require('path');
const process = require('process');
const {authenticate} = require('@google-cloud/local-auth');
const {google} = require('googleapis');
// If modifying these scopes, delete token.json.
const SCOPES = ['https://www.googleapis.com/auth/admin.directory.user.readonly'];
// Token File Name
const TOKEN_FILE = 'token.json'
// The file token.json stores the user's access and refresh tokens, and is
// created automatically when the authorization flow completes for the first
// time.
const TOKEN_PATH = path.join(process.cwd(), TOKEN_FILE);
const CREDENTIALS_PATH = 'C:\\Development\\FreeLance\\GoogleSamples\\Credentials\\Workspace-Installed-TestEverything.json';
// the workspace customer id found in admin on Google Workspace
const WORKSPACE_CUSTOMER_ID = '[REDACTED]'
/**
* Reads previously authorized credentials from the save file.
*
* @return {Promise<OAuth2Client|null>}
*/
async function loadSavedCredentialsIfExist() {
try {
const content = fs.readFileSync(TOKEN_PATH,{encoding:'utf8', flag:'r'});
const credentials = JSON.parse(content);
return google.auth.fromJSON(credentials);
} catch (err) {
return null;
}
}
/**
* Serializes credentials to a file compatible with GoogleAUth.fromJSON.
*
* @param {OAuth2Client} client
* @return {Promise<void>}
*/
async function saveCredentials(client) {
const content = fs.readFileSync(CREDENTIALS_PATH, {encoding:'utf8', flag:'r'});
const keys = JSON.parse(content);
const key = keys.installed || keys.web;
const payload = JSON.stringify({
type: 'authorized_user',
client_id: key.client_id,
client_secret: key.client_secret,
refresh_token: client.credentials.refresh_token,
});
await fs.writeFileSync(TOKEN_PATH, payload);
}
/**
* Load or request or authorization to call APIs.
*
*/
async function authorize() {
let client = await loadSavedCredentialsIfExist();
if (client) {
return client;
}
client = await authenticate({
scopes: SCOPES,
keyfilePath: CREDENTIALS_PATH,
});
if (client.credentials) {
await saveCredentials(client);
}
return client;
}
/**
* Lists the names and IDs of up to ten users on Google Workspace.
* @param {OAuth2Client} authClient An authorized OAuth2 client.
*/
async function listUsers(authClient) {
const service = google.admin({version: 'directory_v1', auth: authClient});
const res = await service.users.list({
customer: WORKSPACE_CUSTOMER_ID,
pageSize: 10,
fields: 'nextPageToken, users(id, name)',
});
const users = res.data.users;
if (users.length === 0) {
console.log('No users found.');
return;
}
console.log('users:');
users.map((user) => {
console.log(`${user.name.fullName} (${user.id})`);
});
}
authorize().then(listUsers).catch(console.error);
Google workspace
In google workspace under the user, You can check if they have admin access.
Google API to list users in directory
Lessons learned using the Google Directory API Ruby client (x post from /r/google)
Perl for Google Admin SDK Directory API?
How much to use Google Maps API (specifically the "Places (new)" API) to populate my directory?
Use the pricing calculator. https://mapsplatform.google.com/pricing/
You will have to build your caching layer, and can use whatever backend you like, including MongoDB or Redis. Don’t forget to expire cache entries so that you periodically fetch updated data.
More on reddit.com