【问题标题】:Can Bound Google Script trigger Google Web App?Bound Google Script 可以触发 Google Web App 吗?
【发布时间】:2019-02-20 11:34:10
【问题描述】:

我有一个运行良好并创建 Google Doc 的 Web 应用程序。该应用程序安装在新 Google 站点上的按钮中。有时,我需要从站点创建一个新文档,但有时我需要在打开 Google 电子表格时创建一个新文档(该表包含与站点相关的数据并且嵌入在站点中)。

我在该工作表上有一个自定义菜单,可以执行许多不同的操作。我想在该菜单中添加一个项目,以访问并运行上述 Web 应用程序。

首先:这可能吗?

其次,我假设如果可能的话,我必须以某种方式使用其 URL 调用 Web App 脚本(就像我使用它附加到我的 Google 站点上的按钮一样)。

我的网络应用代码如下:

代码.gs

function doGet() {
  return HtmlService
      .createTemplateFromFile('Index')
      .evaluate();
}

function createNewLandscapeSong(objArgs) {
  var docName = objArgs.docName;
  var songTitle = objArgs.songTitle;
  var songWriters = objArgs.songWriters;

  Logger.log('songTitle: ' + songTitle)

  var doc = DocumentApp.create(docName);

  var url = doc.getUrl();
  var body = doc.getBody();
  var paragraph = body.insertParagraph(0, "");
  var text = paragraph.appendText("© "+songWriters);
  text.setFontSize(8);
  var rowsData = [['PUT FIRST VERSE/CHORUS HERE.', 'PUT SECOND VERSE/NEXT CHORUS/BRIDGE/ETC HERE.']];
  var style = {};
  body.insertParagraph(0, songTitle)
  .setHeading(DocumentApp.ParagraphHeading.HEADING3);
  table = body.appendTable(rowsData);
  style[DocumentApp.Attribute.BORDER_WIDTH] = 0;
  table.setAttributes(style);

  return {
   url: url,
   songTitle: songTitle
  };
}

索引.html

<!DOCTYPE html>
<html>
  <head>
    <base target="_top">
  </head>
  <body>
Fill in fields below to name Google Lyric Document<br> 
and add the song title and writers.<br>
Then click button to create new song lyric docunent.<br><br>
    <input id="idNewDocName" type="text" placeholder="Google Doc Name"><br><br>
    <input id="idNewSongTitle" type="text" placeholder="Song Title"><br><br>
    <input id="idNewSongWriters" type="text" placeholder="Song Writers"><br><br>

    <button onclick="saveUserInput()">Create New Lyric Doc</button>

    <script>
      window.saveUserInput = function() {
        var docName = document.getElementById('idNewDocName').value;
        var songTitle = document.getElementById('idNewSongTitle').value;
        var songWriters = document.getElementById('idNewSongWriters').value;

        console.log('songTitle: ' + songTitle)

        google.script.run
        
          .withSuccessHandler(openNewDoc)
          .createNewLandscapeSong({docName:docName,songTitle:songTitle, songWriters: songWriters})

      }

       function openNewDoc(results){
           window.open(results.url, '_blank').focus();
       }
    </script>
  </body>
</html>

绑定脚本:SP 目录菜单

/*This menu in use.

This function creates the custom menu. Note: Line 3 throws error, but this script works.*/
function onOpen() {
  //SpreadsheetApp.getActiveSpreadsheet().toast('Task started');
  var ui = SpreadsheetApp.getUi();
  ui.createMenu('SP')
      .addItem('Website', 'openSite')
      .addItem('Open Google Drive', 'openDrive')
      .addItem('Open Old SP Site', 'openOldSP')
      .addItem('Create', 'openCreate')
      .addItem('Perform', 'openPerform')
      .addItem('Catalog', 'openCatalog')
      .addItem('New Lyric - Landscape', 'createLandscapeLyricDoc')
      .addItem('New Lyric - Landscape Test', 'newLyricTest')
      .addItem('New Lyric - Portrait', 'openPortrait')
      .addItem('Add Song to Catalog', 'addSong')
      .addToUi();
}
function openSite() {
  var selection = SpreadsheetApp.getActiveSheet();
  var html = "<a href='https://sites.google.com/view/sp-site/catalog'; target='_blank'>Open SP</a>";
  var userInterface = HtmlService.createHtmlOutput(html);
  SpreadsheetApp.getUi().showModalDialog(userInterface, 'Open SP');
  }
