我正在创建一个Discord机器人,该机器人将从特定的Google表格电子表格中读取内容,并且在尝试集成Google表格功能时,该错误不断出现。 See Github Repo,请知道我在Node.js上是非常新的。
对于此功能,我创建了 index.js 来使discord.js和Google API都运行。
require("dotenv").config();
const fs = require("fs");
const Discord = require("discord.js");
const client = new Discord.Client();
const readline = require('readline');
const { google } = require('googleapis');
const OAuth2Client = google.auth.OAuth2;
const SCOPES = ['https://www.googleapis.com/auth/spreadsheets'];
const TOKEN_PATH = 'token.json';
/**
* Create an OAuth2 client with the given credentials, and then execute the
* given callback function.
* @param {Object} credentials The authorization client credentials.
* @param {function} callback The callback to call with the authorized client.
*/
const authorize = function (credentials, callback) {
const { client_secret, client_id, redirect_uris } = credentials.installed;
const oAuth2Client = new OAuth2Client(client_id, client_secret, redirect_uris[0]);
// Check if we have previously stored a token.
fs.readFile(TOKEN_PATH, (err, token) => {
if (err) return getNewToken(oAuth2Client, callback);
oAuth2Client.setCredentials(JSON.parse(token));
callback(oAuth2Client);
});
}
/**
* Get and store new token after prompting for user authorization, and then
* execute the given callback with the authorized OAuth2 client.
* @param {google.auth.OAuth2} oAuth2Client The OAuth2 client to get token for.
* @param {getEventsCallback} callback The callback for the authorized client.
*/
const getNewToken = function (oAuth2Client, callback) {
const authUrl = oAuth2Client.generateAuthUrl({
access_type: 'offline',
scope: SCOPES,
});
console.log('Authorize this app by visiting this url:', authUrl);
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout,
});
rl.question('Enter the code from that page here: ', (code) => {
rl.close();
oAuth2Client.getToken(code, (err, token) => {
if (err) return callback(err);
oAuth2Client.setCredentials(token);
// Store the token to disk for later program executions
fs.writeFile(TOKEN_PATH, JSON.stringify(token), (err) => {
if (err) console.error(err);
console.log('Token stored to', TOKEN_PATH);
});
callback(oAuth2Client);
});
});
}
//pulls all commands and events
fs.readdir("./events/", (err, files) => {
files.forEach(file => {
const eventHandler = require(`./events/${file}`);
const eventName = file.split(".")[0];
client.on(eventName, (...args) => eventHandler(client, ...args));
});
});
client.login(process.env.BOT_TOKEN);
module.exports = {
authorize,
google
}
Sheets.js 包含我要使用的表格的readAll函数,因此当有人键入作业时,所有函数都应运行:
const {authorize, google} = require('./index');
const fs = require("fs");
const readline = require('readline');
const Discord = require("discord.js");
const client = new Discord.Client();
const spreadsheetId = "1asvhCVI1sC6Q2cCuqdUrRqFHkH2VCr5FM7kWSm8VBE8";
//read entire spreadsheet
const readAll = (range) => {
fs.readFile('client_secret.json', (err, content) => {
if (err) return console.log('Error loading client secret file:', err);
// Authorize a client with credentials, then call the Google Sheets API.
authorize(JSON.parse(content), (auth) => {
const sheets = google.sheets({ version: 'v4', auth });
sheets.spreadsheets.values.get({
spreadsheetId, range
}, (err, res) => {
if (err) return console.log('The API returned an error:' + err);
const rows = res.data.values;
if (rows.length) {
// Print columns B through F.
rows.map((row) => {
message.reply(`Details: ${row[0]}, Link: ${row[1]}, Additional Link: ${row[2]}, Assigned To: ${row[3]}, Assigned On: ${row[4]}, Ready for QC on: ${row[5]}, QC Link: ${row[6]}`);
});
} else {
console.log('No data found.');
}
});
});
});
}
module.exports = {
readAll
};
由于我计划将来让该机器人执行更多功能,因此我在事件文件夹中创建了一个 message.js 文件,以从命令文件夹中调用命令:
const assignments = require('../commands/assignments');
const assign = require('../commands/assign');
const qc = require('../commands/qc');
const qcList = require('../commands/qcList');
const sheets = require('../sheets');
module.exports = (client, message) => {
if (message.content.startsWith('assignments!')) {
return assignments(message);
} else if (message.content.startsWith('assign!')) {
return assign(message);
} else if (message.content.startsWith('qc!')) {
return qc(message);
} else if (message.content.startsWith('qclist!')) {
return qcList(message);
}
};
Assignments.js 实际上告诉该机器人,在!之后使用“ all”一词时!在“工作分配!”中,即当您在表格电子表格的特定标签上运行ReadAll函数时:
// gets all assignments or assignments based on name given after !
module.exports = (message, google, authorize, readAll) => {
const sheets = require('../sheets');
//ex message: assignments!Brody
//gets name after ! and stores as member variable
var messageContent = message.content;
var member = messageContent.split('!')[1];
var member = member.toLowerCase();
//test reading spreadsheet
if(member === 'all') {
sheets.readAll("Active News Assignments!B2:F");
}
//error messages
if (!member) {
message.reply("You must add a name or 'all' after the command.");
}
};
再次,我是Node.js的新手,并按照以下教程创建了该机器人。请随意指出我遗失的任何明显信息,或者一旦代码正常工作就可以简化代码的方式,因为我知道将来会添加更多功能。
https://levelup.gitconnected.com/making-a-custom-discord-bot-in-discord-js-1e17f2090919 https://www.ishaanrawat.com/integrate-google-sheets-api-with-node-js/