Запись данных формы из моего расширения Chrome в Google Sheets

Обновлены фрагменты и текущий прогресс:

Я пишу расширение Chrome, которое по сути является всплывающим окном с формой, и я хотел бы записать данные, введенные в эту форму, в Google Sheets. В настоящее время мое расширение состоит из файла manifest.json, всплывающего окна и фонового сценария.

manifest.json (соответствующие части):

"background": {
    "scripts": ["background.js"],
    "persistent": false
  },
  "content_scripts": [{ "js": ["content.js"], "matches": ["<all_urls>"] }],
  "permissions": [
    "tabs",
    "storage",
    "<all_urls>",
    "identity",
    "https://*.googleapis.com/*"
  ]

popup.js (примечание: это расширение для отслеживания симптомов рассеянного склероза)

const app = {

  symptoms: [],

  init: function () {
    //cache some element references
    let formEl = document.getElementById("symptoms-form");

    let fatigue = document.getElementById("fatigue");
    let tingling = document.getElementById("tingling");
    let weakness = document.getElementById("weakness");
    let vision = document.getElementById("vision");
    let dizzy = document.getElementById("dizzy");
    let cognition = document.getElementById("cognition");
    let depression = document.getElementById("depression");
    let balance = document.getElementById("balance");

    //upon submit, update symptoms obj and send to background
    formEl.addEventListener("submit", ev => {
      ev.preventDefault();
      console.log('button click')
      this.symptoms.push({fatigue: fatigue.value})
      this.symptoms.push({tingling: tingling.value})
      this.symptoms.push({weakness: weakness.value})
      this.symptoms.push({vision: vision.value})
      this.symptoms.push({dizzy: dizzy.value})
      this.symptoms.push({cognition: cognition.value})
      this.symptoms.push({depression: depression.value})
      this.symptoms.push({balance: balance.value})

      // chrome.runtime.sendMessage({fn: 'getSymptoms'}, function(response) {
      //   console.log('popup got response', response)
      // })

      chrome.runtime.sendMessage({fn: 'setSymptoms', symptoms: this.symptoms})
    });

  }
}

document.addEventListener('DOMContentLoaded', () => {
  app.init();
})

background.js — примечание: мой текущий обходной путь — загрузить данные в Firebase, что вы увидите ниже:

console.log("Background running");

const background = {
  symptoms: [],

  init: function() {
    //listen for any messages and route them to functions
    chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
      if (request.fn in background) {
        background[request.fn](request, sender, sendResponse);
      }
      const jsonObj = {}
      jsonObj['symptoms'] = request.symptoms
      console.log("message received", jsonObj);


      this.postSymptoms(jsonObj)
    });
  },

  postSymptoms: function(msg) {
    const xhr = new XMLHttpRequest();

    xhr.open("POST", "https://ms-mysymptoms-1541705437963.firebaseio.com/symptoms.json", true);
    xhr.setRequestHeader("Content-Type", "application/json;charset=UTF-8");
    xhr.send(msg);
  }
};

background.init();

Я настроил новый проект в консоли Google Developers, включил API Google Sheets и настроил свои учетные данные и токен API. Я проверил в проводнике Google API, что аутентификация настроена правильно, и я действительно могу записать строку на свой лист. Это отличная новость!

Я заблокирован прямо сейчас, как это сделать (записать данные) прямо из моего расширения Chrome. До сих пор я сохранил все свои учетные данные, настроил файл конфигурации и написал свой метод append в отдельном локальном файле.

листы.js:

const {authorize, google} = require('./config')
const fs = require('fs')

const spreadsheetId = '---removed for this post--'
const append = (range, values) => {
  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
      });
      const valueInputOption = 'USER_ENTERED';
      const resource = {
        values
      };
      sheets.spreadsheets.values.append({
        spreadsheetId,
        range,
        valueInputOption,
        resource
      }, (err, result) => {
        if (err) {
          console.log(err);
        } else {
          console.log("Success!");
        }
      });
    });
  });
}

// module.exports = {
//     append
// };

Однако, когда я пытаюсь интегрировать этот код в свой сценарий всплывающего окна, я сталкиваюсь с ошибкой, потому что для ссылки на эти данные конфигурации и этот метод добавления я должен использовать require в моем сценарии всплывающего окна. Поскольку скрипт всплывающего окна работает в браузере, я не могу использовать require (то есть без веб-пакета).

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

Решения, которые я рассмотрел:

1 — разверните REST API, отправьте данные из формы в эту конечную точку и сделайте так, чтобы он действовал как прокси для API Google Sheets — это не идеально.

2 - используйте веб-пакет, чтобы я мог использовать require в своем всплывающем файле

Каким будет рекомендуемый способ сделать это? Как мне интегрировать аутентификацию и работу с Google Sheet в это расширение?


person Nancy Eckenthal    schedule 09.11.2018    source источник
comment
Можете ли вы опубликовать соответствующие фрагменты кода?   -  person Prerak Sola    schedule 09.11.2018
comment
Я ищу получение данных из листа Google в расширение Chrome.   -  person NdmGjr    schedule 09.02.2019


Ответы (2)


Запись в электронную таблицу с помощью Google API — это PUT, а не POST.

https://developers.google.com/sheets/api/reference/rest/v4/spreadsheets.values/update

Мне удалось это сделать, используя chrome.identity.getAuthToken, а затем запустив выборку со следующим:

    chrome.identity.getAuthToken({interactive: true}, function(token) {
        var params = {
            'values': [
                ['Row 1 Col A','Row 1 Col B'],
                ['Row 2 Col A','Row 2 Col B'],
            ]
        };
        let init = {
            method: 'PUT',
            async: true,
            body: JSON.stringify(params),
            headers: {
                Authorization: 'Bearer ' + token,
                Content-Type': 'application/json'
            },
            contentType: 'json',
        };
        fetch('https://sheets.googleapis.com/v4/spreadsheets/***YOUR SHEET ID****/values/****YOUR RANGE*****?valueInputOption=USER_ENTERED&key=***YOUR API KEY***', init)
            .then((response) => response.json())
            .then(function(data) {
                //console.log(data);
                //Returns spreadsheet ID, update tange, cols and rows
            });
        })
   });

Это все в фоновом сценарии, где я поместил строку 1, столбец A и т. Д. В качестве значений, это будет первая ячейка вашего диапазона.

Надеюсь, это поможет.

person James Lenthall    schedule 12.04.2019
comment
как бы я использовал его, если я не хочу, чтобы он был в фоновом сценарии? - person Mauritius; 16.12.2019
comment
Я не работал над расширениями по крайней мере 6 месяцев, поэтому мои воспоминания немного отрывочны, но я думаю, где бы вы ни использовали JS, в зависимости от того, как вы хотите, чтобы он работал. Пока у вас есть личность в разрешениях манифеста. Если вы пишете в электронную таблицу на основе пользовательского ввода в popup.html/js, поместите его туда, так как он все равно будет работать только тогда, когда пользователь отправит его. - person James Lenthall; 17.12.2019

Осторожный! Если вы хотите добавить данные, параметр запроса ? идет после параметра :append.

fetch(`https://sheets.googleapis.com/v4/spreadsheets/${spreadsheetId}/values/${range}:append?valueInputOption=${valueInputOption}`, init)
person A. Lezmann    schedule 09.09.2019