我的Discord机器人试图访问Google Sheets API v4.0时遇到问题。我希望它能够读取、写入和更新工作表中的数据。我的代码可以很好地用于Node.js应用程序,但是当我将我的代码放在一个不一致的机器人中时,它会给我这个错误:
UnhandledPromiseRejectionWarning: Error: The request is missing a valid API key
我不明白为什么我会得到这个错误。我甚至为我的不和谐机器人创建了一个服务账户。
这是Discord机器人的代码。
require('dotenv').config();
const sheet = require('./sheet');
const { Client } = require('discord.js');
const { sheets } = require('googleapis/build/src/apis/sheets');
const client = new Client();
图纸文件编码:
const {google} = require('googleapis');
const keys = require('./keys.json');
const client = new google.auth.JWT(
keys.client_email,
keys.private_key_id,
keys.private_key,
['https://www.googleapis.com/auth/spreadsheets']
);
client.authorize(function(err,tokens){
if(err){
console.log(err);
return;
}
// else{
// console.log('Connected');
// gsrun(client);
// }
});
const getdata = async function gsrun(cl){
const gsapi = google.sheets({version:'v4',auth:cl});
const opt = {
spreadsheetId:'1LzdhD4rb2FdElTyQCAkgb5oyeGeu0d9rT2abS4n_4i8',
range: 'A2:B5'
};
let data = await gsapi.spreadsheets.values.get(opt);
console.log(data.data.values);
}
exports.getdata = getdata;
我已经给了访问机器人电子邮件id的工作表,这是discordbotapi@nodejs-api-testing-discordbot.iam.gserviceaccount.com.我还启用了Google Sheets API。我哪里出错了?
发布于 2021-02-12 10:34:36
当您在没有Discord.js的情况下在Node.js中尝试它时,您没有导出任何内容,只是在授权成功后调用gsrun(client)
,所以它工作得很好。问题是,现在您试图在没有任何授权的情况下使用getData
。尽管您的代码中有client.authorize
,但您从未使用过它。
为了解决这个问题,我将在这里创建至少两个不同的函数;一个用于生成客户端,另一个用于get请求本身并将它们导出。
要生成一个客户端,我会将其封装在一个promise中。这样以后我就可以使用async/await了。此函数将使用JWT创建客户端,执行授权,并根据client.authorize()
的结果与客户端进行解析或拒绝承诺。
function connect() {
return new Promise((resolve, reject) => {
const scope = ['https://www.googleapis.com/auth/spreadsheets'];
const { client_email, private_key, private_key_id } = keys;
const client = new google.auth.JWT(
client_email,
private_key_id,
private_key,
scope,
);
client.authorize((err) => {
if (err) {
reject(err);
} else {
resolve(client);
}
});
});
}
现在,您可以使用const client = await connect()
简单地连接和获取客户端。
第二部分是从电子表格中获取一些数据。再说一次,我会把它包装在一个承诺中。此函数将接受客户端(我们在上面刚刚创建)以及带有spreadsheetId和range的选项。在promise中,您只需使用以下选项调用API端点:
function getData(client, options) {
return new Promise((resolve, reject) => {
const endpoint = google.sheets({ version: 'v4', auth: client });
endpoint.spreadsheets.values.get(options, (err, data) => {
if (err) {
reject(err);
} else {
// or resolve with data.data.values if you only want the values
resolve(data.data);
}
});
});
}
您可以在一个对象中同时导出这两个对象。下面是完整的sheet.js
文件:
const { google } = require('googleapis');
const keys = require('./keys.json');
function connect() {
return new Promise((resolve, reject) => {
const scope = ['https://www.googleapis.com/auth/spreadsheets'];
const { client_email, private_key, private_key_id } = keys;
const client = new google.auth.JWT(
client_email,
private_key_id,
private_key,
scope,
);
client.authorize((err) => {
if (err) {
reject(err);
} else {
resolve(client);
}
});
});
}
function getData(client, options) {
return new Promise((resolve, reject) => {
const endpoint = google.sheets({ version: 'v4', auth: client });
endpoint.spreadsheets.values.get(options, (err, data) => {
if (err) {
reject(err);
} else {
resolve(data.data);
}
});
});
}
module.exports = { connect, getData };
然后,您可以将其导入您的机器人的文件中,并在其中使用它首先进行连接,然后获取值:
const { Client } = require('discord.js');
const { connect, getData } = require('./sheet');
const client = new Client();
client.on('message', async (message) => {
if (message.author.bot) return;
const auth = await connect();
const options = {
spreadsheetId: '1LzdhD4rb2FdElTyQCAkgb5oyeGeu0d9rT2abS4n_4i8',
range: 'A2:B5',
};
const { values } = await getData(auth, options);
message.channel.send(values);
});
https://stackoverflow.com/questions/66167018
复制相似问题