Я хотел бы получить значения из электронной таблицы Google, используя REST API Google Sheets (googleapis) с функциями, вызываемыми Firebase.Я нашел пример , но хочу переписать его с помощью Promises. Не могли бы вы помочь мне понять, что не так с этим кодом, или, возможно, возможно ли получить новый токен доступа (или токен обновления) без использования библиотеки ReadLine?Извините за мой грязный код, я хотел войти все шаги, чтобы найти проблему ...
На основе примера: https://developers.google.com/gmail/api/quickstart/nodejs
'use strict'
const functions = require('firebase-functions'); //MUST BE HERE!
const fs = require('fs');
const readline = require('readline');
const { google } = require('googleapis');
const SCOPES = require("./functions/gapi-auth2/SCOPES.js");
//Go to the Google CLoud Dashboard: APIs and Services/ Credentials panel:
//https://console.cloud.google.com/apis/credentials
//OAuth2 Client Credentials (Other):
const KEY_PATH = "functions/credentials/oauth2.key.json"; // pathToKey
/**
* Read content of the oauth2.key.json key file
* @param {String} pathToKey The path to oauth2.key.json file.
*/
function readContentOfKeyFile(pathToKey) {
console.log("Inside readContentOfKeyFile() -------------------------- pathToKey: \n");
console.log(pathToKey);
return new Promise((resolve, reject) => {
console.log("Before readFile --------------------");
// Load client secrets from a local file.
fs.readFile(pathToKey, (err, content) => {
console.log("Inside readFile() --------------------");
if (err) {
console.log('Error loading client secret file:', err);
reject(err)
}
console.log("End of readContentOfKeyFile() --------------------");
console.log(JSON.parse(content));
resolve(JSON.parse(content));
});
})
}
/**
* Create an OAuth2 client with the given credentials
* @param {Object} credentials The authorization client credentials.
*/
function getOAuth2Client(credentials) {
console.log("Inside getOAuth2Client() --------------------------");
const { client_secret, client_id, redirect_uris } = credentials.installed;
console.log("After credentials.installed, returns oAuth2Client --------------------------");
//return oAuth2Client:
return new google.auth.OAuth2(
client_id,
client_secret,
redirect_uris[0]
);
}
/**
* Store token to disk be used in later program executions.
*
* @param {Object} token The token to store to disk.
*/
function storeToken(token) {
fs.writeFile(TOKEN_PATH, JSON.stringify(token), (err) => {
if (err) return console.warn(`Token not stored to ${TOKEN_PATH}`, err);
console.log(`Token stored to ${TOKEN_PATH}`);
});
}
function getNewToken(oauth2Client, callback) {
const authUrl = oauth2Client.generateAuthUrl({
access_type: 'offline',
scope: SCOPES,
});
console.log('Authorize this app by visiting this url:', authUrl);
function askCode() {
console.log("Inside askCode()----------------------------------")
return new Promise((resolve) => {
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout,
});
console.log("After readline.createInterface() ----------------------------------")
rl.question('Enter the code from that page here: ', (code) => {
rl.close();
console.log(code);
console.log("----------------------------------------------")
resolve(code)
})
})
}
askCode().then(code => {
oauth2Client.getToken(code, (err, token) => {
return new Promise((resolve, reject) => {
if (err) {
console.error('Error retrieving access token', err);
reject(err);
}
oauth2Client.credentials = token;
storeToken(token);
onsole.error("After storeToken()-------------------");
resolve(oauth2Client);
})
});
})
}
/**
* Get and store new token after prompting for user authorization
* @param {google.auth.OAuth2} oAuth2Client The OAuth2 client to get token for.
*/
function getNewToken(oAuth2Client, tokenFile) {
console.log("Inside getNewToken() --------------------------");
return new Promise((resolve, reject) => {
const authUrl = oAuth2Client.generateAuthUrl({
access_type: 'offline', // 'online' (default) or 'offline' (gets refresh_token)
scope: SCOPES,
});
console.log('Authorize this app by visiting this url:', authUrl);
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout,
});
console.log("readLine interface.........................."); //LAST RECORD IN THE LOG
try {
rl.question('Enter the code from that page here: ', (code) => {
rl.close();
console.log("rl.question: get code " + code);
oAuth2Client.getToken(code, (err, token) => {
if (err) {
console.error('Error retrieving access token', err);
reject(err);
}
console.error('token:' + token);
oAuth2Client.credentials = token; //oAuth2Client.setCredentials(token);
// Store the token to disk for later program executions
storeToken(token);
console.error("[END] of getNewToken()");
resolve(oAuth2Client);
});
});
} catch (err) {
console.log("Error in the readLine......");
console.error(err);
reject(err);
};
})
}
// 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 = 'token.json';
function authorize(client, tokenFile) {
console.log("Inside authorize() --------------------------");
return new Promise((resolve, reject) => {
// Check if we have previously stored a token.
fs.readFile(tokenFile, (err, token) => {
if (err) {
console.log("Error reading a file: " + err);
try {
resolve(getNewToken(client, tokenFile));
} catch (err) {
reject(err)
}
} else {
console.log("set Credentials from a file--------------------")
client.credentials = token; //client.setCredentials(JSON.parse(token));
resolve(client)
}
});
})
}
function getSpreadsheetData(auth) {
console.log("Inside getSpreadsheetData--------------------------");
return new Promise((resolve, reject) => {
const sheets = google.sheets({ version: 'v4' });
const request = {
auth: auth,
spreadsheetId: 'xxxx-xxxx-xxx',
range: "Checklist!B:L",
}
console.log("****************************************************************************");
console.log("***** getSpreadsheetData, request:------------------------------------------------");
console.log(JSON.stringify(request));
console.log("****************************************************************************");
sheets.spreadsheets.values.get(request, (err, response) => {
//console.log("inside: sheets.spreadsheets.values.get() -------------------------------");
if (err) {
console.log('The Sheets API returned an error: ' + err);
//The API returned an error: Error: API key not valid. Please pass a valid API key.
reject(err);
};
try {
var numRows = response.data.values ? response.data.values.length : 0;
console.log('%d rows retrieved.', numRows);
console.log("response.data:-------------------------------");
console.log(response.data.values);
resolve(response.data.values);
} catch (err) {
console.log("Error processing Sheets API response: " + err);
reject(err);
}
})
})
}
//https://firebase.google.com/docs/functions/callable
exports.getControlSheetData = functions.https.onCall((data, context) => {
console.log("getControlSheetData()---------------------------");
if (!context.auth) {
throw new functions.https.HttpsError('failed-precondition', 'The function must be called ' + 'while authenticated.');
} else {
const uid = context.auth.uid;
console.log("context.auth.uid: " + uid);
const email = context.auth.token.email || null;
console.log("--- * * * * * * * * * * * * * * * * * * ---");
console.log("context.auth.token.email: ", email);
console.log("--- * * * * * * * * * * * * * * * * * * ---");
readContentOfKeyFile(KEY_PATH).then(credentials => {
console.log("Result of readContentOfKeyFile() --------------------------");
let oAuth2Client = getOAuth2Client(credentials);
console.log("oAuth2Client has been created -----------------------");
authorize(oAuth2Client, TOKEN_PATH).then(auth => {
console.log("result of authorize(): " + JSON.stringify(auth));
return getSpreadsheetData(auth); //<------------ Requested Spreadsheet's Data
}).catch(err => {
console.log("error in authorize: " + err);
})
})
}
})