2

I have a google sheet and I am able to read from google sheet by giving access to service account. Below is the snippet of code for reading.

 // configure a JWT auth client
let jwtClient = new google.auth.JWT(
    privatekey.client_email,
    null,
    privatekey.private_key,
    ['https://www.googleapis.com/auth/spreadsheets',
     'https://www.googleapis.com/auth/drive']);
//authenticate request
jwtClient.authorize(function (err, tokens) {
if (err) {
console.log(err);
return;
} else {
console.log("Successfully connected!");
}
})

    // getting data from  google sheet
sheets.spreadsheets.values.get({
   auth: jwtClient,
   spreadsheetId: spreadsheetId,
   range: range
}, function (err, response) {
   if (err) {
       console.log('The API returned an error: ' + err);
   } else {
    console.log('Users list from Google Sheets:', response.data.values);
    
   }
});

this works perfectly, and i am getting the data. But when I want to write to google sheet, it gives an error. Snippet of writing

//  writing to google sheets
let values = [
    [
      'abc','b.ed'
    ],
  ];
  const requestBody = {
    values,
  };
  sheets.spreadsheets.values.update({
    spreadsheetId,
    range:"Sheet1!C3",
    valueInputOption,
    requestBody,
  }, (err, result) => {
    if (err) {
      // Handle error
      console.log(err);
    } else {
      console.log('%d cells updated.', result.updatedCells);
    }
  });

The error I am getting

GaxiosError: Login Required. at Gaxios._request (/home/spread sheet auth (node js + service account)/node_modules/gaxios/build/src/gaxios.js:129:23) at processTicksAndRejections (node:internal/process/task_queues:96:5) { errors: [ { message: 'Login Required.', domain: 'global', reason: 'required', location: 'Authorization', locationType: 'header' } ] }

Linda Lawton - DaImTo
  • 106,405
  • 32
  • 180
  • 449
Ghias Ali
  • 257
  • 2
  • 10

1 Answers1

3

Lets look at the working example you have

sheets.spreadsheets.values.get({
   auth: jwtClient,
   spreadsheetId: spreadsheetId,
   range: range

Notice how you have added auth and set it to your jwtClient? This adds the authorization permission to your call.

Now lets look at your update statment

sheets.spreadsheets.values.update({
    spreadsheetId,
    range:"Sheet1!C3",
    valueInputOption,
    requestBody,

You have not added auth, which means you are trying to preform this action without being authenticated. Update acts upon a users private data you need permission to be able to call this method.

So by that logic the following should fix your error

sheets.spreadsheets.values.update({
    auth: jwtClient,
    spreadsheetId,
    range:"Sheet1!C3",
    valueInputOption,
    requestBody,
Linda Lawton - DaImTo
  • 106,405
  • 32
  • 180
  • 449
  • thanks @DalmTo. it works. Can I create spread sheet using google service account? – Ghias Ali May 25 '22 at 11:07
  • 1
    You can, via the sheets api but it will place the sheet on the service accounts drive account, there is no option to set directory. I suggest going though the google drive api when you do the file.create make sure to set the parents to the folder you want the file created on. – Linda Lawton - DaImTo May 25 '22 at 11:57
  • got it. but If I have created file through google sheets api, then where can I access this file. because I can not login to drive with service account. – Ghias Ali May 25 '22 at 12:10
  • 1
    using the google drive api you could grant permissions to your personal account to access the file then it will appear on your personal drive account under shared with me. Or you can just create the file using drive and share a folder on your personal drive account and have the service account place the file in that folder by settings parents. Drive api and sheets api are very closely mixed – Linda Lawton - DaImTo May 25 '22 at 12:58