Google-таблица. js (npm) доступ только для чтения к ячейке, не работающей с API KEY - нужно OAuth? - PullRequest
2 голосов
/ 06 февраля 2020

Из приложения node.js (бот-дискордант) Я пытаюсь перейти на publi c googlesheet , используя npm package google-могущество

Я внимательно следил за каждым шагом, но я хотел бы использовать только метод аутентификации с ключом API вместо более рискованного Oauth идентификации

(мой дискорд-бот опубликован c, на heroku, и я не хочу возиться с слишком большим количеством конфиденциальной информации, хотя я использую переменные окружения)

В документации Google-таблица. js упоминается, что:

// OR use API key -- only for read-only access to public sheets
doc.useApiKey('YOUR-API-KEY');

Я мог подключиться к таблице и читать его названия и получают названия каждого листа , но когда я звоню await sheet.loadCells();, это выдает мне следующую ошибку

Google API error - [401] 
Request is missing required authentication credential.
Expected OAuth 2 access token, 
login cookie or other valid authentication credential.
See https://developers.google.com/identity/sign-in/web/devconsole-project.

Что было бы правильным путем или ТОЛЬКО ДЛЯ ЧТЕНИЯ ячеек, если возможно с использованием только аутентификации API KEY?

здесь мой полный код:

  const sheetId = "1Bny-ZsCG_oUuS0nTbR-7tBBZu47_ncS9qGYaMpuprWU"

  var loaded = {}

  if (message) {
    message.reply("je me connecte à Google Sheets...")
  }

  const doc = new GoogleSpreadsheet(sheetId);

  doc.useApiKey(process.env.GOOGLE_API_KEY);

  await doc.loadInfo();
  loaded.docTitle = doc.title;
  loaded.sheets = {};

  if (message) {
    message.reply("...connection réussie, je récupère les infos...")
  }

  // get the spreadsheets
  for (let s = 0; s < doc.sheetCount; ++s ) {
    const sheet = doc.sheetsByIndex[s];
    loaded.sheets[sheet.title] = {sheetReference:sheet};

    loaded.sheets[sheet.title].data = []

    await sheet.loadCells(); // <---------it seems to block here

    for (let row= 0; row < sheet.rowCount; ++row) {
      loaded.sheets[sheet.title].data.push([])

      for (let col = 0; col < sheet.columnCount; ++col) {
        let cell = sheet.getCell(row, col).value;
        loaded.sheets[sheet.title].data[row].push(cell)
      }
    }

Большое спасибо!

Ответы [ 2 ]

2 голосов
/ 07 февраля 2020
  • Вы хотите получить значения из таблицы Google, используя ключ API.
  • Таблица Google является общедоступной.
  • Вы хотите добиться этого с помощью google- электронная таблица .

Если мое понимание верно, как насчет этого ответа? Пожалуйста, подумайте об этом как об одном из нескольких возможных ответов.

Проблема и обходное решение:

Когда я увидел исходный скрипт таблицы Google, кажется, что sheet.loadCells() запросы методом POST с использованием ключа API. Ref К сожалению, ключ API не может использовать метод POST. Так что такая ошибка произошла. Я думаю, что причина этой проблемы связана с этим. Например, когда используется токен доступа от OAuth2 и учетной записи службы, я могу подтвердить, что sheet.loadCells() работает. В этой ситуации это может быть ошибка или спецификация библиотеки.

К счастью, значения можно получить из общедоступной электронной таблицы Google с помощью ключа API. Таким образом, в качестве одного из нескольких обходных путей в этом ответе googleapis для Node.js используется в качестве простого метода. Это официальная библиотека.

Пример скрипта:

Сначала, пожалуйста, установите googleapis. И, пожалуйста, установите переменные spreadsheetId и APIKey.

const { google } = require("googleapis");

const spreadsheetId = "1Bny-ZsCG_oUuS0nTbR-7tBBZu47_ncS9qGYaMpuprWU"; // This is from your script.
const APIKey = "### your API key ###";

const sheets = google.sheets({version: "v4", auth: APIKey});
sheets.spreadsheets.get({ spreadsheetId: spreadsheetId }, (err, res) => {
  if (err) {
    console.error(err);
    return;
  }
  sheets.spreadsheets.values.batchGet(
    {
      spreadsheetId: spreadsheetId,
      ranges: res.data.sheets.map(e => e.properties.title)
    },
    (err, res) => {
      if (err) {
        console.error(err);
        return;
      }
      console.log(JSON.stringify(res.data));
    }
  );
});
  • . При запуске сценария извлекаются все значения из всех листов в общедоступной электронной таблице.
  • В приведенном выше примере сценария используются 2 метода spreadsheets.get и spreadsheets.values.batchGet.

Ссылки:

Если я неправильно понял ваш вопрос, и это было не то направление, которое вы хотите, прошу прощения.

1 голос
/ 12 апреля 2020

Автор Google-таблицы здесь.

Я только что выпустил обновление, которое должно решить эту проблему. Это было очень тонкое различие в документах API Google, которое я пропустил. Для метода loadCells теперь по умолчанию используется обычная конечная точка get , если используется только ключ API. Интерфейс для loadCells такой же, но в этом режиме поддерживаются только диапазоны A1.

Cheers!

...