2015-10-31 3 views
1

Я пытаюсь взять Google Apps Script Node.js tutorial и адаптировать его как универсальный вызывающий функцию Google Apps Script. Вот что я придумалОшибка: Ошибка скрипта в Node.js для скрипта Google Apps

var fs = require('fs'); 
var path=require('path'); 
var readline = require('readline'); 
var google = require('googleapis'); 
var googleAuth = require('google-auth-library'); 

var SCOPES = ['https://www.googleapis.com/auth/drive']; 
var TOKEN_DIR = path.dirname(path.dirname(path.dirname(process.execPath))) + '/other/credentials/'; 
var TOKEN_PATH = TOKEN_DIR + 'script-nodejs-quickstart.json'; 
//I ADDED THIS FUNCTION WITH THE PARAMETERS 
exports.run=function (myfunction,myparam){ 
// Load client secrets from a local file. 
fs.readFile('client_secret.json', function processClientSecrets(err, content) { 
    if (err) { 
    console.log('Error loading client secret file: ' + err); 
    return; 
    } 
    // Authorize a client with the loaded credentials, then call the 
    // Google Apps Script Execution API. 
    console.log('one ran'); 
    //TRANSFER THE PARAMETERS TO authorize 
    authorize(JSON.parse(content), callFunction,myfunction,myparam); 
}); 
} 

/** 
* 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,myfunction,myparam) { 
    var clientSecret = credentials.installed.client_secret; 
    var clientId = credentials.installed.client_id; 
    var redirectUrl = credentials.installed.redirect_uris[0]; 
    var auth = new googleAuth(); 
    var oauth2Client = new auth.OAuth2(clientId, clientSecret, redirectUrl); 

    // Check if we have previously stored a token. 
    fs.readFile(TOKEN_PATH, function(err, token) { 
    if (err) { 
     getNewToken(oauth2Client, callback); 
    } else { 
     oauth2Client.credentials = JSON.parse(token); 
     console.log('now two'); 
     //TRANSFER THE PARAMETES TO callFunction 
     callback(oauth2Client,myfunction,myparam); 
    } 
    }); 
} 

/** 
* 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 to call with the authorized 
*  client. 
*/ 
function getNewToken(oauth2Client, callback) { 
    var authUrl = oauth2Client.generateAuthUrl({ 
    access_type: 'offline', 
    scope: SCOPES 
    }); 
    console.log('Authorize this app by visiting this url: \n', authUrl); 
    var rl = readline.createInterface({ 
    input: process.stdin, 
    output: process.stdout 
    }); 
    rl.question('Enter the code from that page here: ', function(code) { 
    rl.close(); 
    oauth2Client.getToken(code, function(err, token) { 
     if (err) { 
     console.log('Error while trying to retrieve access token', err); 
     return; 
     } 
     oauth2Client.credentials = token; 
     storeToken(token); 
     callback(oauth2Client); 
    }); 
    }); 
} 

/** 
* Store token to disk be used in later program executions. 
* 
* @param {Object} token The token to store to disk. 
*/ 
function storeToken(token) { 
    try { 
    fs.mkdirSync(TOKEN_DIR); 
    } catch (err) { 
    if (err.code != 'EEXIST') { 
     throw err; 
    } 
    } 
    fs.writeFile(TOKEN_PATH, JSON.stringify(token)); 
    console.log('Token stored to ' + TOKEN_PATH); 
} 

/** 
* 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 callFunction(auth,myfunction,myparam) { 
    console.log('now we are at the last'); 
    var scriptId = 'my apps script id'; 
    var script = google.script('v1'); 

    // Make the API request. The request object is included here as 'resource'. 
    //PARAMETERS APPLIED 
    script.scripts.run({ 
    auth: auth, 
    resource: { 
     function: myfunction, 
     parameters: myparam, 
     devMode:true 
    }, 
    scriptId: scriptId 
    }, function(err, resp) { 
    console.log(myfunction,myparam,auth); 
    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. 
     var 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 (var i = 0; i < error.scriptStackTraceElements.length; i++) { 
      var trace = error.scriptStackTraceElements[i]; 
      console.log('\t%s: %s', trace.function, trace.lineNumber); 
     } 
     } 
    } else { 
     exports.result(resp.response.result);  
    } 

    }); 
} 
exports.result=function(result){ 
    return result; 
} 

Все в CAPS - это мой комментарий. Моя проблема заключается в том, что каждый раз, когда я проверить это возвращает:

The API returned an error: Error: ScriptError 

Права доступа к API и приложение сценария делать выстраиваются в линию. поэтому это не ошибка разрешений. Это не дает мне никаких других подробностей. Кто-нибудь знает, что вызывает эту ошибку?

+0

У меня такая же проблема. Он работает до тех пор, пока мой скрипт сервера не содержит вызов метода SpreadsheetApp даже в функции, которая не вызывается запросом API. Если это произойдет, я получу эту ошибку. Мой клиентский код содержит обе области - https://www.googleapis.com/auth/drive и https://spreadsheets.google.com/feeds. И я создал токен, используя оба из них. Похоже, что я сделал все, что мне нужно, с точки зрения безопасности, связанных с API таблиц. –

+0

Так это ошибка областей? – Binvention

+0

Это не ошибка области, потому что мои области выстраиваются в линию. – Binvention

ответ

0

Это связано с более ранней проблемой с тем, как анализировались ответы библиотеки Node.js, которая была исправлена ​​в https://github.com/google/google-auth-library-nodejs/commit/323b794f3aa8bf7291041620155451c3f3b2b4d2. Если вы переустановите google-auth-library, тогда вы должны увидеть полную информацию об ошибке.

1

Вероятно, у вас есть проблема с прицелом. Я обнаружил, что правильная область использования для распространения: https://www.googleapis.com/auth/spreadsheets. Это можно увидеть в редакторе сценариев в меню Файл -> Свойства проекта -> Скоменты.

+0

Я уже проверил области, это не ошибка областей – Binvention

+0

Или, по крайней мере, мои области в настоящее время выстраиваются в линию, но она по-прежнему не работает – Binvention

0

Я столкнулся с той же проблемой и решил, добавив соответствующие области к моему сценарию.

Убедитесь, что у вас есть тот же список областей в сценарии node.js, что и в сценарии приложений, просмотрев «Файлы> Свойства проекта> Области».

Это не упоминается в Quick Start, но следующий документ действительно описывает его: https://developers.google.com/apps-script/guides/rest/api#general_procedure

Смежные вопросы