Javascript 将信息传递到Google Docs加载项中的服务器端功能

Javascript 将信息传递到Google Docs加载项中的服务器端功能,javascript,google-apps-script,google-docs,Javascript,Google Apps Script,Google Docs,我正在开发一个基于谷歌的谷歌文档插件。我正在尝试更改教程中加载项的工作流,以附加新页面,然后在新页面上插入翻译,而不是逐行工作流 我有一个在单个文档中工作的脚本,但我很难将其移动到附加组件体系结构。我认为这与将选择从客户端JS传递到执行翻译的服务器端脚本有关 这是翻译脚本 function translate(origin, dest, savePrefs) { Logger.log('Starting the script'); if (savePrefs == true) {

我正在开发一个基于谷歌的谷歌文档插件。我正在尝试更改教程中加载项的工作流,以附加新页面,然后在新页面上插入翻译,而不是逐行工作流

我有一个在单个文档中工作的脚本,但我很难将其移动到附加组件体系结构。我认为这与将选择从客户端JS传递到执行翻译的服务器端脚本有关

这是翻译脚本

function translate(origin, dest, savePrefs) {
  Logger.log('Starting the script');
  if (savePrefs == true) {
    var userProperties = PropertiesService.getUserProperties();
    userProperties.setProperty('originLang', origin);
    userProperties.setProperty('destLang', dest);
    Logger.log(origin,dest);
  }

  var doc = DocumentApp.getActiveDocument();
  var body = doc.getBody();

  // Add a page break for the translated material.
  body.appendPageBreak();

  // Get the number of elements in the document
  var elements = body.getNumChildren();
  Logger.log('Got the page elements');

  // Use the number to loop through each element in the document.
  for( var i=0;i<elements;i++) {
   var element = body.getChild(i).copy();
    var type = element.getType();
    Logger.log('Element Types were successful. Starting tests.');    

    // Test each type for a child element and run script based on the result
    // Images are nested in a paragraph as a child, so the second `if` makes
    // sure there is no image present before moving to the next paragraph.
    if( type == DocumentApp.ElementType.PARAGRAPH ){
      if(element.asParagraph().getNumChildren() != 0 && element.asParagraph().getChild(0).getType() == DocumentApp.ElementType.INLINE_IMAGE) {
        var img = element.asParagraph().getChild(0).asInlineImage().getBlob();
        body.appendImage(img);
      } else if(element.asParagraph().getNumChildren() !=0 && element.asParagraph().getChild(0).getType() == DocumentApp.ElementType.INLINE_DRAWING) {
        var drawing = element.asParagraph().copy();
        body.appendParagraph(drawing);
      } else {
        var text = element.asParagraph().getText();
        Logger.log(text);
        var spn = LanguageApp.translate(text, origin, dest);
        body.appendParagraph(spn);
      }
    } else if(type == DocumentApp.ElementType.TABLE) {
      element.asTable().copy();
      body.appendTable(element);
    } else if(type == DocumentApp.ElementType.LIST_ITEM) {
      var list = element.asListItem().getText();
      body.appendListItem(LanguageApp.translate(list, origin, dest));
    }
  }
如果我将翻译时使用的语言硬编码到服务器端脚本中,它就会工作。但只要我尝试使用单选按钮中的变量,它就不会运行。我在控制台中没有看到任何错误,也无法从编辑器中运行脚本来检查日志。如何调试此代码?

从客户端Javascript调用服务器端函数 您有一个小的语法错误:

应该是:

google.script.run
             .withFailureHander(failFunc) // Optional
             .withSuccessHander(succFunc) // Optional
             .serverFunction(optionalParams...);
这两个处理程序方法从客户端JavaScript分配回调函数,以便在服务器端函数成功或失败时调用。在这两种情况下,客户端函数都作为唯一参数提供

您要与之通信的服务器端函数的显示方式就好像它本身是一个方法一样,并带有可选的参数,这些参数将通过divide传递

最简单的情况是:

google.script.run
             .translate(origin, dest, savePrefs);
(您在发布的代码中有
runTranslation
,但服务器端函数名为
translate()
…我想这是正确的。)

现在,这可能不会解决您所有的问题,所以您明智地询问了调试问题

在Google Apps脚本中调试异步客户端/服务器代码 提供的调试环境不足以调试此类客户端/服务器交换。在用于异步执行的调试器中也存在一些弱点-您可以在中阅读更多关于这方面的内容

在这种情况下,让您调试的最简单工具是将日志写入电子表格

/**
 * Write message and timestamp to log spreadsheet.
 * From: https://stackoverflow.com/a/32212124/1677912
 */
function myLog( message ) {
  var ss = SpreadsheetApp.openById( logSpreadsheetId );
  var logSheet = ss.getSheetByName("Log") || ss.insertSheet("Log");
  logSheet.appendRow([ new Date(), message );
}
您可以从客户端Javascript调用此函数:

google.script.run.myLog( "CLIENT: " + message );

这是一种基本方法,但您可以通过使用实用程序函数和BetterLog库对其进行更多扩展。在我的博客中查看更多信息

这段代码是直接复制和粘贴的吗?我这样问是因为您试图调用名为runTranslation的服务器端方法,但在服务器端代码中,该方法名为translate。如果是这样的话,那就是为什么什么都没有发生。您是否正在检查浏览器控制台或脚本编辑器控制台?任何客户端问题都会出现在您的浏览器控制台中。是的,我检查了测试沙箱中的浏览器控制台以及脚本编辑器控制台,没有显示任何内容。我想我对服务器端函数和客户端函数有一个基本的误解。这太棒了。感谢您如此详细的回复,感谢您在谷歌应用程序中提供了出色的调试方法。今晚我做了些调整,这对我很有帮助。现在它运行得很好。
/**
 * Write message and timestamp to log spreadsheet.
 * From: https://stackoverflow.com/a/32212124/1677912
 */
function myLog( message ) {
  var ss = SpreadsheetApp.openById( logSpreadsheetId );
  var logSheet = ss.getSheetByName("Log") || ss.insertSheet("Log");
  logSheet.appendRow([ new Date(), message );
}
google.script.run.myLog( "CLIENT: " + message );