You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Discord.js对接Google Sheets作为机器人数据库的认证问题求助

解决Discord机器人对接Google Sheets的认证问题

核心问题说明

你现在使用的Web类型OAuth2凭证并不适合Discord机器人这类无前端交互的后台服务。这类凭证需要用户手动授权,而服务账号凭证才是专为服务器端无交互场景设计的,也是你最初成功使用的方案。下面分两种场景给出解决方案:


方案一:回到服务账号凭证(推荐,最适配机器人场景)

1. 重新生成服务账号凭证

  • 登录Google Cloud控制台,进入你的项目
  • 导航到「IAM与管理」→「服务账号」
  • 创建/选择目标服务账号,点击「添加密钥」→「创建新密钥」,选择JSON格式下载,这个文件就是你最初使用的包含private_key的凭证

2. 配置表格权限

  • 打开目标Google Sheets,点击右上角「共享」
  • 输入服务账号凭证里的client_email字段值,赋予编辑权限,保存

3. 使用原代码对接(替换新凭证)

把新下载的服务账号凭证JSON替换掉原sheet.json,运行你最初的代码即可,无需修改逻辑:

const { GoogleSpreadsheet } = require('google-spreadsheet'); 
const sheet = require('./sheet.json') // 替换为新的服务账号凭证
const doc = new GoogleSpreadsheet('<你的表格ID>');

async function initSheet()
{
  await doc.useServiceAccountAuth(sheet);
  await doc.loadInfo()
}

bot.on('ready', () => { 
 initSheet()
})

方案二:适配Web类型OAuth2凭证(不推荐,需手动授权一次)

如果一定要用Web类型凭证,需要完成OAuth2授权流程并存储刷新令牌,步骤如下:

1. 首次授权获取刷新令牌

安装依赖:

npm install googleapis google-spreadsheet

运行以下代码生成授权链接,复制到浏览器打开完成授权,拿到返回的code:

const { google } = require('googleapis');
const fs = require('fs');
const credentials = require('./web-credentials.json'); // 你的Web类型凭证

const oauth2Client = new google.auth.OAuth2(
  credentials.web.client_id,
  credentials.web.client_secret,
  'http://localhost:3000/callback' // 本地回调地址,无需启动服务,授权后会跳转并显示code
);

// 生成授权URL
const authUrl = oauth2Client.generateAuthUrl({
  access_type: 'offline', // 必须添加才能获取refresh_token
  scope: ['https://www.googleapis.com/auth/spreadsheets'] // 表格读写权限
});
console.log('请访问以下链接授权:', authUrl);

// 替换成你拿到的code,运行后会生成tokens.json存储令牌
async function saveTokens(code) {
  const { tokens } = await oauth2Client.getToken(code);
  oauth2Client.setCredentials(tokens);
  fs.writeFileSync('./tokens.json', JSON.stringify(tokens));
  console.log('令牌已保存');
}
// 首次运行时取消注释并传入code
// saveTokens('你从浏览器拿到的code');

2. 机器人启动时加载令牌并对接表格

使用以下代码完成认证,令牌过期会自动刷新并保存:

const { GoogleSpreadsheet } = require('google-spreadsheet');
const { google } = require('googleapis');
const fs = require('fs');
const credentials = require('./web-credentials.json');
const tokens = require('./tokens.json');

const oauth2Client = new google.auth.OAuth2(
  credentials.web.client_id,
  credentials.web.client_secret
);
oauth2Client.setCredentials(tokens);

// 监听令牌更新,自动保存新令牌
oauth2Client.on('tokens', (newTokens) => {
  fs.writeFileSync('./tokens.json', JSON.stringify(newTokens));
});

const doc = new GoogleSpreadsheet('<你的表格ID>');

async function initSheet() {
  await doc.useOAuth2Client(oauth2Client);
  await doc.loadInfo();
  console.log('表格初始化完成');
}

bot.on('ready', () => { 
 initSheet()
})

报错原因解析

  • gapi is not defined:gapi是浏览器端的Google API库,Node.js环境无法直接使用,需改用googleapis库
  • You must initialize some kind of auth before making any requests:Web类型凭证格式不符合服务账号认证的要求,不能直接用useServiceAccountAuth,需改用OAuth2客户端认证
  • fetchUserGoogleCredsFromDatabase() is not defined:这是官方示例中的自定义函数,需要你自己实现从文件/数据库读取令牌的逻辑,对应上面代码中读取tokens.json的部分

内容的提问来源于stack exchange,提问作者Howlita

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 17:04:52