请注意,我是初学者,我正在尽最大努力学习。
我有一个使用 Node JS 运行的 Discord Bot,但每 7 天我必须刷新 Google Sheets API 的令牌。我已在线阅读文档,说明服务帐户可以解决此问题,并且我尝试阅读此处和其他地方的帖子来更改我的代码以与服务帐户一起使用,但到目前为止我所尝试的一切都不起作用。
我当前的代码(如果您认为我遗漏了某些内容,请告诉我)是:
const fs = require("fs");
const path = require("path");
const {authenticate} = require('@google-cloud/local-auth');
const {google} = require('googleapis');
const {sheet} = require("../config.json")
const app = require('../app.js')
const SCOPES = ['https://www.googleapis.com/auth/spreadsheets'];
const TOKEN_PATH = path.join(process.cwd(), 'token.json');
const CREDENTIALS_PATH = path.join(process.cwd(), 'credentials.json');
let gclient = undefined
exports.initialize = authorize
async function loadSavedCredentialsIfExist() {
try {
const content = await fs.readFileSync(TOKEN_PATH);
const credentials = JSON.parse(content);
return google.auth.fromJSON(credentials);
} catch (err) {
return null;
}
}
async function saveCredentials(client) {
const content = await fs.readFileSync(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.writeFileSync(TOKEN_PATH, payload);
}
async function authorize() {
let client = await loadSavedCredentialsIfExist();
if (client) {
gclient = client
return
}
client = await authenticate({
scopes: SCOPES,
keyfilePath: CREDENTIALS_PATH,
});
if (client.credentials) {
await saveCredentials(client);
}
console.log("Authenticated and authorized successfully!")
gclient = client
}
我查看了文档并尝试调整我的代码,但我自己没能解决这个问题。任何帮助将不胜感激!
我认为这里的方法就像你提到的那样,生成一个不会过期的服务帐户
https://console.cloud.google.com/apis/credentials?project=yourproject
然后生成一个新的服务帐户,该帐户将允许您下载以下形式的 .json 文件:
{
"type": "service_account",
"project_id": "project-id-here",
"private_key_id": "privatekeyid",
"private_key": "-----BEGIN PRIVATE KEY-----\nxxxxx PRIVATE KEY-----\n",
"client_email": "[email protected]",
"client_id": "clientid",
"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/your-rpojectserviceaccount.iam.gserviceaccount.com",
"universe_domain": "googleapis.com"
}
然后您可以使用这样的代码来读取一些信息:
const { google } = require('googleapis');
const { auth } = require('google-auth-library');
async function readColumnFromSpreadsheet(spreadsheetId, range) {
// Load client secrets from a local file
const client = auth.fromJSON(require('./service-account-apis-google.json'));
console.log(client, 'client')
client.scopes = ['https://www.googleapis.com/auth/spreadsheets.readonly'];
const sheets = google.sheets({ version: 'v4', auth: client });
try {
// console.log(process.env.SPREADSHEET_ID, 'spreadsheetid')
// console.log(sheets.spreadsheets, 'spreadsheets')
const response = await sheets.spreadsheets.values.get({
spreadsheetId: SPREADSHEET_ID,
range: range,
});
const rows = response.data.values;
if (rows.length === 0) {
console.log('No data found.');
} else {
// Process the rows
rows.forEach((row) => {
console.log(row.join(', '));
});
}
} catch (err) {
console.error('The API returned an error: ' + err);
}
}
// Use the function
const spreadsheetId = 'YOUR_SPREADSHEET_ID'; // replace with your Spreadsheet ID
const range = 'B2:B';
readColumnFromSpreadsheet(spreadsheetId, range);
注意:请记住在主 Gmail 帐户文件所有者(如果我们谈论的是电子表格)上与上面的客户电子邮件(自动生成)“共享”,因此为该资源授予正确的权限,然后它应该按预期工作