function openDrive() {
  var selection = SpreadsheetApp.getActiveSheet();
  var html = "<a href='https://drive.google.com/drive/my-drive'; target='_blank'>Open My Google Drive</a>";
  var userInterface = HtmlService.createHtmlOutput(html);
  SpreadsheetApp.getUi().showModalDialog(userInterface, 'Open My Google Drive');
  }
function openOldSP() {
  var selection = SpreadsheetApp.getActiveSheet();
  var html = "<a href=url'; target='_blank'>Open Old SP Site</a>";
  var userInterface = HtmlService.createHtmlOutput(html);
  SpreadsheetApp.getUi().showModalDialog(userInterface, 'Open My Google Drive');
  }
function openCreate() {
  var selection = SpreadsheetApp.getActiveSheet();
  var html = "<a href='url'; target='_blank'>Open Create Spreadsheet</a>";
  var userInterface = HtmlService.createHtmlOutput(html);
  SpreadsheetApp.getUi().showModalDialog(userInterface, 'Open Create Sheet');
}
function openPerform() {
  var selection = SpreadsheetApp.getActiveSheet();
  var html = "<a href= 'url'; target='_blank'>Open Perform Spreadsheet</a>";
  var userInterface = HtmlService.createHtmlOutput(html);
  SpreadsheetApp.getUi().showModalDialog(userInterface, 'Open Perform Sheet');
}
function createLandscapeLyricDoc() {
  var doc = DocumentApp.create('Rename');
  var title = "replace with song title and then link this text to song title cell in Catalog Spreadsheet"
  var url = doc.getUrl();
  var body = doc.getBody();
  var paragraph = body.insertParagraph(0, "");
  var text1 = paragraph.appendText("© replace with writer(s)");
      text1.setFontSize(8);
  var rowsData = [['PUT FIRST VERSE/CHORUS HERE.  (SUGGEST USE ALL CAPS.)', 'PUT SECOND VERSE/NEXT CHORUS/BRIDGE/ETC HERE.']];
   var style = {};
  body.insertParagraph(0, title)
      .setHeading(DocumentApp.ParagraphHeading.HEADING3);
  table = body.appendTable(rowsData);
  style[DocumentApp.Attribute.BORDER_WIDTH] = 0;
  table.setAttributes(style);
  var html = '<a href= "' + url + '"; target="_blank">Open new lyric doc</a>;'
  var selection = SpreadsheetApp.getActiveSheet();
  var userInterface = HtmlService.createHtmlOutput(html);
  /*Note: The following line throws error when you debug, 
  but the script works from the Catalog Sheet SP Menu.*/
  SpreadsheetApp.getUi().showModalDialog(userInterface, 'Open Landscape New Lyric Doc');
}
function newLyricTest() {
// This is where I want to put call to run the SPSiteNewSongButtonScript (Web App)
}
function openPortrait() {
  var html = "<a href= 'url'; target='_blank'>Open 1-Column Lyric Template</a>";
  var selection = SpreadsheetApp.getActiveSheet();
  var userInterface = HtmlService.createHtmlOutput(html);
  SpreadsheetApp.getUi().showModalDialog(userInterface, 'Open Portrait New Lyric Doc');
}  
function addSong() {
    var ss = SpreadsheetApp.getActive();
    var sheet = ss.getActiveSheet();
    var lastRow = sheet.getLastRow()
    sheet.appendRow([lastRow+1]);
    SpreadsheetApp.flush();
    var range = sheet.getRange(sheet.getLastRow(), 1);
    var songTitle = Browser.inputBox('New Song', 'Enter the song title', Browser.Buttons.OK_CANCEL);
    var namedRange = sheet.getRange("Title");
    var range=sheet.getRange(sheet.getLastRow(), namedRange.getColumn())
  range.setValue(songTitle);
    SpreadsheetApp.setActiveRange(range);
}

【问题讨论】:

  • 您的问题非常模棱两可,无法像目前所问的那样清楚地回答。首先,Web 应用程序在创建新的 Google 文档时实际在做什么(例如,它是否从用户那里获取价值?)。其次,您是否厌倦了在 Google 表格中重新创建/复制网络应用程序代码?如果这是一次性的,这可能是最简单的方法
  • 第二个问题,首先:我没有尝试将 Google Web App 重新创建/复制到绑定脚本中,因为 Web App 由 code.gs (doGet) 段和 index.html 段组成,我是'不知道/不知道如何在绑定脚本中实现它们。此外,我希望有一个简单的“调用”可以在绑定脚本中执行以运行 Web 应用程序。
  • 1Q:我会将Web App和绑定脚本代码添加到问题中以解决歧义问题。

标签: google-apps-script google-sheets web-applications


【解决方案1】:

解决这个问题的方法很少,
1) 使用sidebarcustom dialogs 在google 电子表格中呈现HTML 页面。它的行为类似于电子表格中的网络应用程序。

伪代码: 首先在您的电子表格(html 和 code.gs)中复制您的 webapp,然后修改您的 newLyricTest()

function newLyricTest() 
{
  var html = HtmlService.createHtmlOutputFromFile('Index')
      .setTitle('My custom sidebar')
      .setWidth(300);
  SpreadsheetApp.getUi() // Or DocumentApp or SlidesApp or FormApp.
      .showSidebar(html);
}

当您运行上述代码时,html 页面的值将呈现在电子表格的一侧,您可以在其中输入值并运行保存文件。

2) 您可以只使用提示来获取 docName、songTitle 和 songWriters 的值。 伪代码:

function newLyricTest() 
    {
   var ui = SpreadsheetApp.getUi();  
   var result = ui.prompt(
      'New Lyric Test',
      'Please enter Document name:',
      ui.ButtonSet.OK_CANCEL);

  // Process the user's response.
  var button = result.getSelectedButton();
  var text = result.getResponseText();
  if (button == ui.Button.OK) {
    // User clicked "OK".
    var docName = text
  } else if (button == ui.Button.CANCEL) {
    // User clicked "Cancel".
    return // exit function
  } else if (button == ui.Button.CLOSE) {
    // User clicked X in the title bar.
    return // exit function
  }

   // Now repeat the process as above to get values for songTitle and songWriters.
  // once you have the values of all these variables you can run the remaining code
  // of function createNewLandscapeSong()
  Logger.log('songTitle: ' + songTitle)

  var doc = DocumentApp.create(docName);

  var url = doc.getUrl();
  var body = doc.getBody();
  var paragraph = body.insertParagraph(0, "");
  var text = paragraph.appendText("© "+songWriters);
  text.setFontSize(8);
  var rowsData = [['PUT FIRST VERSE/CHORUS HERE.', 'PUT SECOND VERSE/NEXT CHORUS/BRIDGE/ETC HERE.']];
  var style = {};
  body.insertParagraph(0, songTitle)
  .setHeading(DocumentApp.ParagraphHeading.HEADING3);
  table = body.appendTable(rowsData);
  style[DocumentApp.Attribute.BORDER_WIDTH] = 0;
  table.setAttributes(style);

  return {
   url: url,
   songTitle: songTitle
  };
}

以上代码是您的 webapp 代码的修改副本。我已经给出了一个使用提示获取 docName 值的示例,您可以类似地获取 songTitle 和 songWriters 的值。获得这些值后,您可以简单地从 Web 应用程序运行剩余的代码。

注意:这绝不是解决此问题的详尽方法列表。另外,请注意这两种方法都依赖于在电子表格脚本编辑器中拥有 Web 应用程序代码的副本。最后,上面所有的代码都是伪代码,没有经过测试。这些代码是从侧边栏中给出的示例和上面列出的提示文档中复制而来的。

【讨论】:

  • 谢谢杰克。我会尝试这些方法。因此,由于您省略了选项,我认为没有一种方法可以向“函数 newLyricTest()”添加一行左右的简单代码来导致我的 Web 应用程序执行?换句话说,对于我是否可以从 Google Sheet 中的绑定脚本触发(即运行、开始执行等)Google Web App 的基本问题的答案是:一个大胖子不!
  • 不完全是,你可以使用app script api。但是因为无论如何你都必须获得 docName、songTitle 和歌曲作者的值,所以我采用了这种方法。我会让你决定你更喜欢哪种方法
  • 魔术@JackBrown。侧边栏的东西就像一个魅力。非常感谢。
猜你喜欢
  • 2019-07-21
  • 2023-03-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-11-24
  • 2021-12-10
  • 2014-12-05
  • 2021-08-17
相关资源
最近更新 更多