Ошибка: у запроса недостаточно областей проверки подлинности.Я просто хочу запустить одну функцию удаленно - PullRequest
0 голосов
/ 28 сентября 2018

Я занимаюсь этим часами и не в себе.У меня есть скрипт в Google Apps Script, который принимает 8 аргументов и использует их для соответствующего изменения Google Sheet.

Я дошел до этого, но получаю только «Ошибка: у запроса недостаточно областей аутентификации.

const fs = require('fs');
const readline = require('readline');
const {google} = require('googleapis');

// If modifying these scopes, delete token.json.
const SCOPES = ['https://www.googleapis.com/auth/script.projects'];
const TOKEN_PATH = 'token.json';

// Load client secrets from a local file.
fs.readFile('credentials.json', (err, content) => {
  if (err) return console.log('Error loading client secret file:', err);
  // Authorize a client with credentials, then call the Google Apps Script API.
  authorize(JSON.parse(content), callAppsScript);
});

/**
 * Create an OAuth2 client with the given credentials, and then execute the
 * given callback function.
 * @param {Object} credentials The authorization client credentials.
 * @param {function} callback The callback to call with the authorized client.
 */
function authorize(credentials, callback) {
  const {client_secret, client_id, redirect_uris} = credentials.installed;
  const oAuth2Client = new google.auth.OAuth2(
      client_id, client_secret, redirect_uris[0]);

  // Check if we have previously stored a token.
  fs.readFile(TOKEN_PATH, (err, token) => {
    if (err) return getAccessToken(oAuth2Client, callback);
    oAuth2Client.setCredentials(JSON.parse(token));
    callback(oAuth2Client);
  });
}

/**
 * Get and store new token after prompting for user authorization, and then
 * execute the given callback with the authorized OAuth2 client.
 * @param {google.auth.OAuth2} oAuth2Client The OAuth2 client to get token for.
 * @param {getEventsCallback} callback The callback for the authorized client.
 */
function getAccessToken(oAuth2Client, callback) {
  const authUrl = oAuth2Client.generateAuthUrl({
    access_type: 'offline',
    scope: SCOPES,
  });
  console.log('Authorize this app by visiting this url:', authUrl);
  const rl = readline.createInterface({
    input: process.stdin,
    output: process.stdout,
  });
  rl.question('Enter the code from that page here: ', (code) => {
    rl.close();
    oAuth2Client.getToken(code, (err, token) => {
      if (err) return console.error('Error retrieving access token', err);
      oAuth2Client.setCredentials(token);
      // Store the token to disk for later program executions
      fs.writeFile(TOKEN_PATH, JSON.stringify(token), (err) => {
        if (err) console.error(err);
        console.log('Token stored to', TOKEN_PATH);
      });
      callback(oAuth2Client);
    });
  });
}

/**
 * Creates a new script project, upload a file, and log the script's URL.
 * @param {google.auth.OAuth2} auth An authorized OAuth2 client.
 */
/**
 * Call an Apps Script function to list the folders in the user's root
 * Drive folder.
 *
 * @param {google.auth.OAuth2} auth An authorized OAuth2 client.
 */
function callAppsScript(auth) { // eslint-disable-line no-unused-vars
    const scriptId = 'MqXrmZ5VhTSo4YuWEH6-b4UfoO49Cn6ao';
    const script = google.script('v1');

    // Make the API request. The request object is included here as 'resource'.
    script.scripts.run({
      auth: auth,
      resource: {
        function: 'automateSheet',
        parameters: [
            322,
            6549.51,
            4388,
            282.98,
            454.13,
            168,
            302
        ]
      },
      scriptId: scriptId,
    }, function(err, resp) {
      if (err) {
        // The API encountered a problem before the script started executing.
        console.log('The API returned an error: ' + err);
        return;
      }
      if (resp.error) {
        // The API executed, but the script returned an error.

        // Extract the first (and only) set of error details. The values of this
        // object are the script's 'errorMessage' and 'errorType', and an array
        // of stack trace elements.
        const error = resp.error.details[0];
        console.log('Script error message: ' + error.errorMessage);
        console.log('Script error stacktrace:');

        if (error.scriptStackTraceElements) {
          // There may not be a stacktrace if the script didn't start executing.
          for (let i = 0; i < error.scriptStackTraceElements.length; i++) {
            const trace = error.scriptStackTraceElements[i];
            console.log('\t%s: %s', trace.function, trace.lineNumber);
          }
        }
      } else {
        // The structure of the result will depend upon what the Apps Script
        // function returns. Here, the function returns an Apps Script Object
        // with String keys and values, and so the result is treated as a
        // Node.js object (folderSet).
        console.log("Success");
      }
    });
  }

Как мне сделать эту работу? Я следовал инструкциям для узла.Настройка JS и это работало нормально. Я смог удаленно создать скрипт, так почему я не могу удаленно запустить его?

Скрипт Google Apps

function automateSheet(btcQuantity, btcCost, btcCount, bchQuantity, bchCost, bchCount, merchantCount){
  if(!btcQuantity || !btcCost || !btcCount || !bchQuantity || !bchCost || !bchCount || !merchantCount){
   //Send back "Wtf are you doing?"
  } else {
  const ss = SpreadsheetApp.getActiveSpreadsheet();
  const sheet = ss.getSheets()[1];
  const charts = ss.getSheets()[0];


  sheet.insertRowBefore(4);
  //yellow
  sheet.getRange("A4").setValue(new Date());
  sheet.getRange("C4").setValue(btcQuantity);
  sheet.getRange("D4").setValue(btcCost);
  sheet.getRange("E4").setValue(btcCount);
  sheet.getRange("G4").setValue(bchQuantity);
  sheet.getRange("H4").setValue(bchCost);
  sheet.getRange("I4").setValue(bchCount);
  sheet.getRange("K4").setValue(merchantCount);

  //BTC Stats
  var btcValue = btcQuantity * btcCost;
  var bchValue = bchQuantity * bchCost;
  var totalValue = btcValue + bchValue;
  var btcValPercent = btcValue / totalValue;
  var bchValPercent = bchValue / totalValue;
  var totalCount = btcCount + bchCount;
  var btcCountPercent = btcCount / totalCount;
  var bchCountPercent = bchCount / totalCount;

  sheet.getRange("M4").setValue(btcValue);
  sheet.getRange("N4").setValue(btcValue / btcCount);
  sheet.getRange("O4").setValue(btcValPercent);
  sheet.getRange("P4").setValue(btcCountPercent);

  //BCH Stats
  sheet.getRange("R4").setValue(bchValue);
  sheet.getRange("S4").setValue(bchValue / bchCount);
  sheet.getRange("T4").setValue(bchValPercent);
  sheet.getRange("U4").setValue(bchCountPercent);

  //Combined Stats
  var combinedCount = btcCount + bchCount;
  var combinedValue = btcValue + bchValue;
  var combinedAvg = combinedValue / combinedCount;
  sheet.getRange("W4").setValue(combinedCount);
  sheet.getRange("X4").setValue(combinedValue);
  sheet.getRange("Y4").setValue(combinedAvg);

  //BTC and BCH Stats (7DMA)
  var values = SpreadsheetApp.getActiveSheet().getDataRange().getValues();

  var btcSevenQuantity = 0;
  var btcSevenCount = 0;
  var btcSevenValue = 0;

  var bchSevenQuantity = 0;
  var bchSevenCount = 0;
  var bchSevenValue = 0;
  var merchantCount = 0;

  for(n = 3; n < 10; n++){
    btcSevenQuantity += values[n][2];
    btcSevenCount += values[n][4];
    btcSevenValue += values[n][12];

    bchSevenQuantity += values[n][6];
    bchSevenCount += values[n][8];
    bchSevenValue += values[n][17];

    merchantCount += values[n][10];
  }

  var btcSevenQuantityAvg = btcSevenQuantity / 7;
  var btcSevenCountAvg = btcSevenCount / 7;
  var btcSevenValueAvg = btcSevenValue / 7;
  var btcSevenAvgVal = btcSevenValueAvg / btcSevenCountAvg;

  var bchSevenQuantityAvg = bchSevenQuantity / 7;
  var bchSevenCountAvg = bchSevenCount / 7;
  var bchSevenValueAvg = bchSevenValue / 7;
  var bchSevenAvgVal = bchSevenValueAvg / bchSevenCountAvg;

  var combinedSevenValueTotal = btcSevenValue + bchSevenValue;
  var combinedSevenCountTotal = btcSevenCount + bchSevenCount;

  var btcSevenValPer = btcSevenValue / combinedSevenValueTotal;
  var bchSevenValPer = bchSevenValue / combinedSevenValueTotal
  var btcSevenCountPer = btcSevenCount / combinedSevenCountTotal;
  var bchSevenCountPer = bchSevenCount / combinedSevenCountTotal;

  var combinedSevenCountAvg = combinedSevenCountTotal / 7;
  var combinedSevenValueAvg = combinedSevenValueTotal / 7;
  var combinedSevenAvgVal = combinedSevenValueTotal / combinedSevenCountTotal;

  var sevenMerchantAvg = merchantCount / 7;

  sheet.getRange("AA4").setValue(btcSevenQuantityAvg);
  sheet.getRange("AB4").setValue(btcSevenCountAvg);
  sheet.getRange("AC4").setValue(btcSevenValueAvg);
  sheet.getRange("AD4").setValue(btcSevenAvgVal);
  sheet.getRange("AE4").setValue(btcSevenValPer);
  sheet.getRange("AF4").setValue(btcSevenCountPer);

  sheet.getRange("AH4").setValue(bchSevenQuantityAvg);
  sheet.getRange("AI4").setValue(bchSevenCountAvg);
  sheet.getRange("AJ4").setValue(bchSevenValueAvg);
  sheet.getRange("AK4").setValue(bchSevenAvgVal);
  sheet.getRange("AL4").setValue(bchSevenValPer);
  sheet.getRange("AM4").setValue(bchSevenCountPer);

  sheet.getRange("AO4").setValue(combinedSevenCountAvg);
  sheet.getRange("AP4").setValue(combinedSevenValueAvg);
  sheet.getRange("AQ4").setValue(combinedSevenAvgVal);
  sheet.getRange("AR4").setValue(sevenMerchantAvg);

  var sevenCount = charts.getRange("G3").getValue();
  var sevenValue = charts.getRange("G4").getValue();
  var sevenAvgVal = charts.getRange("G5").getValue();
  var sevenMerchants = charts.getRange("G6").getValue();

  if(sevenCount > combinedSevenCountAvg){
    charts.getRange("G3").setBackgroundRGB(244, 199, 195);
  } else if(sevenCount < combinedSevenCountAvg){
    charts.getRange("G3").setBackgroundRGB(183, 225, 205);
  } else {
    charts.getRange("G3").setBackground("white");
  }

    if(sevenValue > combinedSevenValueAvg){
    charts.getRange("G4").setBackgroundRGB(244, 199, 195);
  } else if(sevenCount < combinedSevenCountAvg){
    charts.getRange("G4").setBackgroundRGB(183, 225, 205);
  } else {
    charts.getRange("G4").setBackground("white");
  }

    if(sevenAvgVal > combinedSevenAvgVal){
    charts.getRange("G5").setBackgroundRGB(244, 199, 195);
  } else if(sevenAvgVal < combinedSevenAvgVal){
    charts.getRange("G5").setBackgroundRGB(183, 225, 205);
  } else {
    charts.getRange("G5").setBackground("white");
  }

    if(sevenMerchants > sevenMerchantAvg){
    charts.getRange("G6").setBackgroundRGB(244, 199, 195);
  } else if(sevenMerchants < sevenMerchantAvg){
    charts.getRange("G6").setBackgroundRGB(183, 225, 205);
  } else {
    charts.getRange("G6").setBackground("white");
  }

  charts.getRange("G3").setValue(Math.round(combinedSevenCountAvg));
  charts.getRange("G4").setValue(parseFloat(combinedSevenValueAvg).toFixed(2));
  charts.getRange("G5").setValue(parseFloat(combinedSevenAvgVal).toFixed(2));
  charts.getRange("G6").setValue(Math.round(sevenMerchantAvg));


  //BTC and BCH Stats (30DMA)

  var values = SpreadsheetApp.getActiveSheet().getDataRange().getValues();

  var btcThirtyQuantity = 0;
  var btcThirtyCount = 0;
  var btcThirtyValue = 0;

  var bchThirtyQuantity = 0;
  var bchThirtyCount = 0;
  var bchThirtyValue = 0;
  var merchantCount = 0;

  for(n = 3; n < 33; n++){
    btcThirtyQuantity += values[n][2];
    btcThirtyCount += values[n][4];
    btcThirtyValue += values[n][12];

    bchThirtyQuantity += values[n][6];
    bchThirtyCount += values[n][8];
    bchThirtyValue += values[n][17];

    merchantCount += values[n][10];
  }

  var btcThirtyQuantityAvg = btcThirtyQuantity / 30;
  var btcThirtyCountAvg = btcThirtyCount / 30;
  var btcThirtyValueAvg = btcThirtyValue / 30;
  var btcThirtyAvgVal = btcThirtyValueAvg / btcThirtyCountAvg;

  var bchThirtyQuantityAvg = bchThirtyQuantity / 30;
  var bchThirtyCountAvg = bchThirtyCount / 30;
  var bchThirtyValueAvg = bchThirtyValue / 30;
  var bchThirtyAvgVal = bchThirtyValueAvg / bchThirtyCountAvg;

  var combinedValueTotal = btcThirtyValue + bchThirtyValue;
  var combinedCountTotal = btcThirtyCount + bchThirtyCount;

  var btcThirtyValPer = btcThirtyValue / combinedValueTotal;
  var bchThirtyValPer = bchThirtyValue / combinedValueTotal
  var btcThirtyCountPer = btcThirtyCount / combinedCountTotal;
  var bchThirtyCountPer = bchThirtyCount / combinedCountTotal;

  var combinedCountAvg = combinedCountTotal / 30;
  var combinedValueAvg = combinedValueTotal / 30;
  var combinedAvgVal = combinedValueTotal / combinedCountTotal;

  var thirtyMerchantAvg = merchantCount / 30;

  sheet.getRange("AT4").setValue(btcThirtyQuantityAvg);
  sheet.getRange("AU4").setValue(btcThirtyCountAvg);
  sheet.getRange("AV4").setValue(btcThirtyValueAvg);
  sheet.getRange("AW4").setValue(btcThirtyAvgVal);
  sheet.getRange("AX4").setValue(btcThirtyValPer);
  sheet.getRange("AY4").setValue(btcThirtyCountPer);

  sheet.getRange("BA4").setValue(bchThirtyQuantityAvg);
  sheet.getRange("BB4").setValue(bchThirtyCountAvg);
  sheet.getRange("BC4").setValue(bchThirtyValueAvg);
  sheet.getRange("BD4").setValue(bchThirtyAvgVal);
  sheet.getRange("BE4").setValue(bchThirtyValPer);
  sheet.getRange("BF4").setValue(bchThirtyCountPer);

  sheet.getRange("BH4").setValue(combinedCountAvg);
  sheet.getRange("BI4").setValue(combinedValueAvg);
  sheet.getRange("BJ4").setValue(combinedAvgVal);
  sheet.getRange("BK4").setValue(thirtyMerchantAvg);

  var thirtyCount = charts.getRange("H3").getValue();
  var thirtyValue = charts.getRange("H4").getValue();
  var thirtyAvgVal = charts.getRange("H5").getValue();
  var thirtyMerchants = charts.getRange("H6").getValue();

  if(thirtyCount > combinedCountAvg){
    charts.getRange("H3").setBackgroundRGB(244, 199, 195);
  } else if(thirtyCount < combinedCountAvg){
    charts.getRange("H3").setBackgroundRGB(183, 225, 205);
  } else {
    charts.getRange("H3").setBackground("white");
  }

    if(thirtyValue > combinedValueAvg){
    charts.getRange("H4").setBackgroundRGB(244, 199, 195);
  } else if(thirtyCount < combinedCountAvg){
    charts.getRange("H4").setBackgroundRGB(183, 225, 205);
  } else {
    charts.getRange("H4").setBackground("white");
  }

    if(thirtyAvgVal > combinedAvgVal){
    charts.getRange("H5").setBackgroundRGB(244, 199, 195);
  } else if(thirtyAvgVal < combinedAvgVal){
    charts.getRange("H5").setBackgroundRGB(183, 225, 205);
  } else {
    charts.getRange("H5").setBackground("white");
  }

    if(thirtyMerchants > thirtyMerchantAvg){
    charts.getRange("H6").setBackgroundRGB(244, 199, 195);
  } else if(thirtyMerchants < thirtyMerchantAvg){
    charts.getRange("H6").setBackgroundRGB(183, 225, 205);
  } else {
    charts.getRange("H6").setBackground("white");
  }

  charts.getRange("H3").setValue(Math.round(combinedCountAvg));
  charts.getRange("H4").setValue(parseFloat(combinedValueAvg).toFixed(2));
  charts.getRange("H5").setValue(parseFloat(combinedAvgVal).toFixed(2));
  charts.getRange("H6").setValue(Math.round(thirtyMerchantAvg));




  //Charts
  var dailyVolume = charts.getCharts()[0];
  var range = charts.getRange("'Raw Data'!A4:A368");
  var range2 = charts.getRange("'Raw Data'!BI4:BI368");
  var range3 = charts.getRange("'Raw Data'!AV4:AV368");
  var range4 = charts.getRange("'Raw Data'!BC4:BC1761");
  var chart = dailyVolume.modify()
    .clearRanges()
    .addRange(range)
    .addRange(range2)
    .addRange(range3)
    .addRange(range4)
    .build();
  charts.updateChart(chart);

  var avgOrderValue = charts.getCharts()[1];
  var range = charts.getRange("'Raw Data'!A4:A368");
  var range2 = charts.getRange("'Raw Data'!BJ4:BJ368");
  var range3 = charts.getRange("'Raw Data'!AW4:AW368");
  var range4 = charts.getRange("'Raw Data'!BD4:BD1761");
  var chart = avgOrderValue.modify()
    .clearRanges()
    .addRange(range)
    .addRange(range2)
    .addRange(range3)
    .addRange(range4)
    .build();
  charts.updateChart(chart);

  var bchMarketShare = charts.getCharts()[2];
  var range = charts.getRange("'Raw Data'!A4:A115");
  var range2 = charts.getRange("'Raw Data'!AL4:AL1761");
  var range3 = charts.getRange("'Raw Data'!AM4:AM1761");
  var range4 = charts.getRange("'Raw Data'!BE4:BE1761");
  var range5 = charts.getRange("'Raw Data'!BF4:BF1761");
  var chart = bchMarketShare.modify()
    .clearRanges()
    .addRange(range)
    .addRange(range2)
    .addRange(range3)
    .addRange(range4)
    .addRange(range5)
    .build();
  charts.updateChart(chart);

  var dailyCount = charts.getCharts()[3];
  var range = charts.getRange("'Raw Data'!A4:A368");
  var range2 = charts.getRange("'Raw Data'!BH4:BH368");
  var range3 = charts.getRange("'Raw Data'!AU4:AU368");
  var range4 = charts.getRange("'Raw Data'!BB4:BB1761");
  var chart = dailyCount.modify()
    .clearRanges()
    .addRange(range)
    .addRange(range2)
    .addRange(range3)
    .addRange(range4)
    .build();
  charts.updateChart(chart);

  var dailyMerchants = charts.getCharts()[4];
  var range = charts.getRange("'Raw Data'!A4:A368");
  var range2 = charts.getRange("'Raw Data'!BK4:BK368");
  var chart = dailyMerchants.modify()
    .clearRanges()
    .addRange(range)
    .addRange(range2)
    .build();
  charts.updateChart(chart);
  }
}



automateSheet(322, 6549.51, 4388, 282.98, 454.13, 168, 302);

Обновлена ​​функция узла

      function callScriptFunction(auth) {
        var scriptId = "M1bIaRPIiFDfQlsKPJEAKTrwdKP7CN6eO";
        var script = google.script('v1');

        script.scripts.run ({
            auth: auth,
            resource: {
                function: 'automateSheet'
            },
            scriptId: scriptId,
        }, function(err, resp){
            if(err){
                console.log(err);
            }
            else {
                var r = resp.data;
if ("error" in r) {
    console.log("Error: %o", r.error);
} else {
    console.log("Result: %o", r.response.result);
}
            }
        });
      }

1 Ответ

0 голосов
/ 29 сентября 2018

Как насчет этого подтверждения и изменения?

Точки подтверждения:

  • Пожалуйста, подтвердите области, которые используются скриптом Google Apps в редакторе скриптов.
    • Файл -> Свойства проекта -> Области действия
    • Скопируйте их.
    • Эти области используются для запуска скрипта Google Apps.Если области действия редактора сценариев не включены в клиентский сценарий (в вашем случае это сценарий node.js), возникает ошибка Request had insufficient authentication scopes..
  • Пожалуйста, подтвердите, есть ли приложенияСценарий API снова включен на консоли API.

