Search code examples
google-apps-scriptgoogle-docsgoogle-docs-api

Using functions in Google Apps Script to build a request and submit updates through batchUpdate with Google Docs API


I have merged the cells of a given table in a Google Doc using Google Docs API through a function in Google Apps Script (i.e. javascript). My function goes through the following steps:

  1. Loop through the content of a document.
  2. Identify a table according to an id located above it marca_tabla.
  3. Build the requests variable.
  4. Submit this variable through batchUpdate.

These steps result in merging the cells between celda_ini and celda_fin.

function fun_fusion_cel_tbl(id_documento, marca_tabla, celda_ini, celda_fin){
  let cuerpo_api = Docs.Documents.get(id_documento).body.content;

  for(var i = 0; i < cuerpo_api.length; i++){
    //console.log('read object %s... is it a table?: %s' , i, cuerpo_api[i].table != null);
    if (cuerpo_api[i].table != null) {
      //console.log('previous object is paragraph?:', cuerpo_api[i-1].paragraph != null);
      let marca = cuerpo_api[i-1].paragraph.elements[0].textRun.content;
      marca = marca.replace('\n', '');
      //console.log('object %s : table id in doc %s', i, marca);
      if (marca == marca_tabla){
        indice = cuerpo_api[i].startIndex;
        i      = cuerpo_api.length;             // exit
      }      
    }
  }

  let requests = [{ 
    mergeTableCells : { 
      tableRange      : { 
        tableCellLocation : { 
          tableStartLocation : { index: indice },
          rowIndex           : celda_ini[0], 
          columnIndex        : celda_ini[1] 
                            },
        columnSpan           : celda_fin[1] - celda_ini[1] + 1,
        rowSpan              : celda_fin[0] - celda_ini[0] + 1  
                        } } }];
  Logger.log(requests);
  Docs.Documents.batchUpdate({ requests }, id_documento);
}

When I call this function from another function it works perfectly:

function my_function1(){
    let id_doc = DocumentApp.getActiveDocument().getId();
    fun_fusion_cel_tbl(id_doc, '<<table_01>>', [1, 2], [2, 3]);
}

Now I'm trying to build a function replacing the last code line Docs.Documents.batchUpdate({ requests }, id_documento); with return(requests); and call it from a main function like this:

function my_function2(){
    let id_doc   = DocumentApp.getActiveDocument().getId();
    let my_req = fun_fusion_cel_tbl2(id_doc, '<<table_01>>', [1,2], [2,3]);
    Logger.log(my_req);
    Docs.Documents.batchUpdate({ my_req }, id_doc);
}

Log output for requests is identical to output for my_req but I get the following error when running my_function2: GoogleJsonResponseException: API call to docs.documents.batchUpdate failed with error: Invalid JSON payload received. Unknown name "my_req": Cannot find field. What should I do to pass my_req to batchUpdate?


Solution

  • About your following script.

    function my_function2(){
        let id_doc   = DocumentApp.getActiveDocument().getId();
        let my_req = fun_fusion_cel_tbl2(id_doc, '<<table_01>>', [1,2], [2,3]);
        Logger.log(my_req);
        Docs.Documents.batchUpdate({ my_req }, id_doc);
    }
    
    

    From Log output for requests is identical to output for my_req and API call to docs.documents.batchUpdate failed with error: Invalid JSON payload received. Unknown name "my_req": Cannot find field., if your request body of my_req is valid request body for the batchUpdate method, how about the following modification?

    From:

    Docs.Documents.batchUpdate({ my_req }, id_doc);
    

    To:

    Docs.Documents.batchUpdate({ requests: my_req }, id_doc);
    

    or, if my_req is {requests: [,,,]}, please modify as follows.

    Docs.Documents.batchUpdate(my_req, id_doc);
    

    or, if my_req is [,,,], the following modification can be used.

    From:

    let my_req = fun_fusion_cel_tbl2(id_doc, '<<table_01>>', [1,2], [2,3]);
    Logger.log(my_req);
    Docs.Documents.batchUpdate({ my_req }, id_doc);
    

    To:

    let requests = fun_fusion_cel_tbl2(id_doc, '<<table_01>>', [1,2], [2,3]);
    Logger.log(requests);
    Docs.Documents.batchUpdate({ requests }, id_doc);
    

    Reference: