Accès d'une Googlesheet avec Node.js

Le problème exposé dans ce sujet a été résolu.

****Encore bonjour a vous tous,

J’expérimente l’utilisation d’une app Node.js qui pourrais accéder a un fichier Google worksheet en utilisant us Service account.

J’ai suivi …. je pense…les directives données par: https://developers.google.com/sheets/api/quickstart/nodejs?hl=fr

Lorsque j’exécute… grelot:test $ node .

L’erreur suivante se présente: TypeError: Cannot read properties of undefined (reading 'redirect_uris’) at authenticate (/home/grelot/node_modules/@google-cloud/local-auth/build/src/index.js:50:15) at authorize (/home/grelot/Dropbox/Serge/Programmation/js-node/test/index.js:58:18)

La routine local-auth de googleapis@105 @google-cloud/local-auth@2.1.0 appelée par async function authorize() semble chercher 'redirect_uris’ , probablement dans le fichier credentials.json.

Après recherche Gooogle et avoir trouvé https://stackoverflow.com/questions/61912639/typeerror-cannot-read-property-redirect-uris-of-undefined

J’ai essayé d’ajouter "redirect_uris": "http://localhost:3000/oauth2callback", mais la même erreur persiste.

Ou dois-je chercher?

Merci de votre temps.

Serge

+0 -0

Voici pour le code qui est une cc de https://developers.google.com/sheets/api/quickstart/nodejs?hl=fr

=====================================================================
index.js
=====================================================================
const fs = require('fs').promises;
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/spreadsheets.readonly'];
// 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.json');
const CREDENTIALS_PATH = path.join(process.cwd(), 'credentials.json');

/**
 * Reads previously authorized credentials from the save file.
 *
 * @return {Promise<OAuth2Client|null>}
 */
async function loadSavedCredentialsIfExist() {
  try {
    const content = await fs.readFile(TOKEN_PATH);
    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 = await fs.readFile(CREDENTIALS_PATH);
  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.writeFile(TOKEN_PATH, payload);
}
/**
 * Load or request or authorization to call APIs.
 *
 */
async function authorize() {
   
  let client = await loadSavedCredentialsIfExist();
  if (client) {
    return client;
  }

  console.log("Authenticate running...",SCOPES);
  console.log("Authenticate running...",CREDENTIALS_PATH);

  client = await authenticate({
    scopes: SCOPES,
    keyfilePath: CREDENTIALS_PATH,
  });

  


  if (client.credentials) {
    await saveCredentials(client);
  }
  return client;
}

/**
 * Prints the names and majors of students in a sample spreadsheet:
 * @see https://docs.google.com/spreadsheets/d/1BxiMVs0XRA5nFMdKvBdBZjgmUUqptlbs74OgvE2upms/edit
 * @param {google.auth.OAuth2} auth The authenticated Google OAuth client.
 */
async function listMajors(auth) {
  const sheets = google.sheets({version: 'v4', auth});
  const res = await sheets.spreadsheets.values.get({
    spreadsheetId: '1BxiMVs0XRA5nFMdKvBdBZjgmUUqptlbs74OgvE2upms',
    range: 'Class Data!A2:E',
  });
  const rows = res.data.values;
  if (!rows || rows.length === 0) {
    console.log('No data found.');
    return;
  }
  console.log('Name, Major:');
  rows.forEach((row) => {
    // Print columns A and E, which correspond to indices 0 and 4.
    console.log(`${row[0]}, ${row[4]}`);
  });
}

authorize().then(listMajors).catch(console.error);

=====================================================================
credential.json
=====================================================================
{
  "type": "service_account",
  "project_id": "##############",
  "private_key_id": "###############",
  "private_key": "-----BEGIN PRIVATE KEY-----\n#############==\n-----END PRIVATE KEY-----\n",
  "client_email": "##########.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:###########.iam.gserviceaccount.com",
  "universe_domain": "googleapis.com"
}



Après recherche Gooogle et avoir trouvé https://stackoverflow.com/questions/61912639/typeerror-cannot-read-property-redirect-uris-of-undefined

dubser

La première réponse te suggère d’utiliser google.auth.GoogleAuth plutôt que authenticate, est-ce que tu as essayé cela ? C’est par ailleurs déjà ce que je te suggerrais dans ce post. À mon avis, tu peux entièrement te passer de @google-cloud/local-auth.

Cette demo tirée de… https://developers.google.com/sheets/api/quickstart/nodejs?hl=fr Les instructions données dans cette page de Google Workspace doivent être suivies intégralement à l’exception du code de sheets/quickstart/index.js que j’ai remplacé par le code ci joint qui est fonctionnel et testé pour lire les données d’une feuille de calcul qui est un example supporté par Google. Les credentials sont entreposés dans le fichier credentials.json dans le même répertoire que index.js. Merci à olybri pour son support.

const fs = require('fs').promises;
const {google} = require('googleapis');
//============================================
async function readCred() {
  const filePath = 'credentials.json';
  try {
    // Lire le fichier en utilisant fs.readFile
    const content = await fs.readFile(filePath, 'utf8');
    dataJson = JSON.parse(content);
    //console.log("Json data =====>",dataJson);
    return dataJson;
  } catch (error) {
    console.error('Erreur lors de la lecture du fichier :', error.message);
  }
}
//============================================
// Préparer l'objet auth pour authentifier la lecture.
function setAuth(dataJson) {
const auth = new google.auth.GoogleAuth({
  credentials: {
      private_key:dataJson.private_key ,
      client_email: dataJson.client_email,
  },
  scopes: ['https://www.googleapis.com/auth/spreadsheets.readonly'], // Add the required scopes for your use case
});
return auth;
}
//============================================
// Lire les données du fichier spreadsheetId
async function getData(auth) {
console.log("GetData running ");
//Créer une instance du service Sheets
const sheets = google.sheets({ version: 'v4', auth });
//console.log("Sheets ",sheets);
const spreadsheetId = '1BxiMVs0XRA5nFMdKvBdBZjgmUUqptlbs74OgvE2upms';
const range = 'Class Data!A2:E'; 
try {
  const res = await sheets.spreadsheets.values.get({
    spreadsheetId,
    range,
  });
  const rows = res.data.values;

  if (rows.length) {
    console.log('Données lues avec succès :');
    rows.forEach((row) => {
      console.log(row);
    });
  } else {
    console.log('Aucune donnée trouvée.');
  }
} catch (err) {
  console.error('Erreur lors de la lecture des données :', err);
}
}
//============================================
// Exécute chaque fonction et attendant qu'elle se termine ;
async function executeAll() {
  try {
    const dataJson = await readCred()
    const auth1=setAuth(dataJson)
    await getData(auth1);

    console.log('Toutes les opérations sont terminées.');
    console.log('===========================================================');
  } catch (error) {
    console.error('Erreur lors de l’exécution séquentielle :', error.message);
  }
}
// Appel de la fonction principale
executeAll();

Salut Serge Il semble que le problème vienne de ton fichier credentials.json. Vérifie qu’il contient bien les informations nécessaires, notamment le champ redirect_uris. Si tu utilises un compte de service, tu n’as normalement pas besoin de redirect_uris, donc assure-toi d’utiliser les bonnes informations pour l’authentification. Vérifie aussi que le fichier est bien au bon emplacement et que le code pointe vers le bon chemin.

Connectez-vous pour pouvoir poster un message.
Connexion

Pas encore membre ?

Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte