使用应用程序脚本API执行函数



我正在尝试使用Apps Script API执行Apps Script函数。为此,我设置了一个目标脚本,并使用谷歌的指令调用脚本(JavaScript代码(。

我完全按照它的描述,但我得到了以下错误。

  1. 调用脚本时出错:

    ReferenceError:未定义漏洞

  2. 手动运行函数"时目标脚本出错;getFoldersUnderRoot((">

    异常:很抱歉,出现服务器错误。请稍等,然后重试。

函数";getFoldersUnderRoot(("在将目标脚本连接到GCP项目之前运行正常。

感谢任何帮助来指出我做错了什么。

我了解了如何使用应用程序脚本API执行应用程序脚本函数。所以我发布这个答案是为了其他人的利益。此外,我会尝试插入谷歌在其说明中没有提供的缺失信息。

  1. 目标脚本是一个应用程序脚本(例如"code.gs"(文件,其中包含要执行的所需功能。此脚本必须附加到启用了应用程序脚本API的GCP项目。

  2. 调用脚本必须是保存在本地文件夹中的html文件,而不是应用程序脚本文件。下面是一个例子";index.html";它调用两个函数";callScriptFunction(("以及";getSheets(("。

    <!DOCTYPE html>
    <html>
    <head>
    <title>Google Apps Script API Quickstart</title>
    <meta charset="utf-8" />
    </head>
    <body>
    <p>Google Apps Script API Quickstart</p>
    <!--Add buttons to initiate auth sequence and sign out-->
    <button id="authorize_button" style="display: none;">Authorize</button>
    <button id="signout_button" style="display: none;">Sign Out</button>
    <pre id="content" style="white-space: pre-wrap;"></pre>
    <script type="text/javascript">
    // Client ID and API key from the Developer Console
    var CLIENT_ID = 'YOUR_CLIENT_ID';
    var API_KEY = 'YOUR_API_KEY';
    // Array of API discovery doc URLs for APIs used by the quickstart
    var DISCOVERY_DOCS = ["https://script.googleapis.com/$discovery/rest?version=v1"];
    // Authorization scopes required by the API; multiple scopes can be
    // included, separated by spaces.
    var SCOPES = 'https://www.googleapis.com/auth/spreadsheets https://www.googleapis.com/auth/drive.readonly';
    var authorizeButton = document.getElementById('authorize_button');
    var signoutButton = document.getElementById('signout_button');
    /**
    *  On load, called to load the auth2 library and API client library.
    */
    function handleClientLoad() {
    gapi.load('client:auth2', initClient);
    }
    /**
    *  Initializes the API client library and sets up sign-in state
    *  listeners.
    */
    function initClient() {
    gapi.client.init({
    apiKey: API_KEY,
    clientId: CLIENT_ID,
    discoveryDocs: DISCOVERY_DOCS,
    scope: SCOPES
    }).then(function () {
    // Listen for sign-in state changes.
    gapi.auth2.getAuthInstance().isSignedIn.listen(updateSigninStatus);
    // Handle the initial sign-in state.
    updateSigninStatus(gapi.auth2.getAuthInstance().isSignedIn.get());
    authorizeButton.onclick = handleAuthClick;
    signoutButton.onclick = handleSignoutClick;
    }, function(error) {
    appendPre(JSON.stringify(error, null, 2));
    });
    }
    /**
    *  Called when the signed in status changes, to update the UI
    *  appropriately. After a sign-in, the API is called.
    */
    function updateSigninStatus(isSignedIn) {
    if (isSignedIn) {
    authorizeButton.style.display = 'none';
    signoutButton.style.display = 'block';
    //   callScriptFunction();
    getSheets();
    } else {
    authorizeButton.style.display = 'block';
    signoutButton.style.display = 'none';
    }
    }
    /**
    *  Sign in the user upon button click.
    */
    function handleAuthClick(event) {
    gapi.auth2.getAuthInstance().signIn();
    }
    /**
    *  Sign out the user upon button click.
    */
    function handleSignoutClick(event) {
    gapi.auth2.getAuthInstance().signOut();
    }
    /**
    * Append a pre element to the body containing the given message
    * as its text node. Used to display the results of the API call.
    *
    * @param {string} message Text to be placed in pre element.
    */
    function appendPre(message) {
    var pre = document.getElementById('content');
    var textContent = document.createTextNode(message + 'n');
    pre.appendChild(textContent);
    }
    /**
    * Shows basic usage of the Apps Script API.
    *
    * Call the Apps Script API to create a new script project, upload files
    * to the project, and log the script's URL to the user.
    */
    function callScriptFunction() {
    var scriptId = "TARGET_SCRIPT_ID";
    // Call the Apps Script API run method
    //   'scriptId' is the URL parameter that states what script to run
    //   'resource' describes the run request body (with the function name
    //              to execute)
    gapi.client.script.scripts.run({
    'scriptId': scriptId,
    'resource': {
    'function': 'getFoldersUnderRoot',
    'devMode': true
    }
    }).then(function(resp) {
    var result = resp.result;
    if (result.error && result.error.status) {
    // The API encountered a problem before the script
    // started executing.
    appendPre('Error calling API:');
    appendPre(JSON.stringify(result, null, 2));
    } else if (result.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 = result.error.details[0];
    appendPre('Script error message: ' + error.errorMessage);
    if (error.scriptStackTraceElements) {
    // There may not be a stacktrace if the script didn't start
    // executing.
    appendPre('Script error stacktrace:');
    for (var i = 0; i < error.scriptStackTraceElements.length; i++) {
    var trace = error.scriptStackTraceElements[i];
    appendPre('t' + 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 JavaScript object (folderSet).
    var folderSet = result.response.result;
    if (Object.keys(folderSet).length == 0) {
    appendPre('No folders returned!');
    } else {
    appendPre('Folders under your root folder:');
    Object.keys(folderSet).forEach(function(id){
    appendPre('t' + folderSet[id] + ' (' + id  + ')');
    });
    }
    }
    });
    }
    
    function getSheets() {
    // ID of the script to call. Acquire this from the Apps Script editor,
    // under Publish > Deploy as API executable.
    var scriptId = "TARGET_SCRIPT_ID";
    // Initialize parameters for function call.
    var sheetId = "SPREADSHEET_ID";
    
    gapi.client.script.scripts.run({
    'scriptId': scriptId,
    'resource': {
    'function': 'getSheetNames',
    'parameters': [sheetId],
    'devMode': true
    }
    }).then(function(resp) {
    var result = resp.result;
    if (result.error && result.error.status) {
    // The API encountered a problem before the script
    // started executing.
    appendPre('Error calling API:');
    appendPre(JSON.stringify(result, null, 2));
    } else if (result.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 = result.error.details[0];
    appendPre('Script error message: ' + error.errorMessage);
    if (error.scriptStackTraceElements) {
    // There may not be a stacktrace if the script didn't start
    // executing.
    appendPre('Script error stacktrace:');
    for (var i = 0; i < error.scriptStackTraceElements.length; i++) {
    var trace = error.scriptStackTraceElements[i];
    appendPre('t' + 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 JavaScript object (folderSet).
    var names = result.response.result;
    if (Object.keys(names).length == 0) {
    appendPre('No sheetnames returned!');
    } else {
    appendPre(names);
    }
    }
    });  
    }
    </script>
    <script async defer src="https://apis.google.com/js/api.js"
    onload="this.onload=function(){};handleClientLoad()"
    onreadystatechange="if (this.readyState === 'complete') this.onload()">
    </script>
    </body>
    </html>
    
  3. 下面是目标脚本的示例。

    function getFoldersUnderRoot() {
    var root = DriveApp.getRootFolder();
    var folders = root.getFolders();
    var folderSet = {};
    while (folders.hasNext()) {
    var folder = folders.next();
    folderSet[folder.getId()] = folder.getName();
    }
    return folderSet;
    }
    function getSheetNames(sheetId) {
    var ss = SpreadsheetApp.openById(sheetId);
    var sheets = ss.getSheets();
    var names = sheets.map(function(sheet) {
    return sheet.getName();
    })
    return names;
    }
    
  4. 从终端更改到工作目录并执行python3-m http.server 8000。打开浏览器并加载";http://localhost:8000/"。授权并继续。

  5. 您需要将"白名单";http://localhost:8000/"在项目证书

  6. 您需要在项目的OAuth同意屏幕中添加所需的范围。

我能够执行函数";getSheetNames(("但是";getFoldersUnderRoot(("正在引发错误:从脚本编辑器执行Exception: We're sorry, a server error occurred. Please wait a bit and try again.也会出现相同的错误。然而;getFoldersUnderRoot(("可在未附加到GCP项目的任何其他脚本上执行

相关内容

  • 没有找到相关文章

最新更新