Точки изменения:

  • Пожалуйста, включите области, которые были скопированы выше, в сценарий на стороне node.js.
  • О parameters из resource, в вашем случае функция скрипта Google Apps должна иметь 7 аргументов, таких как function automateSheet(a, b, c, d, e, f, g) {}.Если вы хотите использовать его как массив, измените его на parameters: [[322,6549.51,4388,282.98,454.13,168,302]].Таким образом, вы можете установить функцию как function automateSheet(a) {}.
  • Как насчет добавления свойства devMode: true к ресурсу?Таким образом, когда вы изменяете скрипт Google Apps, скрипт на стороне node.js может использовать последнюю версию скрипта Google Apps.Если devMode равно false, при изменении скрипта Служб Google необходимо обновить версию скрипта.

Если указанное выше изменение отражено в вашем скрипте, измените его следующим образом.

Часть модификации 1:

От:
const SCOPES = ['https://www.googleapis.com/auth/script.projects'];
До:
const SCOPES = ['https://www.googleapis.com/auth/script.projects', 'https://www.googleapis.com/auth/spreadsheets'];

Я подумал, что по вашему вопросу, по крайней мере, https://www.googleapis.com/auth/spreadsheets может быть включено.Если в вашем скрипте Служб Google используются другие области, добавьте их.

