1

So, I recently have been working on a project with google sheets, where I am getting some data and creating files with that data to email as attachment. I am

  • copying my template file
  • setting a name to that template copy file
  • opening it with the new copy id
  • doing my replacements of tags (changing values of the copy template file)
  • sending it as an email

    function sendEmail(){
        for (var row in rangeData) {
          var varify = false;
          var fileName = new Date().toString();
          Logger.log("template " + templateId);
          var fileId = DriveApp.getFileById(templateId).makeCopy().getId();
          DriveApp.getFileById(fileId).setName(fileName);
          var body = DocumentApp.openById(fileId).getBody();
          Logger.log('current row ' + rangeData[row]);
          for (var column in rangeData[row]) {
            var target = firstRowMapped.indexOf(columnNames[column]);
            if (target != -1) {
              Logger.log('found Key');
              try {
                body.replaceText(firstRowMapped[target].toString(), rangeData[row] 
                [target].toString());
                varify = true;
              } catch (err) {
                Logger.log(err);
              }
            }
          }
          if (varify == true) {
            var toSend = DocumentApp.openById(fileId);
            // send mail
            try {
              MailApp.sendEmail(rangeData[row][emailColumn], 'Test Email', rangeData[row][0], {
                name: 'Emailer Script from DOER',
                cc: rangeData[row][ccColumn],
                attachments: toSend.getAs(MimeType.PDF)
              });
              Logger.log('sent');
            } catch (err) {
              Logger.log(err);
            } 
          }
        }
      }

I am getting my expected files on google drive. The Id of those files match that of toSend yet when I am getting my email, I get the fileId. I have been trying to figure this out for days, no luck. Does anyone know why this might be happening? Any Ideas? I personally have send countless attachments through this process (not with a template though) and never had this problem.

sakib11
  • 496
  • 1
  • 5
  • 20
  • 1
    Could you reduce this to a much shorter piece of code that has the same problem? – Brilliand Oct 12 '19 at 19:36
  • I thought I would post everything to make it easier to understand but alright. Hold on a second. – sakib11 Oct 12 '19 at 19:44
  • Okay. How about now? – sakib11 Oct 12 '19 at 19:58
  • It's still so long... surely you don't need all that logging and error handling just to show us what the problem is? – Brilliand Oct 12 '19 at 20:57
  • The idea of reducing it is to create a [minimal, reproducible example](https://stackoverflow.com/help/minimal-reproducible-example). Quite often, the act of reducing the code to that point will make the solution obvious. – Brilliand Oct 12 '19 at 21:16
  • I'm unfamiliar with the google apps classes, but it looks like you aren't saving the modified document body after you modify it. – Brilliand Oct 12 '19 at 21:17
  • actually I am. Because when I go to that file link from my Google drive, I get all the correct content. – sakib11 Oct 13 '19 at 01:48
  • seems like what you suspected was right. Thanks. – sakib11 Oct 13 '19 at 08:55

2 Answers2

3

The code in the question is opening two instances of the file, modifying one, then sending the other (unmodified) instance. To fix this, you can either:

Save and close the first instance before opening the other

/* globals
   rangeData, templateId, firstRowMapped,columnNames, emailColumn, ccColumn */

function sendEmail() {

    ...

    var doc = DocumentApp.openById(fileId);
    var body = doc.getBody();

    ...

    doc.saveAndClose();

    if (varify == true) {
      var toSend = DocumentApp.openById(fileId);
      // send mail
      ...

}

Or, only open one instance, and send the same one you modified

// Don't close the doc before this 
var toSend = doc;
Brilliand
  • 13,404
  • 6
  • 46
  • 58
contributorpw
  • 4,739
  • 5
  • 27
  • 50
  • wow, Cant believe that worked as With My way, I was still getting the files in google drive (edited files) hence I did not think I would need to save it. – sakib11 Oct 13 '19 at 03:41
  • 2
    @sakib11 It's a pretty good bet that the Google Apps class you're using autosaves the file when your script ends... which was just a little too late for it to be sent in the modified form. – Brilliand Oct 13 '19 at 08:59
  • Yes. exactly. That is what I thought. Hence I was getting ready to implement delays but thought there has to be a better way @Brilliand – sakib11 Oct 13 '19 at 10:48
1

Reopening and saving fixed my errors.

        var editFile = DocumentApp.openById(fileId);
        var body = editFile.getBody();
        var target = firstRowMapped.indexOf(columnNames[column]);
        if (target != -1) {
          Logger.log('found Key');
          try {
            Logger.log('row column ' + rangeData[row][target] + ' replacing ' + 
            firstRowMapped[target]);
            body.replaceText(firstRowMapped[target].toString(), rangeData[row] 
            [target].toString());
            Logger.log('replaced Key');
            varify = true;
            editFile.saveAndClose();
sakib11
  • 496
  • 1
  • 5
  • 20