Nano Hash - криптовалюты, майнинг, программирование

Бот Discord не может получить доступ к Google Таблицам, возникает ошибка. В запросе отсутствует действующий ключ API.

У меня проблема с ботом Discord, пытающимся получить доступ к Google Sheets API v4.0. Я хочу, чтобы он читал, записывал и обновлял данные на листе. Мой код отлично работает для приложения Node.js, но когда я помещаю свой код в бота Discord, он выдает такую ​​ошибку:

UnhandledPromiseRejectionWarning: Error: The request is missing a valid API key

Я не понимаю, почему я получаю эту ошибку. Я даже сделал сервисный аккаунт для своего бота Discord.

Вот код бота 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;

Я предоставил доступ к идентификатору электронной почты бота на лист, который называется discordbotapi@nodejs-api-testing-discordbot.iam.gserviceaccount.com. Я также включил API Google Таблиц. Где я делаю ошибку?


  • Как вы звоните getdata()? Похоже, вы не передавали токен, полученный в client.authorize(). 12.02.2021
  • @ZsoltMeszaros Я не знаю, но он отлично работал в приложении node js. Проблема возникает, когда я использую свой код в discord .js. Вот он и дает мне эти утомительные ошибки! 12.02.2021
  • Я думаю, он работал нормально, потому что после авторизации вы назвали его как gsrun(client). Теперь вы экспортируете только функцию без какой-либо авторизации, и я не думаю, что вы передадите client после импорта getdata. 12.02.2021
  • @ZsoltMeszaros Итак, по вашему мнению, я должен экспортировать свою авторизацию в нее, а затем авторизовать ее там. Какой здесь должен быть подход, чтобы решить эту проблему. 12.02.2021
  • @COdeingNinja У меня есть бот Discord, у которого та же предпосылка, где он использует googleapis для добавления информации в электронную таблицу. Я создал отдельные функции, одну для сбора сообщений через Discord, а затем одну для функции добавления googleapi. Затем я просто создал глобальную переменную, содержащую массив, и передал ее добавляющей функции. Возможно, стоит попробовать альтернативный метод. 13.02.2021

Ответы:


1

Когда вы попробовали это в Node.js без Discord.js, вы ничего не экспортировали и просто вызвали gsrun(client) после успешной авторизации, так что все работало нормально. Проблема в том, что теперь вы пытаетесь использовать getData без авторизации. Хотя в вашем коде есть client.authorize, вы никогда его не используете.

Чтобы решить эту проблему, я бы сделал здесь как минимум две разные функции; один для генерации клиента и один для самого запроса получения и экспорта их обоих.

Чтобы создать клиента, я бы обернул это обещанием. Таким образом, я мог позже использовать 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 и диапазоном. Внутри обещания вы просто вызываете конечную точку 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);
});
12.02.2021
Новые материалы

Кластеризация: более глубокий взгляд
Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

Как написать эффективное резюме
Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

Частный метод Python: улучшение инкапсуляции и безопасности
Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

Как я автоматизирую тестирование с помощью Jest
Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

Понимание расстояния Вассерштейна: мощная метрика в машинном обучении
В обширной области машинного обучения часто возникает необходимость сравнивать и измерять различия между распределениями вероятностей. Традиционные метрики расстояния, такие как евклидово..

Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..