Часть модификации 2:

С:
script.scripts.run({
  auth: auth,
  resource: {
    function: 'automateSheet',
    parameters: [
        322,
        6549.51,
        4388,
        282.98,
        454.13,
        168,
        302
    ]
  },
  scriptId: scriptId,
}, function(err, resp) {
Кому:
script.scripts.run({
  auth: auth,
  resource: {
    function: 'automateSheet',
    parameters: [[ // Modified
        322,
        6549.51,
        4388,
        282.98,
        454.13,
        168,
        302,
    ]],
  },
  scriptId: scriptId,
  devMode: true, // Added
}, function(err, resp) {

Часть модификации 3:

С:
console.log("Success");
Кому:
console.log(resp.data);

В этой модификации вы можете видеть ответ при запуске Google Apps Script.Об этом, пожалуйста, решите, изменяет ли он это.

Примечание:

  • Если в вашем скрипте Google Apps вы используете функцию, такую ​​как function automateSheet(a, b, c, d, e, f, g) {}, пожалуйста, измените с parameters: [[322,6549.51,4388,282.98,454.13,168,302]]parameters: [322,6549.51,4388,282.98,454.13,168,302].
  • Когда в редакторе сценариев отображается «Файл -> Свойства проекта -> Информация», Project key отображается как Deprecated.Project key совпадает с «Текущим идентификатором API», показанным в «Развертывание как исполняемый файл API».На текущем этапе можно использовать Project key.Но если подумать о будущем обновлении, лучше использовать Script ID.Это мое соображение.

Ссылка:

Если этот ответ не былизвините, полезно для вашей ситуации.

Добавлено:

Если вы хотите отобразить, отделив сообщения об ошибках и результаты от API скриптов приложений, как насчет этой модификации?

От:

console.log(resp.data);

До:

var r = resp.data;
if ("error" in r) {
    console.log("Error: %o", r.error);
} else {
    console.log("Result: %o", r.response.result);
}

или

До:

console.log(JSON.stringify(resp.data))
...